Skip to content

Handling Input and On Screen Game Pad

James Shen edited this page Nov 17, 2015 · 1 revision

In the Raindrop example the Bucket’s act method ,we already used some code to handle touch or key press input,In the example code:

public void act(float delta){
        if(input.isTouched()){
            Vector3 touchPos=new Vector3();
            touchPos.set(input.getX(),input.getY(),0);
            getStage().getCamera().unproject(touchPos);
            setX(touchPos.x-64/2);
        }
        if(input.isKeyPressed(Input.Keys.LEFT)){
            setX(getX() - 200 * graphics.getDeltaTime());
        }
        if(input.isKeyPressed(Input.Keys.RIGHT)){
            setX(getX() + 200*graphics.getDeltaTime());
        }
  
        if(getX()<0) setX(0); if(getX() > 800- 64) setX(800-64);
    }
}

we used input.isTouched ,input.isKeypressed to check if user has touched screen or pressed a key. This way of handling input is called pooling because we periodically check if there is some input from user. Pooling normally is a bit more resource intensive. Beside polling , Guidebee Game Engine also support input event handling. The following diagram displays the major component in the game engine which handles input (polling and event handling)

Handle input

Static member of GameEngine object input is the interface to input facilities, this allows polling the state of the keyboard, the touch screen and the accelerometer.Instead of polling for events, one can process all input events with an InputProcessor. You can set the InputProcessor via the setInputProcessor(InputProcessor) method. It will be called before the render() method in each frame.

Event handling allows you to get more granular and most of all chronological information about input from the user. Event handling provides a way to implement interactions with user interfaces, where specific input sequences are important, e.g. touch down, touch up on a button means the user clicked the button. Such interactions are hard to implement with polling.

#Input Processor Event handling is done using the common observer pattern. First we have to implement a listener interface called InputProcessor:

public class MyInputProcessor implements InputProcessor {
   public boolean keyDown (int keycode) {
      return false;
   }
 
   public boolean keyUp (int keycode) {
      return false;
   }
 
   public boolean keyTyped (char character) {
      return false;
   }
 
   public boolean touchDown (int x, int y, int pointer, int button) {
      return false;
   }
 
   public boolean touchUp (int x, int y, int pointer, int button) {
      return false;
   }
 
   public boolean touchDragged (int x, int y, int pointer) {
      return false;
   }
 
   public boolean mouseMoved (int x, int y) {
      return false;
   }
 
   public boolean scrolled (int amount) {
      return false;
   }
}

The first three methods allow you to listen for keyboard events:

  • keyDown(): Called when a key was pressed down. Reports the key code, as found in Keys.
  • keyUp(): Called when a key was lifted. Reports the key code as above.
  • keyTyped(): Called when a Unicode character was generated by the keyboard input. This can be used to implement text fields and similar user interface elements.

The next three methods report mouse/touch events:

  • touchDown(): Called when a finger went down on the screen or a mouse button was pressed. Reports the coordinates as well as the pointer index and mouse button (always Buttons.LEFT for touch screens).
  • touchUp(): Called when a finger was lifted from the screen or a mouse button was released. Reports the last known coordinates as well as the pointer index and mouse button (always Buttons.Left for touch screens).
  • touchDragged(): Called when a finger is being dragged over the screen or the mouse is dragged while a button is pressed. Reports the coordinates and pointer index. The button is not reported as multiple buttons could be pressed while the mouse is being dragged. You can use Gdx.input.isButtonPressed() to check for a specific button.
  • mouseMoved(): Called when the mouse is moved over the screen without a mouse button being down. This event is only relevant on the desktop and will never occur on touch screen devices where you only get touchDragged() events.
  • scrolled(): Called when the scroll wheel of the mouse was turned. Reports either -1 or 1 depending on the direction of spin. This will never be called for touch screen devices.
  • Each of the methods returns a boolean. We’ll look into why that is in the InputMultiplexer section below. Once you implement your InputProcessor you have to tell libgdx about it so it can be called when a new input event arrives:
MyInputProcessor inputProcessor = new MyInputProcessor();
GameEngine.input.setInputProcessor(inputProcessor);

From this point on, all new input events will be pushed to the MyInputProcessor instance. Events are dispatched right before the call to ApplicationListener.render(), on the rendering thread.

#InputMulitiplexer Sometimes you want to chain InputProcessors, e.g. you have one processor for your UI which should be invoked first, and a second processor for input events that manipulate your game’s world. You can use the InputMultiplexer class to achieve this:

InputMultiplexer multiplexer = new InputMultiplexer();
multiplexer.addProcessor(new MyUiInputProcessor());
multiplexer.addProcessor(new MyGameInputProcessor());
GameEngine.input.setInputProcessor(multiplexer);

The InputMultiplexer will hand any new events to the first InputProcessor that was added to it. If that processor returns false from the method invoked to handle the event, this indicates the event was not handled and the multiplexer will hand the event to the next processor in the chain. Through this mechanism, the MyUiInputProcessor can handle any events that fall inside one of its widgets and pass on any other events to the MyGameInputProcessor.

#Stage As we encourage the Stage-Actor pattern, the State implement the InputProcessor interface,so it can handle user input such as keyboard and touch event. it also can have an on screen game controller which can simulate a game pad for touch screen smart phone.

#GameController An Game Controller normally have direction pad and two Buttons (Button A fire button, and Button B)

On Screen Game Controller

Guidebee Game Engine make it easy for use to add on a on screen game controller (game pad) to your game. now let’s add a game controller for the raindrop game ,the game controller can control Mario to move in four directions:

First we load resources for the game controller, game controllers requires a couple of resources (like background ,knob image, button images) ,which has a constructor as follows:

public GameController (TextureRegionDrawable touchBackground, 
 TextureRegionDrawable touchKnob,
 TextureRegionDrawable buttonA, 
 TextureRegionDrawable buttonAPressed,
 TextureRegionDrawable buttonB,
 TextureRegionDrawable buttonBPressed)

So we can reuse the TextureAtlas we loaded before:

TextureAtlas textureAtlas=assetManager.get("raindrop.atlas",TextureAtlas.class);
GameController gameController
                = new GameController(new TextureRegionDrawable(textureAtlas.findRegion("Back")),
                new TextureRegionDrawable(textureAtlas.findRegion("Joystick")),
                new TextureRegionDrawable(textureAtlas.findRegion("Button_08_Normal_Shoot")),
                new TextureRegionDrawable(textureAtlas.findRegion("Button_08_Pressed_Shoot")),
                new TextureRegionDrawable(textureAtlas.findRegion("Button_08_Normal_Virgin")),
                new TextureRegionDrawable(textureAtlas.findRegion("Button_08_Pressed_Virgin"))
        );
gameController.addGameControllerListener(mario);
 
...
sceneStage.setGameController(gameController);

we want Mario to handle the game controller event ,that’s why we call gameController.addGameControllerListener(mario)

public class Mario extends Actor implements GameControllerListener {
...
 
@Override
    public void KnobMoved(Touchpad touchpad, Direction direction) {
 
        currentDirection=direction;
        handleKeyPress();
 
    }
 
    @Override
    public void ButtonPressed(GameButton button) {
 
    }
 
    private void handleKeyPress(){
        switch(currentDirection){
            case WEST:
                setTextureRegion(leftAnimation.getKeyFrame(elapsedTime,true));
                setX(getX() - 200 * graphics.getDeltaTime());
                break;
            case EAST:
                setTextureRegion(rightAnimation.getKeyFrame(elapsedTime,true));
                setX(getX() + 200*graphics.getDeltaTime());
                break;
            case NORTH:
                setTextureRegion(forwardAnimation.getKeyFrame(elapsedTime,true));
                setY(getY() + 200 * graphics.getDeltaTime());
                break;
            case SOUTH:
                setTextureRegion(backwardAnimation.getKeyFrame(elapsedTime,true));
                setY(getY() - 200 * graphics.getDeltaTime());
                break;
 
        }
 
        if(getX()<0)  setX(0);
        if(getY()<0) setY(0); if(getX() > 800- 64) setX(800-64);
        if(getY() > 480- 64) setY(480 -64);
    }
 
    @Override
    public void act(float delta){
        elapsedTime += GameEngine.graphics.getDeltaTime();
        handleKeyPress();
 
    }

Last we need Stage to handle input event for us:

public class DropScene extends Scene  {
private InputProcessor savedInputProcessor;
...
@Override
    public void show() {
        savedInputProcessor = GameEngine.input.getInputProcessor();
        GameEngine.input.setInputProcessor(sceneStage);
        rainMusic.play();
    }
 
 @Override
    public void hide() {
        GameEngine.input.setInputProcessor(savedInputProcessor);
    }

Now you move Mario in four directions (actually can move in 8 directions, since we only have the sprite sheets for 4 directions, so in this demo ,we only allow Mario move in EAST,WEST,NORTH and SOUTH ,there are NORTHWEST,NORTHEAST,SOUTHEAST,SOUTHWEST also)

IMAGE ALT TEXT HERE

In the Github project’s controller directory ,there are more resources you can choose from to show the on screen game controllers:

##Game Controller background

background

##Game Controller Joystick

joystick

##Game Controller Buttons

buttons

You can’t perform that action at this time.