儘管大多數遊戲都設計為使用單一 Android 裝置支援單一使用者。 系統也能為多個使用者 並同時連線到同一部 Android 裝置。
本課程介紹了處理單張輸入資料 從多個連線控制器中操控多款裝置的多人遊戲。這包括 玩家顯示圖片和每個控制器裝置會保持對應 妥善處理控制器輸入事件
將玩家對應至控制器裝置 ID
當遊戲控制器連線至 Android 裝置時,系統
為該版本指派一個整數的裝置 ID您可以取得已連結
呼叫 InputDevice.getDeviceIds()
來呼叫遊戲控制器,如「確認遊戲控制器已連線」一節中所述。這樣就可以將每個
遊戲中玩家專用的裝置 ID,系統會分別處理每位玩家的遊戲動作。
注意: 在搭載 Android 4.1 (API) 的裝置上
16 級) 以上版本,則可以使用
getDescriptor()
:傳回不重複的
輸入裝置的永久字串值。與裝置 ID 不同
值不會改變,即使輸入裝置已中斷連線、重新連線或
重新設定。
下列程式碼片段說明如何使用 SparseArray
將玩家的顯示圖片與特定控制器建立關聯。在這個範例中,
mShips
變數會儲存 Ship
物件的集合。新的
當使用者附加新控制器時,系統會在遊戲中建立玩家顯示圖片。
並在相關聯的控制器移除時移除。
onInputDeviceAdded()
和 onInputDeviceRemoved()
回呼
方法均屬於
支援所有 Android 版本的控制器。導入這些
事件監聽器回呼,遊戲就能識別遊戲控制器的裝置 ID,
系統就會新增或移除控制器這項偵測功能與 Android 2.3 相容
(API 級別 9) 以上版本。
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); }
處理多個控制器輸入內容
遊戲應執行下列迴圈來處理 多個控制器的輸入:
- 偵測輸入事件是否發生。
- 識別輸入來源及其裝置 ID。
- 根據輸入事件按鍵碼或軸值指定的動作。 更新與該裝置 ID 相關聯的玩家顯示圖片。
- 轉譯及更新使用者介面。
KeyEvent
和 MotionEvent
輸入來源
事件都有相關聯的裝置 ID。您的遊戲可利用
以便判斷輸入事件來自哪個控制器,並更新
與該控制器相關聯的玩家顯示圖片。
下列程式碼片段顯示如何取得玩家顯示圖片參照 對應遊戲控制器裝置 ID,並根據 使用者的按鈕。
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); }
注意: 最佳做法是 遊戲控制器中斷連線,建議您暫停遊戲,並詢問使用者是否 想要重新連線。