-
-
Notifications
You must be signed in to change notification settings - Fork 13
Configurable Game Controller Mappings
Add the dependency to your core project:
compile "de.golfgl.gdxcontrollerutils:gdx-controllerutils-mapping:$cuversion"
Make sure that you have read and understood Documentation on libGDX' controller interface. This extension provides a configurable mapping on top of that.
The main class of this extension is ControllerMappings
. At the creation of your game, you have to instantiate this class (or a subclass of it).
public class MyGame extends Game {
public ControllerMappings controllerMappings;
@Override
public void create() {
//...
controllerMappings = new MyControllerMappings();
}
}
public class MyControllerMapping extends ControllerMappings {
// we fill this soon
}
Each game needs different controller buttons and axis. While retro games will work best with a D-Pad and up to four buttons, others will need two analog axis to work. You define the needed input types by instantiating a ConfiguredInput
object. Its constructor takes the type of the input (button, analog axis, digital axis or digital or analog axis) and a unique identification number for this input:
public static final int BUTTON_JUMP = 0;
new ConfiguredInput(ConfiguredInput.Type.button, BUTTON_JUMP)
Add such configured inputs by calling addConfiguredInput()
of ControllerMappings
. For example, the following calls define a good old NES-style gamepad. They are best placed in MyControllerMapping
's constructor:
public static final int BUTTON_JUMP = 0;
public static final int BUTTON_FIRE = 1;
public static final int AXIS_VERTICAL = 2;
public static final int AXIS_HORIZONTAL = 3;
public static final int BUTTON_START = 4;
public static final int BUTTON_CANCEL = 5;
public MyControllerMapping() {
super();
addConfiguredInput(new ConfiguredInput(ConfiguredInput.Type.button, BUTTON_JUMP));
addConfiguredInput(new ConfiguredInput(ConfiguredInput.Type.button, BUTTON_FIRE));
addConfiguredInput(new ConfiguredInput(ConfiguredInput.Type.button, BUTTON_START));
addConfiguredInput(new ConfiguredInput(ConfiguredInput.Type.button, BUTTON_CANCEL));
addConfiguredInput(new ConfiguredInput(ConfiguredInput.Type.axisDigital, AXIS_VERTICAL));
addConfiguredInput(new ConfiguredInput(ConfiguredInput.Type.axisDigital, AXIS_HORIZONTAL));
commitConfig();
}
As you see, you must commit the configuration by calling commitConfig()
.
As said before, ControllerMappings
support four different controller input types. While ConfiguredInput.Type.button
should be clear, difference between axisDigital
, axisAnalog
and axis
is probably not at first glance. Read the JavaDoc for clarification.
Override ControllerMappings
' getDefaultMapping()
method:
@Override
public boolean getDefaultMapping(MappedInputs defaultMapping) {
// see https://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BUTTON_A
boolean onAndroid = Gdx.app.getType() == Application.ApplicationType.Android;
defaultMapping.putMapping(new MappedInput(AXIS_VERTICAL, new ControllerAxis(1)));
defaultMapping.putMapping(new MappedInput(AXIS_HORIZONTAL, new ControllerAxis(0)));
defaultMapping.putMapping(new MappedInput(BUTTON_JUMP, new ControllerButton(onAndroid ? 96 : 0)));
defaultMapping.putMapping(new MappedInput(BUTTON_FIRE, new ControllerButton(onAndroid ? 97 : 1)));
defaultMapping.putMapping(new MappedInput(BUTTON_START, new ControllerButton(onAndroid ? 108 : 9)));
defaultMapping.putMapping(new MappedInput(BUTTON_CANCEL, new ControllerButton(onAndroid ? 4 : 8)));
return true;
}
mappings.recordMapping(controller, idToRecord);
returns ControllerMappings.RecordResult
:
recorded, nothing_done, not_added, need_second_button, not_added_need_button
Don't call on every render()
, wait 100ms.
mappings.toJson()
mappings.fillFromJson(jsonValue);
For polling controllers respecting your mapping, use the MappedController
:
MappedController mappedController = new MappedController(controller, mappings);
mappedController.isButtonPressed(BUTTON_JUMP);
mappedController.getAxisValue(AXIS_HORIZONTAL);
Controllers.addListener(mappedController);
For event based controller input recpecting your mapping, extend MappedControllerAdapter
In many cases, especially when you do not use an analog axis, a game's controller input will give the player the same actions than keyboard input. You already defined input listeners for keyboard actions, so you just want to map the controller input to keyboard keys. You can use the convinience class ControllerToInputAdapter
for this. Exmaple with the NES controller could be:
controllerToInputAdapter = new ControllerToInputAdapter(controllerMappings);
controllerToInputAdapter.addButtonMapping(BUTTON_JUMP, Input.Keys.SPACE);
controllerToInputAdapter.addButtonMapping(BUTTON_FIRE, Input.Keys.ALT);
controllerToInputAdapter.addButtonMapping(BUTTON_START, Input.Keys.ENTER);
controllerToInputAdapter.addButtonMapping(BUTTON_CANCEL, Input.Keys.ESCAPE);
controllerToInputAdapter.addAxisMapping(AXIS_HORIZONTAL, Input.Keys.LEFT, Input.Keys.RIGHT);
controllerToInputAdapter.addAxisMapping(AXIS_VERTICAL, Input.Keys.UP, Input.Keys.DOWN);
controllerToInputAdapter.setInputListener(yourKeyboardInputListener);