Input
Slick2D input can handle keyboard, mouse and controller input (mostly just wrapped carefully around the existing LWJGL functionality).
The input processing is handled by the Input class. To receive input you need to get an instance of this class and call poll() during the game loop to check input and fire events to registered listeners.
If you're using the GameContainer framework then this is all handled for you and you can simply call gameContainer.getInput() (which is the preferred option).
There are 2 ways to handle input: You can either poll the keyboard, mouse and controllers by using the direct method calls on Input such as isKeyDown(). This will give you the state of the input at any time.
Alternatively you can register a listener with the Input instance you're using with addListener and then implement the InputListener interface to handle notifications of input changes. Note that if you're using an extension of BasicGame then this is done for you and you can simply override the input event handler methods.
Contents
Input polling
Polling the input allows you to check the state of the input devices at a given moment in time.This is suitable for cases where you're expecting the player to hold a button/key down while something happens in game.
For instance, hold left arrow key to run left. The key can be simply polled from the game loop. However, the downside is that if the game loop isn't running quickly enough the input may miss changes.
For instance if the user were to tap left and the tap occurred while your game was rendering it may be missed. When short lived input is expected it may be more suitable to use the event based input.
Mouse
Mouse input can be checked by using the isMouseButtonDown() method to check the buttons and getMouseX() and getMouseY() to check positional information. Note that the mouse position has it's origin (0,0) in the top left hand corner of the display unlike OpenGL. This is down to author discretion rather than any desperate need.
Keyboard
Keyboard state can be polled using the isKeyDown() method on the Input class. The identifier of the key to check should be supplied and these identifiers are defined within the Input class. For instance to check if space is pressed you do the following:
input.isKeyDown(Input.KEY_SPACE);
Controllers
An arbitrary number of gamepads and joysticks are supported. At initialisation the controllers are detected and assigned IDs. The controller directional and button state can be polled using the isButtonXPressed() methods and the isControllerXXXX() for directional control. For instance if we'd like to check if the controller was pushed left and button 1 was pressed the following code can be used:
// note we're specifying controller ID zero here, using BasicGame you can // check all the controller in one sweep if (input.isControllerLeft(0) && input.isButton1Pressed(0)) { // fire the big guns here! }
Examples
Event based input
In some cases it makes sense to be notified when input changes occur. The most obvious case is when implementing a GUI.
It's important that key presses aren't missed (which could happen if you poll input) and the GUI is also generally event driven. The InputListener defines a set of methods that can be implemented to receive notifications of input events from an Input instance by adding a listener using addListener().
Note that if you're using a subclass of basic game that it already implements InputListener and hence you can simply override the interface methods from the BasicGame class.
Mouse
Mouse events are reported to the input listener through the following methods:
public void mouseMoved(int oldx, int oldy, int newx, int newy) public void mousePressed(int button, int x, int y) public void mouseReleased(int button, int x, int y) public void mouseWheelMoved(int change)
What the methods are indicating when they're called should be fairly self explanatory, however it is worth mentioning that the origin of the screen for mouse coordinates is the top left - unlike that of OpenGL which uses bottom left. This means if the mouse is clicked at the top of the screen the mousePressed() method will be called with a y value of zero.
Keyboard
Keyboard events are reported each time a key is pressed and release to the following two methods on the InputListener interface:
public void keyPressed(int key, char c) public void keyReleased(int key, char c)
Note that both the key code and the character representing that key are reported. The character will only be reported for keys that can be visualised, a value of zero will be reported for other keys (like CTRL, ALT, etc).
Controllers
As with keyboard and mouse, connected game controllers will report events as buttons and directional controls are pressed. The following input listener methods will be called when controllers are manipulated:
public void controllerButtonPressed(int controller, int button) public void controllerButtonReleased(int controller, int button) public void controllerDownPressed(int controller) public void controllerDownReleased(int controller) public void controllerLeftPressed(int controller) public void controllerLeftReleased(int controller) public void controllerRightPressed(int controller) public void controllerRightReleased(int controller) public void controllerUpPressed(int controller) public void controllerUpReleased(int controller)
Each event method includes the index of the controller on which the change was detected. Basic game also provides this state as protected member variables. Controller input on events is a very special case. In nearly all cases polling controllers state is more appropriate than relying on the input listener.
To use a controller, you need to add Jinput.jar to your classpath. When your game does not use a controller you can remove Jinput.jar and disable support for controllers:
Input.disableControllers();
Within Update
The following methods are included in Input for your convenience, and can be used to check for event-driven input within the update method. Calling them will clear their state. So they should only be called once per frame.
input.isKeyPressed(Input.KEY_SPACE); input.isMousePressed(0); input.isControlPressed(0); //if LEFT is pressed
Note that isControlPressed uses different indices than isButtonPressed, this is because isControlPressed checks for directional first with indices 0, 1, 2, 3 and LEFT, RIGHT, UP, DOWN, respectively. So, isControlPressed(4) checks to see if button 1 is pressed.
Examples
Abstract Input
The InputProvider binds abstract physical device controls (keyboard, mouse or game controller) to arbitrary objects which implement Command. When one of the input sources triggers, an event is fired indicating that a command should be enacted.
This allows you to separate the game commands from the configured controls.
Usage
First you have to create a Command object:
private Command attack = new BasicCommand("attack");
Then you define the inputs for that command:
public void init(GameContainer container) throws SlickException { InputProvider provider = new InputProvider(container.getInput()); provider.addListener(this); provider.bindCommand(new KeyControl(Input.KEY_SPACE), attack); provider.bindCommand(new MouseButtonControl(0), attack); }
The attack command is triggered when: Space is pressed
The left mouse button is pressed
public void controlPressed(Command command) { message = "Pressed: "+command; } public void controlReleased(Command command) { message = "Released: "+command; }