Meskipun sebagian besar game didesain untuk mendukung satu pengguna per perangkat Android, Anda juga dapat mendukung beberapa pengguna dengan pengontrol {i>game<i} yang terhubung secara bersamaan di perangkat Android yang sama.
Tutorial ini mencakup beberapa teknik dasar untuk menangani input dalam single game multiplayer perangkat dari beberapa pengontrol yang terhubung. Hal ini mencakup mempertahankan pemetaan antara avatar pemain dan setiap perangkat pengontrol, dan memproses peristiwa input pengontrol dengan tepat.
Memetakan pemain ke ID perangkat pengontrol
Saat pengontrol game terhubung ke perangkat Android, sistem
menetapkan ID perangkat bilangan bulat. Anda bisa mendapatkan ID perangkat untuk
pengontrol game dengan memanggil InputDevice.getDeviceIds()
, seperti yang ditunjukkan dalam Memverifikasi Pengontrol Game Tersambung. Anda kemudian dapat
menghubungkan setiap
ID perangkat dengan pemain di game Anda, dan proses tindakan game untuk setiap pemain secara terpisah.
Catatan: Pada perangkat yang menjalankan Android 4.1 (API
level 16) dan yang lebih tinggi, Anda bisa mendapatkan deskriptor perangkat input menggunakan
getDescriptor()
, yang menampilkan
untuk perangkat input. Tidak seperti ID perangkat, deskriptor
nilai tidak akan berubah bahkan jika perangkat {i>input <i}
putus, terhubung kembali, atau
dikonfigurasi ulang.
Cuplikan kode di bawah menunjukkan cara menggunakan SparseArray
untuk mengaitkan avatar pemain dengan pengontrol tertentu. Dalam contoh ini,
Variabel mShips
menyimpan kumpulan objek Ship
. Fitur baru
avatar pemain dibuat dalam game saat {i>
controller<i} baru dipasang oleh pengguna,
dan dihapus saat pengontrol terkaitnya dihapus.
Callback onInputDeviceAdded()
dan onInputDeviceRemoved()
adalah bagian dari lapisan abstraksi yang diperkenalkan di
Mendukung Pengontrol di Berbagai Versi Android. Dengan menerapkan
Anda, game Anda dapat mengidentifikasi ID perangkat pengontrol game saat
{i>controller<i} ditambahkan atau dihapus. Deteksi ini kompatibel dengan Android 2.3
(level API 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, perbarui avatar pemain yang terkait dengan ID perangkat tersebut.
- Merender dan memperbarui antarmuka pengguna.
Input KeyEvent
dan MotionEvent
peristiwa memiliki ID perangkat yang terkait dengannya. Game Anda dapat memanfaatkan
ini untuk menentukan dari pengontrol mana peristiwa input itu berasal, dan memperbarui
avatar pemain yang terkait dengan pengontrol tersebut.
Cuplikan kode berikut menunjukkan cara mendapatkan referensi avatar pemain sesuai dengan ID perangkat pengontrol game, dan memperbarui game berdasarkan pengguna menekan tombol {i>controller<i} tersebut.
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); }
Catatan: Sebagai praktik terbaik, saat perilaku pengguna pengontrol game terputus, Anda harus menjeda game dan bertanya apakah pengguna ingin terhubung kembali.