Meskipun sebagian besar game didesain untuk mendukung satu pengguna per perangkat Android, tetapi game juga dapat mendukung beberapa pengguna dengan pengontrol game yang disambungkan secara bersamaan di perangkat Android yang sama.
Tutorial ini membahas teknik dasar untuk menangani input di game multiplayer satu perangkat dari beberapa pengontrol yang tersambung. Ini mencakup mempertahankan pemetaan antara avatar pemain dan setiap perangkat pengontrol serta memproses peristiwa input pengontrol dengan tepat.
Memetakan pemain ke ID perangkat pengontrol
Saat pengontrol game tersambung ke perangkat Android, sistem menetapkan ID perangkat integer pada pengontrol tersebut. Anda bisa mendapatkan ID perangkat untuk pengontrol
game yang tersambung dengan memanggil InputDevice.getDeviceIds()
, seperti yang ditunjukkan dalam Memverifikasi bahwa Pengontrol Game Tersambung. Kemudian Anda dapat mengaitkan setiap
ID perangkat dengan pemain di game Anda, dan memproses tindakan game untuk setiap pemain secara terpisah.
Catatan: Di perangkat yang menjalankan Android versi 4.1 (API level
16) dan yang lebih tinggi, Anda bisa mendapatkan deskriptor perangkat input menggunakan
getDescriptor()
, yang menampilkan nilai
string terus-menerus yang unik untuk perangkat input tersebut. Tidak seperti ID perangkat, nilai
deskriptor tidak akan berubah meskipun perangkat input terputus sambungannya, disambungkan kembali, atau
dikonfigurasi ulang.
Cuplikan kode di bawah ini menunjukkan cara menggunakan SparseArray
untuk mengaitkan avatar pemain dengan pengontrol tertentu. Dalam contoh ini,
variabel mShips
menyimpan kumpulan objek Ship
. Avatar pemain yang baru dibuat dalam game saat pengontrol baru dikaitkan oleh pengguna, dan dihapus saat pengontrol terkaitnya dihapus.
Metode callback onInputDeviceAdded()
dan onInputDeviceRemoved()
merupakan bagian dari lapisan abstraksi yang diperkenalkan di Mendukung Pengontrol di Seluruh Versi Android. Dengan menerapkan
callback pemroses ini, game Anda dapat mengidentifikasi ID perangkat pengontrol game saat
pengontrol ditambahkan atau dihapus. Deteksi ini kompatibel dengan Android versi 2.3 (API level 9) dan yang lebih tinggi.
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); }
Memproses beberapa input pengontrol
Game Anda harus menjalankan loop berikut untuk memproses input dari beberapa pengontrol:
- Mendeteksi apakah peristiwa input terjadi.
- Mengidentifikasi sumber input dan ID perangkatnya.
- Berdasarkan tindakan yang ditunjukkan oleh kode tombol peristiwa input atau nilai sumbu, memperbarui avatar pemain yang dikaitkan dengan ID perangkat tersebut.
- Merender dan memperbarui antarmuka pengguna.
Peristiwa input KeyEvent
dan MotionEvent
memiliki ID perangkat yang dikaitkan dengannya. Game Anda dapat memanfaatkan ini
untuk menentukan dari pengontrol mana peristiwa input berasal, dan memperbarui
avatar pemain yang dikaitkan dengan pengontrol tersebut.
Cuplikan kode berikut menunjukkan cara agar Anda bisa mendapatkan referensi avatar pemain yang sesuai dengan ID perangkat pengontrol game, dan memperbarui game berdasarkan penekanan tombol di pengontrol oleh pengguna.
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); }
Perlu diperhatikan: Sebagai praktik terbaik, saat pengontrol game pengguna terputus sambungannya, Anda harus menjeda game dan menanyakan apakah pengguna ingin menyambungkan kembali.