Większość gier została zaprojektowana z myślą o jednym użytkowniku każdego urządzenia z Androidem, Można również obsługiwać wielu użytkowników za pomocą kontrolerów do gier, jednocześnie na tym samym urządzeniu z Androidem.
W tym wykładzie omówione zostaną podstawowe techniki radzenia sobie z danymi gra wieloosobowa na różnych urządzeniach, korzystając z kilku połączonych kontrolerów. Obejmuje to m.in. zachowanie mapowania między awatarami graczy a każdym urządzeniem kontrolera; odpowiednie zdarzenia wejściowe kontrolera przetwarzania.
Zmapuj odtwarzacze na identyfikatory urządzeń kontrolera
Gdy kontroler gry jest podłączony do urządzenia z Androidem,
przypisuje mu identyfikator urządzenia w postaci liczby całkowitej. Możesz uzyskać identyfikatory połączonych urządzeń
kontrolerów gier, wywołując metodę InputDevice.getDeviceIds()
, jak pokazano w sekcji Sprawdzanie, czy kontroler do gier jest połączony. Następnie możesz powiązać każdy z nich,
z graczem w grze i przetwarzaj działania każdego z nich z osobna.
Uwaga: na urządzeniach z Androidem 4.1 (interfejs API)
poziomu 16) i wyższych, deskryptor urządzenia wejściowego można uzyskać za pomocą funkcji
getDescriptor()
, która zwraca unikalną wartość
wartość ciągu trwałego dla urządzenia wejściowego. W przeciwieństwie do identyfikatora urządzenia deskryptor
nie zmienia się nawet wtedy, gdy urządzenie wejściowe jest odłączone, podłączone ponownie,
ponowna konfiguracja.
Fragment kodu poniżej pokazuje, jak używać tabeli SparseArray
aby powiązać awatar gracza z konkretnym kontrolerem. W tym przykładzie para klucz-wartość
Zmienna mShips
przechowuje kolekcję Ship
obiektów. Nowy
awatar gracza jest tworzony w grze, gdy użytkownik podłącza nowy kontroler.
i usuwane po usunięciu powiązanego kontrolera.
Wywołanie zwrotne onInputDeviceAdded()
i onInputDeviceRemoved()
są częścią warstwy abstrakcji wprowadzonej
Obsługa kontrolerów na różnych wersjach Androida. Dzięki wdrożeniu
na wywołaniach zwrotnych detektora, gra może identyfikować identyfikator urządzenia kontrolera gry, gdy
dodanie lub usunięcie kontrolera. Wykrywanie jest zgodne z Androidem 2.3
(poziom interfejsu API 9) i wyższy.
Kotlin
private val ships = SparseArray<Ship>() override fun onInputDeviceAdded(deviceId: Int) { getShipForID(deviceId) } override fun onInputDeviceRemoved(deviceId: Int) { removeShipForID(deviceId) } private fun getShipForID(shipID: Int): Ship { return ships.get(shipID) ?: Ship().also { ships.append(shipID, it) } } private fun removeShipForID(shipID: Int) { ships.remove(shipID) }
Java
private final SparseArray<Ship> ships = new SparseArray<Ship>(); @Override public void onInputDeviceAdded(int deviceId) { getShipForID(deviceId); } @Override public void onInputDeviceRemoved(int deviceId) { removeShipForID(deviceId); } private Ship getShipForID(int shipID) { Ship currentShip = ships.get(shipID); if ( null == currentShip ) { currentShip = new Ship(); ships.append(shipID, currentShip); } return currentShip; } private void removeShipForID(int shipID) { ships.remove(shipID); }
Przetwarzaj dane wejściowe kontrolera
Twoja gra powinna wykonywać tę pętlę, aby przetworzyć danych wejściowych z kilku kontrolerów:
- Wykrywanie, czy wystąpiło zdarzenie wejściowe.
- Identyfikowanie źródła danych wejściowych i jego identyfikatora urządzenia.
- W zależności od działania wskazanego przez kod klucza zdarzenia wejściowego lub wartość osi zaktualizować awatara gracza powiązany z identyfikatorem urządzenia.
- Renderowanie i aktualizowanie interfejsu użytkownika.
Dane wejściowe: KeyEvent
i MotionEvent
zdarzenia mają powiązane identyfikatory urządzeń. Twoja gra może wykorzystać:
aby określić, z którego kontrolera pochodzi zdarzenie wejściowe, i zaktualizować
awatar gracza powiązanego z tym kontrolerem.
Ten fragment kodu pokazuje, jak uzyskać odniesienie do awatara gracza odpowiadający identyfikatorowi kontrolera do gier i zaktualizować grę na podstawie naciśnięcie przycisku użytkownika na tym kontrolerze.
Kotlin
override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean { if (event.source and InputDevice.SOURCE_GAMEPAD == InputDevice.SOURCE_GAMEPAD) { event.deviceId.takeIf { it != -1 }?.also { deviceId -> val currentShip: Ship = getShipForID(deviceId) // Based on which key was pressed, update the player avatar // (e.g. set the ship headings or fire lasers) return true } } return super.onKeyDown(keyCode, event) }
Java
@Override public boolean onKeyDown(int keyCode, KeyEvent event) { if ((event.getSource() & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD) { int deviceId = event.getDeviceId(); if (deviceId != -1) { Ship currentShip = getShipForId(deviceId); // Based on which key was pressed, update the player avatar // (e.g. set the ship headings or fire lasers) ... return true; } } return super.onKeyDown(keyCode, event); }
Uwaga: zgodnie ze sprawdzonymi metodami, kontroler do gier rozłącza się. Wstrzymaj grę i zapytaj użytkownika, Użytkownik chce ponownie nawiązać połączenie.