Meskipun sebagian besar game didesain untuk mendukung satu pengguna per perangkat yang didukung Android, game juga dapat mendukung beberapa pengguna dengan pengontrol game yang disambungkan secara bersamaan di perangkat yang didukung Android yang sama.
Tutorial ini membahas beberapa 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 berteknologi Android, sistem akan menetapkan ID perangkat integer untuk 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.
Cuplikan kode menunjukkan cara menggunakan SparseArray untuk mengaitkan avatar pemain dengan pengontrol tertentu. Dalam contoh ini, variabel mShips
menyimpan kumpulan objek Ship. Avatar pemain 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 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, perbarui 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);
}