В libGDX игре или приложении обработка событий позволяет получить более детальную и прежде всего хронологическую информацию о входных данных от пользователя. Обработка событий
обеспечивает способ реализации взаимодействия с пользовательским интерфейсом, где важны конкретные последовательности ввода, например зажатие кнопки и
затем отпускание означает, что пользователь нажал кнопку. Такое взаимодействие трудно реализовать с помощью
опроса состояния клавиши.
Процессор ввода
Обработка событий осуществляется с помощью общего шаблона наблюдателя. Сначала мы должны реализовать интерфейс обработчик, называемый InputProcessor
:
public class MyInputProcessor implements InputProcessor {
@Override
public boolean keyDown (int keycode) {
return false;
}
@Override
public boolean keyUp (int keycode) {
return false;
}
@Override
public boolean keyTyped (char character) {
return false;
}
@Override
public boolean touchDown (int x, int y, int pointer, int button) {
return false;
}
@Override
public boolean touchUp (int x, int y, int pointer, int button) {
return false;
}
@Override
public boolean touchDragged (int x, int y, int pointer) {
return false;
}
@Override
public boolean touchMoved (int x, int y) {
return false;
}
@Override
public boolean scrolled (int amount) {
return false;
}
}
Первые три метода позволяют перехватывать события клавиатуры:
- keyDown(): метод вызывается, когда была нажата клавиша. Сообщает код клавиши, который можно найти в
Keys классе.
- keyUp(): метод вызывается, когда была отпущена клавиша. Сообщает код клавиши, как указано выше.
- keyTyped(): метод вызывается, когда был сгенерирован Unicode символ при вводе с клавиатуры.
keyTyped()
метод может быть
использован для реализации текстовых полей и аналогичных элементов пользовательского интерфейса.
Следующие три метода сообщают о событиях мыши и сенсорного экрана:
- touchDown(): метод вызывается, когда палец коснулся экрана или была нажата кнопка мыши. Сообщает последние известные координаты, а также
индекс указателя и кнопку мыши (для сенсорных экранов всегда
Buttons.LEFT).
- touchUp(): метод вызывается, когда палец был убран с экрана или была отпущена кнопка мыши. Сообщает последние известные координаты, а также
индекс указателя и кнопку мыши (для сенсорных экранов всегда
Buttons.LEFT
).
- touchDragged(): метод вызывается, когда палец перемещается по экрану или перемещается мышь с нажатой кнопкой. Какая была нажата кнопка – не
сообщается, так как во время движения могло быть нажато несколько кнопок. В libGDX вы можете использовать
Gdx.input.isButtonPressed()
метод для проверки определенной кнопки.
- touchMoved(): метод вызывается, когда мышь перемещается по экрану без нажатой кнопки. Это событие имеет значение только для персонального
компьютера, и никогда не будет вызываться на устройствах с сенсорным экраном, где вы можете получить только
touchDragged()
событие.
- scrolled(): метод вызывается, когда совершается прокрутка колеса мыши. Сообщает значение -1 или 1, в зависимости от направления вращения.
Этот метод никогда не вызывается для устройств с сенсорным экраном.
Каждый из методов возвращает boolean
значение. Почему это так, мы изучим в разделе о классе InputMultiplexer
.
После реализации InputProcessor
нужно сказать об этом libGDX, чтобы фреймворк мог вызвать ее, когда придет новое событие.
MyInputProcessor inputProcessor = new MyInputProcessor();
Gdx.input.setInputProcessor(inputProcessor);
С этого момента все новые события ввода будет сообщаться MyInputProcessor экземпляру.
InputAdapter
В libGDX существует InputAdapter
класс, который реализует полностью интерфейс InputProcessor
, возвращая false в каждом методе.
Вы можете наследоваться от InputAdapter
класса и переопределить необходимые методы. Также можно использовать анонимные внутренние классы.
Gdx.input.setInputProcessor(new InputAdapter(){
public boolean touchDown(int x,int y,int pointer,int button){
// код при нажатии
return true; // возвращает true, сообщая, что событие было обработано
}
public boolean touchUp(int x,int y,int pointer,int button){
// код при отпускании
return true; // возвращает true, сообщая, что событие было обработано
}
});
InputMultiplexer
Иногда хочется иметь несколько InputProcessor
, например один процессор для пользовательского интерфейса, который лучше вызывать первым, а
второй процессор для событий ввода, который управляет игровым миром. Для достижения этой цели можно воспользоваться
InputMultiplexer классом libGDX фреймворка.
InputMultiplexer multiplexer = new InputMultiplexer();
multiplexer.addProcessor(new MyUiInputProcessor());
multiplexer.addProcessor(new MyGameInputProcessor());
Gdx.input.setInputProcessor(multiplexer);
Класс InputMultiplexer
будет перенаправлять новые события первому InputProcessor
. Если этот процессор вернет
false
из
вызванного метода обработки события, это указывает на то, что событие не было обработано и мультиплексор передаст событие другому процессору.
Благодаря этому механизму в libGDX, MyUiInputProcessor
может обрабатывать любые события, которые исходят от элементов управления и
передавать любые другие события в MyGameInputProcessor
.
Пример непрерывной обработки ввода
Если вы хотите перемещать в игре персонажа, используя процессор ввода, то вы заметите, что персонаж будет двигаться только тогда, когда нажата клавиша. Для
непрерывной обработки событий ввода или перемещения спрайта, вы можете добавить boolean
флаг в класс персонажа.
public class Bob
{
boolean leftMove;
boolean rightMove;
...
updateMotion()
{
if (leftMove)
{
x -= 5 * Gdx.graphics.getDeltaTime();
}
if (rightMove)
{
x += 5 * Gdx.graphics.getDeltaTime();
}
}
...
public void setLeftMove(boolean t)
{
if(rightMove && t) rightMove = false;
leftMove = t;
}
public void setRightMove(boolean t)
{
if(leftMove && t) leftMove = false;
rightMove = t;
}
Процессор ввода
...
@Override
public boolean keyDown(int keycode)
{
switch (keycode)
{
case Keys.LEFT:
bob.setLeftMove(true);
break;
case Keys.RIGHT:
bob.setRightMove(true);
break;
}
return true;
}
@Override
public boolean keyUp(int keycode)
{
switch (keycode)
{
case Keys.LEFT:
bob.setLeftMove(false);
break;
case Keys.RIGHT:
bob.setRightMove(false);
break;
}
return true;
}