Na poziomie systemu Android zgłasza kody zdarzeń wejściowych z kontrolerów gier jako kody kluczy i wartości osi Androida. W grze możesz otrzymać te kody i przekształcać je w konkretne działania w grze.
Gdy gracze łączą się fizycznie lub bezprzewodowo z kontrolerem do gier
urządzeń z Androidem, system automatycznie wykryje kontroler,
jako urządzenie wejściowe i rozpoczyna raportowanie zdarzeń wejściowych. Twoja gra może otrzymywać
tych zdarzeń wejściowych, implementując poniższe metody wywołania zwrotnego w aktywnych
Activity
lub zaznaczone View
(należy
zaimplementuj wywołania zwrotne dla Activity
albo
View
, ale nie oba):
- Od
Activity
:dispatchGenericMotionEvent(android.view. MotionEvent)
Wywoływane w celu przetwarzania ogólnych zdarzeń ruchu, takich jak ruchy joysticka.
dispatchKeyEvent(android.view.KeyEvent)
Wywoływane w celu przetwarzania kluczowych zdarzeń, takich jak naciśnięcie lub zwolnienie pada do gier lub pada kierunkowego.
- Od
View
:onGenericMotionEvent(android.view.MotionEvent)
Wywoływane w celu przetwarzania ogólnych zdarzeń ruchu, takich jak ruchy joysticka.
onKeyDown(int, android.view.KeyEvent)
Wywoływane w celu przetworzenia naciśnięcia klawisza fizycznego, takiego jak pad do gier lub Przycisk na padzie kierunkowym.
onKeyUp(int, android.view.KeyEvent)
Wywoływane w celu przetworzenia zwolnienia klawisza fizycznego, takiego jak pad do gier lub Przycisk na padzie kierunkowym.
Zalecanym sposobem jest rejestrowanie zdarzeń z
konkretny obiekt View
, z którym użytkownik wchodzi w interakcję.
Aby uzyskać informacje, sprawdź następujące obiekty podane przez wywołania zwrotne
o typie otrzymanego zdarzenia wejściowego:
KeyEvent
- Obiekt opisujący
zdarzeń przycisków pada kierunkowego i pada do gier. Kluczowym zdarzeniom towarzyszy reklama
kod klucza wskazujący wywołany konkretny przycisk, np.
DPAD_DOWN
lubBUTTON_A
. Możesz uzyskać kod klucza, wywołującgetKeyCode()
lub z klucza wywołań zwrotnych zdarzeń, takich jakonKeyDown()
MotionEvent
- Obiekt opisujący dane wejściowe pochodzące z joysticka i spustu pobocznego
i ruchu. Zdarzeniom ruchu towarzyszy kod działania i zestaw
wartości osi. Kod działania określa zachodzącą zmianę stanu
np. poruszając joystickiem. Wartości na osi opisują pozycję i inne parametry
właściwości ruchu dla określonej kontroli fizycznej, takich jak
AXIS_X
lubAXIS_RTRIGGER
Aby uzyskać kod działania, wywołując funkcjęgetAction()
i wartość osi przez Dzwonię pod numergetAxisValue()
.
Z tego wykładu dowiesz się, jak radzić sobie z danymi pochodzącymi z najczęstszych typów
elementy sterujące (przyciski pada do gier, pady kierunkowe i
joysticki) na ekranie gry przez wdrożenie
View
metoda wywołania zwrotnego i przetwarzanie
KeyEvent
i MotionEvent
obiektów.
Sprawdź, czy kontroler do gier jest podłączony
Podczas raportowania zdarzeń wejściowych Android nie rozróżnia
między zdarzeniami pochodzącymi z kontrolera innego niż kontroler do gry a zdarzeniami,
za pomocą kontrolera do gier. Na przykład działanie na ekranie dotykowym generuje
Zdarzenie AXIS_X
, które reprezentuje symbol X
współrzędną powierzchni dotykowej, ale joystick generuje
Zdarzenie AXIS_X
, które reprezentuje pozycję X joysticka. Jeśli
w przypadku gry zależy od obsługi danych wejściowych kontrolera, najpierw sprawdź,
że zdarzenie wejściowe pochodzi z odpowiedniego typu źródła.
Aby sprawdzić, czy podłączone urządzenie wejściowe jest kontrolerem gry, wywołaj
getSources()
, aby uzyskać połączone pole bitowe
typów źródeł wejściowych obsługiwanych przez dane urządzenie. Następnie można sprawdzić, czy
ustaw te pola:
- Typ źródła
SOURCE_GAMEPAD
wskazuje czy urządzenie wejściowe ma przyciski pada do gier (np.BUTTON_A
). Pamiętaj, że to źródło nie wskazuje bezpośrednio, czy kontroler do gier ma przyciski padów kierunkowych, chociaż większość padów do gier ma sterowanie kierunkowe. - Typ źródła
SOURCE_DPAD
wskazuje, że urządzenie wejściowe ma przyciski pada kierunkowego (np.DPAD_UP
). - Typ źródła:
SOURCE_JOYSTICK
wskazuje, że urządzenie wejściowe jest wyposażone w analogowe gałki sterujące (np. joystick rejestrujący ruchy wzdłuż liniiAXIS_X
iAXIS_Y
).
Poniższy fragment kodu zawiera metodę pomocniczą, która pozwala sprawdzić, czy podłączone urządzenia wejściowe to kontrolery gier. Jeśli tak, metoda pobiera identyfikatory urządzeń kontrolerów do gier. Następnie możesz powiązać każde urządzenie Identyfikator gracza w grze i przetwarzaj działania w przypadku każdego połączenia z osobna. Dowiedz się więcej o obsłudze kilku kontrolerów do gier które są jednocześnie połączone z tym samym urządzeniem z Androidem, zobacz Obsługa wielu kontrolerów do gier.
Kotlin
fun getGameControllerIds(): List<Int> { val gameControllerDeviceIds = mutableListOf<Int>() val deviceIds = InputDevice.getDeviceIds() deviceIds.forEach { deviceId -> InputDevice.getDevice(deviceId).apply { // Verify that the device has gamepad buttons, control sticks, or both. if (sources and InputDevice.SOURCE_GAMEPAD == InputDevice.SOURCE_GAMEPAD || sources and InputDevice.SOURCE_JOYSTICK == InputDevice.SOURCE_JOYSTICK) { // This device is a game controller. Store its device ID. gameControllerDeviceIds .takeIf { !it.contains(deviceId) } ?.add(deviceId) } } } return gameControllerDeviceIds }
Java
public ArrayList<Integer> getGameControllerIds() { ArrayList<Integer> gameControllerDeviceIds = new ArrayList<Integer>(); int[] deviceIds = InputDevice.getDeviceIds(); for (int deviceId : deviceIds) { InputDevice dev = InputDevice.getDevice(deviceId); int sources = dev.getSources(); // Verify that the device has gamepad buttons, control sticks, or both. if (((sources & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD) || ((sources & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK)) { // This device is a game controller. Store its device ID. if (!gameControllerDeviceIds.contains(deviceId)) { gameControllerDeviceIds.add(deviceId); } } } return gameControllerDeviceIds; }
Warto też sprawdzić możliwości indywidualnego wprowadzania tekstu obsługiwane przez podłączony kontroler do gier. Może to być przydatne, jeśli na przykład chcesz, aby gra korzystała tylko z danych wejściowych z zestawu elementów sterujących; .
Do wykrywania, czy określony kod klucza lub osi jest obsługiwany przez połączone kontroler do gier, użyj tych technik:
- W Androidzie 4.4 (poziom interfejsu API 19) lub nowszym możesz sprawdzić, czy kod klucza
obsługiwane na połączonym kontrolerze do gier przez wywołanie
hasKeys(int...)
- W Androidzie 3.1 (poziom interfejsu API 12) lub nowszym znajdziesz wszystkie dostępne osie
obsługiwane na połączonym kontrolerze do gier po pierwszym wywołaniu
getMotionRanges()
Następnie w każdym kolejnym kroku ZwróconoInputDevice.MotionRange
obiekt, wywołaniegetAxis()
, aby uzyskać identyfikator jej osi.
Przetwarzaj naciśnięcia przycisków na padzie do gier
Rysunek 1 pokazuje, jak Android mapuje kody kluczy i wartości osi na większości kontrolerów do gier.
Objaśnienia na ilustracji odnoszą się do tych informacji:
Typowe kody klawiszy generowane przez naciśnięcia przycisków na padzie do gier to
BUTTON_A
,
BUTTON_B
,
BUTTON_SELECT
,
i BUTTON_START
. Jakaś gra
kontrolery uruchamiają też kod klawisza DPAD_CENTER
po naciśnięciu środkowej części paska poprzeczki na padzie kierunkowym. Twoje
gra może sprawdzić kod klucza, wywołując funkcję getKeyCode()
lub wywołań zwrotnych kluczowych zdarzeń, takich jak
onKeyDown()
,
Jeśli jest to zdarzenie związane z grą, potraktuj je jako
akcji. Tabela 1 zawiera listę zalecanych działań w grach do
przyciski pada do gier.
Akcja | Kod klawisza przycisku |
---|---|
Uruchom grę w menu głównym albo wstrzymaj/wznów grę podczas gry | BUTTON_START * |
Wyświetl menu | BUTTON_SELECT *
i KEYCODE_MENU * |
Takie same jak w przypadku nawigacji Wstecz w Androidzie opisane w Projekt nawigacji Google. | KEYCODE_BACK |
Powrót do poprzedniego elementu w menu | BUTTON_B |
Potwierdź wybór lub wykonaj główne działanie w grze | BUTTON_A i
DPAD_CENTER |
* Gra nie powinna polegać na obecności przycisków Start, Select ani Menu.
Wskazówka: rozważ dodanie ekranu konfiguracji pozwala użytkownikom personalizować własne mapowania kontrolera działań w grze.
Ten fragment kodu pokazuje, jak zastąpić
onKeyDown()
do
kojarz BUTTON_A
i
Naciśnięcia przycisku: DPAD_CENTER
z akcją w grze.
Kotlin
class GameView(...) : View(...) { ... override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean { var handled = false if (event.source and InputDevice.SOURCE_GAMEPAD == InputDevice.SOURCE_GAMEPAD) { if (event.repeatCount == 0) { when (keyCode) { // Handle gamepad and D-pad button presses to navigate the ship ... else -> { keyCode.takeIf { isFireKey(it) }?.run { // Update the ship object to fire lasers ... handled = true } } } } if (handled) { return true } } return super.onKeyDown(keyCode, event) } // Here we treat Button_A and DPAD_CENTER as the primary action // keys for the game. private fun isFireKey(keyCode: Int): Boolean = keyCode == KeyEvent.KEYCODE_DPAD_CENTER || keyCode == KeyEvent.KEYCODE_BUTTON_A }
Java
public class GameView extends View { ... @Override public boolean onKeyDown(int keyCode, KeyEvent event) { boolean handled = false; if ((event.getSource() & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD) { if (event.getRepeatCount() == 0) { switch (keyCode) { // Handle gamepad and D-pad button presses to // navigate the ship ... default: if (isFireKey(keyCode)) { // Update the ship object to fire lasers ... handled = true; } break; } } if (handled) { return true; } } return super.onKeyDown(keyCode, event); } private static boolean isFireKey(int keyCode) { // Here we treat Button_A and DPAD_CENTER as the primary action // keys for the game. return keyCode == KeyEvent.KEYCODE_DPAD_CENTER || keyCode == KeyEvent.KEYCODE_BUTTON_A; } }
Uwaga: na Androidzie 4.2 (interfejs API)
17) i niższym, system traktuje
BUTTON_A
jako Androida
domyślny klawisz Wstecz. Jeśli Twoja aplikacja obsługuje te Androida
pamiętaj, aby traktować te wersje
BUTTON_A
jako główna gra
działania. Aby określić bieżący pakiet Android SDK
wersji na urządzeniu, zapoznaj się z
Wartość: Build.VERSION.SDK_INT
.
Przetwarzaj wprowadzanie za pomocą pada kierunkowego
Czterokierunkowy pad kierunkowy (pad kierunkowy) jest standardowym elementem wielu gier
i kontrolerach. Android zgłasza naciśnięcia przycisków W GÓRĘ i W DÓŁ na padzie kierunkowym jako
AXIS_HAT_Y
zdarzeń z zakresem
od -1,0 (góra) do 1,0 (dół), a pad kierunkowy w lewo lub w prawo naciska jako
Zdarzenia (AXIS_HAT_X
) o zakresie od -1,0
(od lewej) do 1,0 (po prawej).
Niektóre kontrolery zgłaszają naciśnięcia na padach kierunkowych wraz z kodem klawisza. Jeśli Twoja gra naciska na pad kierunkowy, należy traktować zdarzenia osi kapelusza oraz kody klawiszy jako te same zdarzenia wejściowe, zgodnie z zaleceniami w tabeli 2.
Akcja | Kod klawisza pada kierunkowego | Kod osi kapelusza |
---|---|---|
W górę | KEYCODE_DPAD_UP |
AXIS_HAT_Y (dla wartości od 0 do -1,0) |
W dół | KEYCODE_DPAD_DOWN |
AXIS_HAT_Y (dla wartości od 0 do 1,0) |
Przenieś w lewo | KEYCODE_DPAD_LEFT |
AXIS_HAT_X (dla wartości od 0 do -1,0) |
Przenieś w prawo | KEYCODE_DPAD_RIGHT |
AXIS_HAT_X (dla wartości od 0 do 1,0) |
Ten fragment kodu pokazuje klasę pomocniczą, która pozwala sprawdzić kapelusz wartości osi i kodu klucza ze zdarzenia wejściowego w celu określenia kierunku pada kierunkowego.
Kotlin
class Dpad { private var directionPressed = -1 // initialized to -1 fun getDirectionPressed(event: InputEvent): Int { if (!isDpadDevice(event)) { return -1 } // If the input event is a MotionEvent, check its hat axis values. (event as? MotionEvent)?.apply { // Use the hat axis value to find the D-pad direction val xaxis: Float = event.getAxisValue(MotionEvent.AXIS_HAT_X) val yaxis: Float = event.getAxisValue(MotionEvent.AXIS_HAT_Y) directionPressed = when { // Check if the AXIS_HAT_X value is -1 or 1, and set the D-pad // LEFT and RIGHT direction accordingly. xaxis.compareTo(-1.0f) == 0 -> Dpad.LEFT xaxis.compareTo(1.0f) == 0 -> Dpad.RIGHT // Check if the AXIS_HAT_Y value is -1 or 1, and set the D-pad // UP and DOWN direction accordingly. yaxis.compareTo(-1.0f) == 0 -> Dpad.UP yaxis.compareTo(1.0f) == 0 -> Dpad.DOWN else -> directionPressed } } // If the input event is a KeyEvent, check its key code. (event as? KeyEvent)?.apply { // Use the key code to find the D-pad direction. directionPressed = when(event.keyCode) { KeyEvent.KEYCODE_DPAD_LEFT -> Dpad.LEFT KeyEvent.KEYCODE_DPAD_RIGHT -> Dpad.RIGHT KeyEvent.KEYCODE_DPAD_UP -> Dpad.UP KeyEvent.KEYCODE_DPAD_DOWN -> Dpad.DOWN KeyEvent.KEYCODE_DPAD_CENTER -> Dpad.CENTER else -> directionPressed } } return directionPressed } companion object { internal const val UP = 0 internal const val LEFT = 1 internal const val RIGHT = 2 internal const val DOWN = 3 internal const val CENTER = 4 fun isDpadDevice(event: InputEvent): Boolean = // Check that input comes from a device with directional pads. event.source and InputDevice.SOURCE_DPAD != InputDevice.SOURCE_DPAD } }
Java
public class Dpad { final static int UP = 0; final static int LEFT = 1; final static int RIGHT = 2; final static int DOWN = 3; final static int CENTER = 4; int directionPressed = -1; // initialized to -1 public int getDirectionPressed(InputEvent event) { if (!isDpadDevice(event)) { return -1; } // If the input event is a MotionEvent, check its hat axis values. if (event instanceof MotionEvent) { // Use the hat axis value to find the D-pad direction MotionEvent motionEvent = (MotionEvent) event; float xaxis = motionEvent.getAxisValue(MotionEvent.AXIS_HAT_X); float yaxis = motionEvent.getAxisValue(MotionEvent.AXIS_HAT_Y); // Check if the AXIS_HAT_X value is -1 or 1, and set the D-pad // LEFT and RIGHT direction accordingly. if (Float.compare(xaxis, -1.0f) == 0) { directionPressed = Dpad.LEFT; } else if (Float.compare(xaxis, 1.0f) == 0) { directionPressed = Dpad.RIGHT; } // Check if the AXIS_HAT_Y value is -1 or 1, and set the D-pad // UP and DOWN direction accordingly. else if (Float.compare(yaxis, -1.0f) == 0) { directionPressed = Dpad.UP; } else if (Float.compare(yaxis, 1.0f) == 0) { directionPressed = Dpad.DOWN; } } // If the input event is a KeyEvent, check its key code. else if (event instanceof KeyEvent) { // Use the key code to find the D-pad direction. KeyEvent keyEvent = (KeyEvent) event; if (keyEvent.getKeyCode() == KeyEvent.KEYCODE_DPAD_LEFT) { directionPressed = Dpad.LEFT; } else if (keyEvent.getKeyCode() == KeyEvent.KEYCODE_DPAD_RIGHT) { directionPressed = Dpad.RIGHT; } else if (keyEvent.getKeyCode() == KeyEvent.KEYCODE_DPAD_UP) { directionPressed = Dpad.UP; } else if (keyEvent.getKeyCode() == KeyEvent.KEYCODE_DPAD_DOWN) { directionPressed = Dpad.DOWN; } else if (keyEvent.getKeyCode() == KeyEvent.KEYCODE_DPAD_CENTER) { directionPressed = Dpad.CENTER; } } return directionPressed; } public static boolean isDpadDevice(InputEvent event) { // Check that input comes from a device with directional pads. if ((event.getSource() & InputDevice.SOURCE_DPAD) != InputDevice.SOURCE_DPAD) { return true; } else { return false; } } }
Tej klasy pomocniczej możesz używać w grze, gdziekolwiek chcesz:
Wprowadzanie tekstu na padzie kierunkowym (na przykład w
onGenericMotionEvent()
lub
onKeyDown()
wywołania zwrotne).
Na przykład:
Kotlin
private val dpad = Dpad() ... override fun onGenericMotionEvent(event: MotionEvent): Boolean { if (Dpad.isDpadDevice(event)) { when (dpad.getDirectionPressed(event)) { Dpad.LEFT -> { // Do something for LEFT direction press ... return true } Dpad.RIGHT -> { // Do something for RIGHT direction press ... return true } Dpad.UP -> { // Do something for UP direction press ... return true } ... } } // Check if this event is from a joystick movement and process accordingly. ... }
Java
Dpad dpad = new Dpad(); ... @Override public boolean onGenericMotionEvent(MotionEvent event) { // Check if this event if from a D-pad and process accordingly. if (Dpad.isDpadDevice(event)) { int press = dpad.getDirectionPressed(event); switch (press) { case LEFT: // Do something for LEFT direction press ... return true; case RIGHT: // Do something for RIGHT direction press ... return true; case UP: // Do something for UP direction press ... return true; ... } } // Check if this event is from a joystick movement and process accordingly. ... }
Przetwarzaj ruchy joysticka
Gdy gracz porusza joystickiem na kontrolerach do gier, Android zgłasza
MotionEvent
, który zawiera parametr
ACTION_MOVE
– kod działania i zaktualizowane
położenie osi joysticka. Twoja gra może używać danych dostarczonych przez
MotionEvent
, by sprawdzić, czy ruch joysticka
na to, co się wydarzyło.
Pamiętaj, że zdarzenia ruchu joysticka mogą zgrupować wiele próbek ruchu.
w obrębie jednego obiektu. Obiekt MotionEvent
zawiera
bieżącej pozycji dla każdej osi joysticka oraz wielu historycznych
dla każdej osi. Podczas raportowania zdarzeń ruchu o kodzie działania ACTION_MOVE
(np. ruchów joysticka), Android grupuje
wartości osi dla wydajności. Wartości historyczne na osi składają się
zbiór unikalnych wartości starszych niż bieżąca wartość osi i nowszych niż
we wszystkich wcześniejszych zdarzeniach ruchu. Zobacz
MotionEvent
– więcej informacji.
Możesz wykorzystać informacje historyczne, aby dokładniej renderować grę
ruchu obiektu w oparciu o dane wejściowe joysticka. Do
dla pobierania wartości bieżących i historycznych, wywołanie
getAxisValue()
lub getHistoricalAxisValue()
. Możesz też sprawdzić liczbę
punktów w zdarzeniu joysticka, wywołując
getHistorySize()
Ten fragment kodu pokazuje, jak możesz zastąpić
Wywołanie zwrotne onGenericMotionEvent()
do przetwarzania danych wejściowych joysticka. Najpierw musisz
przetwarzania wartości historycznych osi, a następnie przetwarzania jej bieżącej pozycji.
Kotlin
class GameView(...) : View(...) { override fun onGenericMotionEvent(event: MotionEvent): Boolean { // Check that the event came from a game controller return if (event.source and InputDevice.SOURCE_JOYSTICK == InputDevice.SOURCE_JOYSTICK && event.action == MotionEvent.ACTION_MOVE) { // Process the movements starting from the // earliest historical position in the batch (0 until event.historySize).forEach { i -> // Process the event at historical position i processJoystickInput(event, i) } // Process the current movement sample in the batch (position -1) processJoystickInput(event, -1) true } else { super.onGenericMotionEvent(event) } } }
Java
public class GameView extends View { @Override 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); } }
Przed użyciem sterowania joystickiem należy sprawdzić, czy a następnie odpowiednio obliczyć ruchy osi. Zwykle joysticki mają płaski obszar, czyli zakres wartości w pobliżu współrzędnych (0,0) na której oś jest uznawana za wyśrodkowaną. Jeśli wartość osi raportowana przez Android to płaski obszar, a kontroler należy traktować tak, jak spoczynek (czyli ruch nie może się ruszać wzdłuż obu osi).
Ten fragment kodu przedstawia metodę pomocniczą, która oblicza ruch wzdłuż
każdej osi. Wywołanie tej funkcji pomocniczej w metodzie processJoystickInput()
opisane poniżej.
Kotlin
private fun getCenteredAxis( event: MotionEvent, device: InputDevice, axis: Int, historyPos: Int ): Float { val range: InputDevice.MotionRange? = device.getMotionRange(axis, event.source) // 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. range?.apply { val value: Float = if (historyPos < 0) { event.getAxisValue(axis) } else { 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 0f }
Java
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; }
Oto jak można przetwarzać ruchy joysticka w Twoja gra:
Kotlin
private fun processJoystickInput(event: MotionEvent, historyPos: Int) { val inputDevice = event.device // 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. var x: Float = getCenteredAxis(event, inputDevice, MotionEvent.AXIS_X, historyPos) if (x == 0f) { x = getCenteredAxis(event, inputDevice, MotionEvent.AXIS_HAT_X, historyPos) } if (x == 0f) { x = getCenteredAxis(event, inputDevice, 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. var y: Float = getCenteredAxis(event, inputDevice, MotionEvent.AXIS_Y, historyPos) if (y == 0f) { y = getCenteredAxis(event, inputDevice, MotionEvent.AXIS_HAT_Y, historyPos) } if (y == 0f) { y = getCenteredAxis(event, inputDevice, MotionEvent.AXIS_RZ, historyPos) } // Update the ship object based on the new x and y values }
Java
private void processJoystickInput(MotionEvent event, int historyPos) { InputDevice inputDevice = 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, inputDevice, MotionEvent.AXIS_X, historyPos); if (x == 0) { x = getCenteredAxis(event, inputDevice, MotionEvent.AXIS_HAT_X, historyPos); } if (x == 0) { x = getCenteredAxis(event, inputDevice, 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, inputDevice, MotionEvent.AXIS_Y, historyPos); if (y == 0) { y = getCenteredAxis(event, inputDevice, MotionEvent.AXIS_HAT_Y, historyPos); } if (y == 0) { y = getCenteredAxis(event, inputDevice, MotionEvent.AXIS_RZ, historyPos); } // Update the ship object based on the new x and y values }
na potrzeby obsługi bardziej zaawansowanych kontrolerów do gier; funkcji wykraczających poza pojedynczy joystick, zastosuj następujące sprawdzone metody:
- Obsługuj 2 gałki kontrolera. Wiele kontrolerów do gier ma
lewy i prawy joystick. Na lewym skrzydle: Android
raportuje ruchy w poziomie jako
AXIS_X
zdarzeń a ruchy w pionie jako zdarzeniaAXIS_Y
. Ruch w poziomie prawej drążka jest raportowany jakoAXIS_Z
zdarzenia i zmiany w pionie jako Wydarzenia:AXIS_RZ
. Upewnij się, że obsługa obydwa kontrolery pozostają w kodzie. - Obsługuj naciśnięcia spustu pobocznego (ale podaj inne dane wejściowe
). Niektóre kontrolery mają lewe i prawe barki
wyzwalaczy. Jeśli te reguły są obecne, Android zgłasza naciśnięcie lewego spustu
jako zdarzenie
AXIS_LTRIGGER
oraz Naciśnięcie prawego spustuAXIS_RTRIGGER
. Android 4.3 (poziom interfejsu API 18) – kontroler, który tworzyAXIS_LTRIGGER
zgłasza też jednakowa wartość na osiAXIS_BRAKE
. to samo dotyczyAXIS_RTRIGGER
iAXIS_GAS
Android zgłasza wszystkie aktywatory analogowe dociśnień o znormalizowanej wartości od 0,0 (zwolnione) do 1,0 (w pełni naciśnięte). Nie Wszystkie kontrolery mają wyzwalacze, więc rozważ zezwolenie graczom na wykonywanie tych czynności działania w grze za pomocą innych przycisków.