Detecting user input via event polling

Typically, there are a couple of approaches when it comes to detecting user input. The most straightforward approach is event polling, which involves actively querying the state of a specific input peripheral whenever we want to make a decision based on it. This can happen either in every frame or on demand for specific bits of game logic.

Throughout this recipe, we will work with an example where you will learn how to query the keyboard, mouse, accelerometer, and compass of the device. The updated state of these devices will be shown on the screen.

Getting ready

The sample projects are required to follow this recipe; please make sure that you already have them in your Eclipse workspace.

How to do it…

The code for this recipe is found in the InputPollingSample class. We have the classic members to support regular rendering: camera, viewport, and sprite batch. Besides these, we add a BitmapFont object to draw the state of the input devices on the screen, rather than using logging and spamming the console in every frame. In the create() method, we instantiate our members and in the dispose() method, we deallocate the batch and font resources.

Note

Take a peek at Chapter 6, Font Rendering, for more details on how BitmapFont works.

The actual polling takes place inside the render() method, which means it will run in every frame. We will proceed on a per device basis; you will see that this is extremely simple.

We can retrieve the mouse or touch coordinates with Gdx.input.getX() and Gdx.input.getY(). Keep in mind that they come in screen space, so you have to call unproject() on your camera to transform them into world space. Computer mice typically have three buttons: left, right, and middle. We can check the state of these buttons with Gdx.input.isButtonPressed(), passing in the appropriate constant. Alternatively, on mobile devices, you can use Gdx.input.isTouched().

Note

Screen space means the actual pixels on your device's screen, while world space refers to the virtual units you use to model your game world. A camera knows how to convert between the two spaces. Refer to Chapter 2, Working with 2D Graphics, for more details.

Have a look at the following lines of code:

float mouseX = Gdx.input.getX();
float mouseY = Gdx.input.getY();
boolean leftPressed = Gdx.input.isButtonPressed(Buttons.LEFT);
boolean rightPressed = Gdx.input.isButtonPressed(Buttons.RIGHT);
boolean middlePressed = Gdx.input.isButtonPressed(Buttons.MIDDLE);

Note

Since they lack buttons, touch events in phones and tablets correspond to the Buttons.LEFT constant. The reason behind this is simply convenience.

To know whether a given key is pressed or not, we can use the Gdx.input.isKeyPressed() method, passing in the corresponding constant, as shown in the following lines of code. These constants live inside the Keys static class; please check the official documentation at http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/Input.Keys.html to access the whole list.

boolean wPressed = Gdx.input.isKeyPressed(Keys.W);
boolean aPressed = Gdx.input.isKeyPressed(Keys.A);
boolean sPressed = Gdx.input.isKeyPressed(Keys.S);
boolean dPressed = Gdx.input.isKeyPressed(Keys.D);

Most tablets and phones come with accelerometers. These sensors detect the device acceleration along the three axes relative to the Earth's gravitational field. Axes are queried separately using methods similar to Gdx.input.getAccelerometerX(). The values we obtain lie within the [-10.0, 10.0] range:

float accelerometerX = Gdx.input.getAccelerometerX();
float accelerometerY = Gdx.input.getAccelerometerY();
float accelerometerZ = Gdx.input.getAccelerometerZ();

Other devices also feature a compass, which is often used for map applications such as Google Maps. The Gdx.input.getPitch() function returns the device's orientation in degrees around its x axis, where positive x points to the west. The Gdx.input.getRoll() function returns the y axis rotation in degrees, where positive y points to the north. Finally, Gdx.input.getAzimuth() gives us the z axis rotation in degrees, where positive z points to the Earth's center:

float pitch = Gdx.input.getPitch();
float roll = Gdx.input.getRoll();
float azimuth = Gdx.input.getAzimuth();

The following diagram illustrates a phone's axes:

How to do it…

The result of each one of the queries we have made is shown on the screen using the draw() method in the BitmapFont class. Check the sample source code for more details.

How it works…

The input is one of the Libgdx main subsystems and is statically accessible from the Gdx environment class. Every backend is responsible for implementing all the functionality offered by the interface. Feel free to dig in to the Libgdx repository to find out on your own, but here is how each backend achieves it:

  • Desktop: This uses the LWJGL framework, which provides input features. The Input implementation is LwjglInput.
  • Android: The Android SDK is used by the AndroidInput class.
  • HTML 5: The GWTInput class uses the GWT input systems.
  • iOS: The IOSInput class uses the cocoatouch module in RoboVM.

Note

Peripherals can be disabled or enabled using the configuration parameters that are passed to the launcher class. See the Understanding the project structure and application life cycle recipe of Chapter 1, Diving into Libgdx, for more details.

There's more…

A couple of extra useful things that you can do with the input interface is check the peripheral availability and show or hide the on-screen keyboard.

Checking input availability

Desktop platforms always have a keyboard and a mouse, but they tend to lack touch screens and definitely do not have a compass or an accelerometer. On the other hand, smartphones typically have a compass and an accelerometer. It would not be rare to find yourself with the need to check whether a particular peripheral is available or not at runtime.

This is really easy to achieve with the Gdx.input.isPeripheralAvailable() method, passing in a constant that represents the device in question. The following code fragment has been added to InputPollingSample in order to check for input availability:

Gdx.input.isPeripheralAvailable(Peripheral.Accelerometer);
Gdx.input.isPeripheralAvailable(Peripheral.Compass);
Gdx.input.isPeripheralAvailable(Peripheral.HardwareKeyboard);
Gdx.input.isPeripheralAvailable(Peripheral.MultitouchScreen);
Gdx.input.isPeripheralAvailable(Peripheral.OnscreenKeyboard);
Gdx.input.isPeripheralAvailable(Peripheral.Vibrator);

Showing the on-screen keyboard

Phones and tablets may not have a hardware keyboard, but we can make them display an on-screen one if need be. In order to control whether or not such a keyboard should be active, you can use the following line of code:

Gdx.input.setOnScreenKeyboardVisible(boolean visible);
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.2.240