Страницы

Поиск по вопросам

понедельник, 15 июля 2019 г.

Как считывать данные с игровых контроллеров?

Я новичок в разработке на 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 соответсвенно.
}

Комментариев нет:

Отправить комментарий