Я новичок в разработке на Android. Появилась необходимость обеспечить поддержку игровых контроллеров для Android c версией 4.3 и выше. Я нашел информацию на developer.android.com, но с ней сложно разбираться, в скачанном примере очень много не нужного например интерфейсы для обратной совместимости с Android 3.1 и прочее. Есть ли простые beginners guide на эту тему? Не могли бы вы поделиться ссылками и прочим. Любая полезная информация по этой теме.
P.S. Сейчас я пытаюсь подключить геймпад от PS4, но как я понял они работают по стандартам, и обеспечив поддержку одного, в принципе должны работать и остальные.
Ответ
Необходимо переопределить 2 метода:
public boolean onGenericMotionEvent(MotionEvent event){}
public boolean onKeyDown(int keyCode, KeyEvent event){}
С помощью первого можно получать значения со "стиков", а с помощью второго получать id нажатой кнопки.
Пример использования onKeyDown:
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((event.getSource() & InputDevice.SOURCE_GAMEPAD)
== InputDevice.SOURCE_GAMEPAD) {
switch(keyCode){
case 109:
// реакция на кнопку с кодом 109
break;
case 108:
//реакция на кнопку с кодом 108
break;
}
return true;
}
return super.onKeyDown(keyCode, event);
}
C использованием onGenericMotionEvent все немного сложнее, описывать все подробно не буду, прочитать об этом можно тут. Пример кода с Android Developer, на выходе дает от [-1:1] по осям x и y. Итоговые значения получаем в методе processJoystickInput
public boolean onGenericMotionEvent(MotionEvent event) {
// Check that the event came from a game controller
if ((event.getSource() & InputDevice.SOURCE_JOYSTICK) ==
InputDevice.SOURCE_JOYSTICK &&
event.getAction() == MotionEvent.ACTION_MOVE) {
// Process all historical movement samples in the batch
final int historySize = event.getHistorySize();
// Process the movements starting from the
// earliest historical position in the batch
for (int i = 0; i < historySize; i++) {
// Process the event at historical position i
processJoystickInput(event, i);
}
// Process the current movement sample in the batch (position -1)
processJoystickInput(event, -1);
return true;
}
return super.onGenericMotionEvent(event);
}
private static float getCenteredAxis(MotionEvent event,
InputDevice device, int axis, int historyPos) {
final InputDevice.MotionRange range =
device.getMotionRange(axis, event.getSource());
// A joystick at rest does not always report an absolute position of
// (0,0). Use the getFlat() method to determine the range of values
// bounding the joystick axis center.
if (range != null) {
final float flat = range.getFlat();
final float value =
historyPos < 0 ? event.getAxisValue(axis):
event.getHistoricalAxisValue(axis, historyPos);
// Ignore axis values that are within the 'flat' region of the
// joystick axis center.
if (Math.abs(value) > flat) {
return value;
}
}
return 0;
}
private void processJoystickInput(MotionEvent event,
int historyPos) {
InputDevice mInputDevice = event.getDevice();
// Calculate the horizontal distance to move by
// using the input value from one of these physical controls:
// the left control stick, hat axis, or the right control stick.
float x = getCenteredAxis(event, mInputDevice,
MotionEvent.AXIS_X, historyPos);
if (x == 0) {
x = getCenteredAxis(event, mInputDevice,
MotionEvent.AXIS_HAT_X, historyPos);
}
if (x == 0) {
x = getCenteredAxis(event, mInputDevice,
MotionEvent.AXIS_Z, historyPos);
}
// Calculate the vertical distance to move by
// using the input value from one of these physical controls:
// the left control stick, hat switch, or the right control stick.
float y = getCenteredAxis(event, mInputDevice,
MotionEvent.AXIS_Y, historyPos);
if (y == 0) {
y = getCenteredAxis(event, mInputDevice,
MotionEvent.AXIS_HAT_Y, historyPos);
}
if (y == 0) {
y = getCenteredAxis(event, mInputDevice,
MotionEvent.AXIS_RZ, historyPos);
}
// x и y значение осей х и y соответсвенно.
}
Комментариев нет:
Отправить комментарий