# Input Handling

Users interact with your jME3 application with different input devices – the mouse, the keyboard, or a joystick. To respond to inputs we use the `inputManager` object in `SimpleApplication`.

This is how you add interaction to your game:

1. For each action, choose the trigger(s) (a key or mouse click etc)
2. For each action, add a trigger mapping to the inputManager
3. Create at least one listener in SimpleApplication
4. For each action, register its mappings to a listener
5. Implement each action in the listener

## 1. Choose Trigger

Choose one or several key/mouse events for the interaction. We use `KeyTrigger`, `MouseAxisTrigger`, `MouseButtonTrigger`, `JoyAxisTrigger` and `JoyButtonTrigger` constants from the `com.jme3.input.controls` package.

The booleans are used to negate the axes: For inputs that have two axes (MouseAxis, JoyAxis), you have to listen to the negative (true) and positive (false) axis separately.

Trigger | Code
--- | ---
Mouse button: Left Click | MouseButtonTrigger(MouseInput.BUTTON_LEFT)
Mouse button: Right Click | MouseButtonTrigger(MouseInput.BUTTON_RIGHT)
Mouse button: Middle Click | MouseButtonTrigger(MouseInput.BUTTON_MIDDLE)
Mouse movement: | MouseAxisTrigger(MouseInput.AXIS_X, true), MouseAxisTrigger(MouseInput.AXIS_Y, true), MouseAxisTrigger(MouseInput.AXIS_X, false), MouseAxisTrigger(MouseInput.AXIS_Y, false)
Mouse wheel: | MouseAxisTrigger(MouseInput.AXIS_WHEEL,false) MouseAxisTrigger(MouseInput.AXIS_WHEEL,true)
Keyboard: Characters and Numbers etc | KeyTrigger(KeyInput.KEY_X) etc
Keyboard: Spacebar | KeyTrigger(KeyInput.KEY_SPACE)
Keyboard: Shift | KeyTrigger(KeyInput.KEY_RSHIFT), KeyTrigger(KeyInput.KEY_LSHIFT)
Keyboard: F1 etc | KeyTrigger(KeyInput.KEY_F1) etc
Keyboard: Return, Enter | KeyTrigger(KeyInput.KEY_RETURN), KeyTrigger(KeyInput.KEY_NUMPADENTER)
Keyboard: PageUp, PageDown | KeyTrigger(KeyInput.KEY_PGUP), KeyTrigger(KeyInput.KEY_PGDN)
Keyboard: Delete, Backspace | KeyTrigger(KeyInput.KEY_BACK), KeyTrigger(KeyInput.KEY_DELETE)
Keyboard: Escape | KeyTrigger(KeyInput.KEY_ESCAPE)
Keyboard: Arrows | KeyTrigger(KeyInput.KEY_DOWN), KeyTrigger(KeyInput.KEY_UP) KeyTrigger(KeyInput.KEY_LEFT), KeyTrigger(KeyInput.KEY_RIGHT)
NumPad: Number 1 etc | KeyTrigger(KeyInput.KEY_NUMPAD1) etc
Joystick: Button | JoyButtonTrigger(0, JoyInput.AXIS_POV_X), JoyButtonTrigger(0, JoyInput.AXIS_POV_Y) ?
Joystick: Movement | JoyAxisTrigger(0, JoyInput.AXIS_POV_X, true), JoyAxisTrigger(0, JoyInput.AXIS_POV_X, false), JoyAxisTrigger(0, JoyInput.AXIS_POV_Z, true), JoyAxisTrigger(0, JoyInput.AXIS_POV_Z, false)

## 2. Add a Trigger Mapping

When initializing the application, add a Mapping for each Trigger.

Give the mapping a meaningful name. The name should reflect the action, not the key, since the keys can change. Here some examples:

    inputManager.addMapping("Pause Game", new KeyTrigger(KeyInput.KEY_P));
    inputManager.addMapping("Rotate",     new KeyTrigger(KeyInput.KEY_SPACE));

There are cases where you may want more then one trigger for one action. For instance some users prefer the WASD keys to navigate, others prefer the arrow keys. You can define both by adding them after a comma.

    inputManager.addMapping("Left",  new KeyTrigger(KeyInput.KEY_A),
                                     new KeyTrigger(KeyInput.KEY_LEFT));
    inputManager.addMapping("Right", new KeyTrigger(KeyInput.KEY_D),
                                     new KeyTrigger(KeyInput.KEY_RIGHT));

## 3. Create Listeners

The jME3 input manager supports two types of event listeners for inputs:

com.jme3.input.controls.AnalogListener

- Use for continuous and gradual actions.
  - Examples: Walk, run, rotate, accelerate vehicle, strafe, (semi-)automatic weapon shot
- JME gives you access to:
  - the name of the triggered action.
  - a gradual value between 0-9 how long the key has been pressed.

com.jme3.input.controls.ActionListener

- Use for absolute “pressed or released?”, “on or off?” actions.
  - Examples: Pause/unpause, a rifle or revolver shot, jump, click to select.
- JME gives you access to:
  - the name of the triggered action.
  - a boolean whether the key is still pressed or has just been released.

You can use one or both in the same application. Add one or both of these code snippets to your main SimpleApplication-based class to activate the listener.

    private ActionListener() {
      public void onAction(String name, boolean keyPressed, float tpf) {
         /** TODO */
      }
    };

    private AnalogListener analogListener = new AnalogListener() {
      public void onAnalog(String name, float keyPressed, float tpf) {
         /** TODO */
      }
    };

## 4. Register Mappings to Listeners

To activate the mappings, you must register them to the Listener. Write your registration code after the part where you have added the mappings to the inputManager before.

In this example, we register the “Pause Game” mapping to the `actionListener` object, because pausing a game is in “either/or” decision.

    inputManager.addListener(actionListener, new String[]{"Pause Game"});

In this example, we register navigational mappings to the `analogListener` object, because walking is a continuous action. Players tend to keep the key pressed to express continuity, for example when they want to “walk on” or “accelerate”.

    inputManager.addListener(analogListener, new String[]{"Left", "Right"});

As you see, you can add several listeners in one String array. You can call the addListener() method more than once, each time with a subset of your list, if that helps you keep you code tidy.

Tip: Check the string's capitalization and spelling if you think you have registered an action, but it does not work.

## 5. Implement Actions

You specify the action to be triggered where it says TODO in the Listener code snippets. Typically you write a series of if/else conditions, testing for all the mapping names, and specifying each action. Here is one example:

    private AnalogListener analogListener = new AnalogListener() {
        public void onAnalog(String name, float value, float tpf) {

          if (name.equals("Rotate")) {         // test?
            player.rotate(0, value*speed, 0);  // action!
          } // else if ...

        }
      };

It's very common that you want an action to be only triggered once, in the moment when the key is released. Examples are when the player presses an action key to open a door or pick up an item, or to flip a game state, such as pause/unpause. For these cases, use an ActionListener and test for `&& !keyPressed`, like shown in the following example.

    private ActionListener() {
        public void onAction(String name, boolean keyPressed, float tpf) {

          if (name.equals("Pause Game") && !keyPressed) { // test?
            isRunning = !isRunning;                       // action!
          } // else if ...

        }
      };

## Remapping Keys

This approach of separating triggers from actions has the advantage that you can remap triggers easily. Maybe your players have different keyboard layouts, are used to “reversed” mouse navigation, or prefer different navigational keys than the ones you defined. In any case, you only need to replace the trigger parts in the `inputManager.addMapping()` lines with variables, and load different sets of trigger objects when the game starts. The rest of the code stays as it is.

keyinput, input, documentation

view online version