Controllers play a big role in gaming as they are the kings of home consoles. Interestingly, they are also gaining followers among PC users, who had originally praised the mouse. Lots of people have a desktop connected to their living room television just to play from their couches using controllers. Not to mention that some games, such as sports titles, are simply better experienced with gamepads.
After diving into keyboard, mouse, and touch inputs, it is time to pay some attention to such an important icon of games. Libgdx provides a fully featured controllers API; however, it does not belong to the core framework. Instead, it is distributed as an extension, which means that you will not include it in your project unless you actually need it.
Throughout this recipe, we will cover the main aspects of the controllers API, which will be shown in the accompanying sample.
For the controllers example, you need to import the sample projects into your Eclipse workspace.
There are quite a few sides to this extension. First, we will see how to include the controllers extension in an existing project, then we will move on to how to enumerate which controllers are connected, and finally we will explain how to do polling and event listening.
Everything in the controllers API is accessible through the Controllers
singleton.
Controllers is a Libgdx extension, so you need to edit your Gradle build file to add the new dependency. We already covered this in the Updating and managing project dependencies recipe of Chapter 1, Diving into Libgdx.
Several players can have their controllers plugged in at the same time, and we can query this information with the getControllers()
method, which returns an array of the Controller
objects:
for (Controller controller : Controllers.getControllers()) { Gdx.app.log("Controllers: ", controller.toString()); }
The Controller
interface is implemented by the corresponding backends. Once we have the Controller
instance that we are interested in, we can use it to poll its state with the following methods, which we will explain later:
public interface Controller { public boolean getButton (int buttonCode); public float getAxis (int axisCode); public PovDirection getPov (int povCode); public boolean getSliderX (int sliderCode); public boolean getSliderY (int sliderCode); public Vector3 getAccelerometer (int accelerometerCode); … }
We can register a class to be notified on every controller event quite easily, as long as it implements the ControllerListener
interface. There are two ways of doing this, depending on whether we are interested in all controllers' events or just those for a specific one.
To listen to events coming from all controllers, you need to register with the Controllers
class, as follows:
Controllers.addListener(new ControllerListener() { … });
If you only care about a specific controller, you need to register with a specific instance:
Controller player1Controller = Controllers.getControllers().get(0); player1Controller.addListener(new ControllerListener() { … });
The ControllerListener
interface looks like the following code snippet:
public interface ControllerListener { public void connected(Controller controller); public void disconnected(Controller controller); public boolean buttonDown (Controller controller, int buttonCode); public boolean buttonUp (Controller controller, int buttonCode); public boolean axisMoved (Controller controller, int axisCode, float value); public boolean povMoved (Controller controller, int povCode, PovDirection value); public boolean xSliderMoved (Controller controller, int sliderCode, boolean value); public boolean ySliderMoved (Controller controller, int sliderCode, boolean value); boolean accelerometerMoved (Controller controller, int accelerometerCode, Vector3 value); }
Our sample application, located in GamepadSample.java
, logs event messages pretty much like the other input samples.
Controllers come in all flavors and colors, each with different button layouts and a wide range of components such as buttons, axes, accelerometers, and so on and so forth. The controller interface is supposed to abstract a generic gamepad with the following concepts:
buttonDown()
and buttonUp()
events.axisMoved()
events.povMoved()
event takes the pov ID and a PovDirection
value, which is simply an enum
containing a list of directions such as north
or southEast
.Integrating gamepad controls in your game is actually far from simple. While the Libgdx API is quite nice and clean, the variety of devices makes it really hard to handle all the cases. Keep this in mind when trying to officially support controllers in your game.
As a game programmer, you cannot be aware of the controller your users will plug into the game machine. It could be an Xbox controller, a PlayStation 3, OUYA, or a generic one. Each one of these assigns different buttons and axes to their physical components. The horizontal axis of the right stick will not have the same code across devices and platforms. This can be an awful nightmare!
The com.badlogic.gdx.controllers.mappings
package hosts classes with static values representing codes for known controllers. As of now, the only available one is the OUYA mapping set. Obviously, you are free to add support for other controllers in your game following this method:
public class Ouya { public static final String ID = "OUYA Game Controller"; public static final int BUTTON_O; public static final int BUTTON_U; public static final int BUTTON_Y; public static final int BUTTON_A; … }
The following picture illustrates only a fraction of the controllers' variety in the market:
This approach can be really good if you are only going to support a specific controller, such as the OUYA one, if you are releasing on that platform. However, if you want to support a wide range of controllers, it is not feasible to check for each of the mappings whenever an event fires. In this case, the best approach is usually to provide a controller configuration screen, where the user picks the button or axis of his choice for every action in the game.
Most aspects of Libgdx's input system have already been covered. Please find the following related content:
18.223.108.119