Sunday, June 22, 2014

[LibGDC] day 3 – handling input

it’s already day 3 of my tutorial series,
but before we start to care about the input the user does, I want to solve a little “problem” I always had with starting the game.

Usually I always work in the main class of our game (TestGame) or at least in the main project. But if I now want to click on Run eclipse tries to start this library-project, but that does not work. When developing my game most of the time I want to start the desktop-version. So I decided to move the Desktop-Starter class to my main project. (if there is a better way to do that, tell me!)
Therefore I do a right click on testgame and then Properties -> Java Build Path -> Source and at the right “Link Source”
Here you choose the assets-folder from the testgame-android project.

In the tab “Libraries” you press on “Add JARs”:
there you select “testgame-desktop/libs” and the following files
gdx-backend-lwjgl-natives.jar
gdx-backend-lwjgl-sources.jar
gdx-backend-lwjgl.jar
gdx-natives.jar
Now you just have to copy the main-class from the testgame-desktop in the testgame project and you can run it with one click.
Just select that you want to start it as a “Java Application” and tell it that your “Main” class is the right class to start.
Now you can edit the TestGame class and do not have to press on testgame-desktop again before you can test your game. :)
But onto the real topic of todays tutorial.
Input in libgdx is quite abstracted. it’s not importat if you press the touchscreen or the mouse, the game will get the same.
There are two ways to get the input of the user. The first one is called poll, that means you ask in every Frame wheter a key is pressed or where the user touches the screen at the moment.
With the object Gdx.input you can ask for all the input(if you use the auto-completion of eclipse [Ctrl+space] you get a good overview).
we can now ask things like:
is the key A pressed?
if(Gdx.input.isKeyPressed(Keys.A)){ }
is the touchscreen or the mouse pressed?
if(Gdx.input.isTouched(){ }
A problem is, that the mousecoordinates start in the left top edge of the screen and do not care about the resolution we gave in our camera. To get the coordinates in our screenspace, we have to project it with the cameramatrix (sounds complicated, but we do not have to understand how it works, just that it works):
// project input to gamescreen
Vector3 touchPos = new Vector3();
touchPos.set(Gdx.input.getX(), Gdx.input.getY(), 0);
camera.unproject(touchPos);
// touchPos.x and touchPos.y are now the variables to use
Now we can put this into the render()-method and put our christmas ball there where the mouse is at the moment:
if(Gdx.input.isTouched()){
 // project input
 Vector3 touchPos = new Vector3();
 touchPos.set(Gdx.input.getX(), Gdx.input.getY(), 0);
 camera.unproject(touchPos);

 x=(int) touchPos.x-32; 
 y=(int) touchPos.y-32;
}
// [...]
batch.draw(ball,x,y);
The other possibility is to create a kind of EventListener that catches the input the moment it is done. Therefore you create your own InputProcessor (a class implementing that interface), that you just have to register with libgdx (the last two lines).
class GameInputProcessor implements InputProcessor {
 @Override
 public boolean keyDown(int keycode) {
  return false;
 }

 @Override
 public boolean keyUp(int keycode) {
  return false;
 }
 @Override
 public boolean keyTyped(char character) {
  return false;
 }
 @Override
 public boolean touchDown(int x, int y, int pointer, int button) {
  return false;
 }
 @Override
 public boolean touchUp(int x, int y, int pointer, int button) {
  return false;
 }
 @Override
 public boolean touchDragged(int x, int y, int pointer) {
  return false;
 }
 @Override
 public boolean scrolled(int amount) {
  return false;
 }

 @Override
 public boolean mouseMoved(int screenX, int screenY) {
  return false;
 }
} 
// [..] in create():
GameInputProcessor inputProcessor = new GameInputProcessor();
Gdx.input.setInputProcessor(inputProcessor);
The InputProcessor recieves different events:
keyDown() and keyUp() tell you when a key is pressed or released and give you the keycode (that one you as well reference with Keys.X). keyTyped() gives you the typed key as a char. might be useful if you want to create a textfield.
touchDown() and touchUp() are called, if you press with the mouse or the finger. here the x and y coordinate are passt (which have again to be transformed). As well it is passed which finger it is (if you have multitouch) and which button is pressed (if you have a mouse).
Then there is the method mouseMoved() which is called if you move the mouse, but do not touch and the methode touchDragged(), which is called if you pressed the mouse or the screen and move the same time.
Last but not least there is the method scrolled() which is called if you turn the mousewheel.
The first method is better if you just need the state of keys or the position of the finger in every frame (this is usually the case if you are ingame) and the second is better if you need the exact order of the events (like if you write an UI for your game).
This was a very text-heavy tutorial today and I probably change some things tomorrow as I’m quite tired.
Tomorrow there will be either something on animation or on fonts (depending on in which mood I am).

No comments:

Post a Comment

Popular Posts