複数のゲーム コントローラをサポートする
コレクションでコンテンツを整理
必要に応じて、コンテンツの保存と分類を行います。
ほとんどのゲームは Android デバイス 1 台につき 1 人のユーザーをサポートするように設計されていますが、
複数ユーザーに対応することもできます
同じ Android デバイスで同時に接続することもできます。
このレッスンでは、単一のコードで入力を処理する基本的な手法について説明します。
接続されている複数のコントローラからデバイス上のマルチプレーヤー ゲーム ゲームを検出します。例
プレーヤーのアバターと各コントローラ デバイス間のマッピングを維持します。
適切に処理する必要があります。
プレーヤーをコントローラ デバイス ID にマッピングする
ゲーム コントローラを Android デバイスに接続すると、
整数のデバイス ID が割り当てられます。接続されているデバイスのデバイス ID は、
ゲーム コントローラが接続されていることを確認するで説明するように、InputDevice.getDeviceIds()
を呼び出してゲーム コントローラに接続します。各キャンペーンに
デバイス ID をゲーム内のプレーヤーと関連付けて、各プレーヤーのゲーム アクションを個別に処理します。
注: Android 4.1(API)を搭載するデバイスの場合
レベル 16)以降の場合は、
getDescriptor()
は一意のキーを返します。
入力デバイスの永続的な文字列値。記述子は、デバイス ID とは異なり、
入力デバイスが接続解除、再接続、または接続されても、
再構成されます。
以下のコード スニペットは、SparseArray
の使用方法を示しています。
プレーヤーのアバターを特定のコントローラに関連付けます。この例では、
mShips
変数には、Ship
オブジェクトのコレクションが格納されます。新しい
ユーザーが新しいコントローラをアタッチしたときに、ゲーム内でプレーヤーのアバターが作成される。
関連するコントローラが削除されると削除されます。
onInputDeviceAdded()
と onInputDeviceRemoved()
のコールバック
抽象化レイヤの一部であり、
<ph type="x-smartling-placeholder"></ph>
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 に対応する 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);
}
注: Google Chat の設定で
ゲーム コントローラの接続が切断された場合は、ゲームを一時停止して、
再接続しようとしています。
このページのコンテンツやコードサンプルは、コンテンツ ライセンスに記載のライセンスに従います。Java および OpenJDK は Oracle および関連会社の商標または登録商標です。
最終更新日 2025-07-26 UTC。
[[["わかりやすい","easyToUnderstand","thumb-up"],["問題の解決に役立った","solvedMyProblem","thumb-up"],["その他","otherUp","thumb-up"]],[["必要な情報がない","missingTheInformationINeed","thumb-down"],["複雑すぎる / 手順が多すぎる","tooComplicatedTooManySteps","thumb-down"],["最新ではない","outOfDate","thumb-down"],["翻訳に関する問題","translationIssue","thumb-down"],["サンプル / コードに問題がある","samplesCodeIssue","thumb-down"],["その他","otherDown","thumb-down"]],["最終更新日 2025-07-26 UTC。"],[],[],null,["# Support multiple game controllers\n\nWhile most games are designed to support a single user per Android device,\nit's also possible to support multiple users with game controllers that are\nconnected simultaneously on the same Android device.\n\nThis lesson covers some basic techniques for handling input in your single\ndevice multiplayer game from multiple connected controllers. This includes\nmaintaining a mapping between player avatars and each controller device and\nprocessing controller input events appropriately.\n\nMap players to controller device IDs\n------------------------------------\n\nWhen a game controller is connected to an Android device, the system\nassigns it an integer device ID. You can obtain the device IDs for connected\ngame controllers by calling [InputDevice.getDeviceIds()](/reference/android/view/InputDevice#getDeviceIds()), as shown in [Verify a Game Controller is Connected](/develop/ui/views/touch-and-input/game-controllers/controller-input#input). You can then associate each\ndevice ID with a player in your game, and process game actions for each player separately.\n\n**Note:** On devices running Android 4.1 (API\nlevel 16) and higher, you can obtain an input device's descriptor using\n[getDescriptor()](/reference/android/view/InputDevice#getDescriptor()), which returns a unique\npersistent string value for the input device. Unlike a device ID, the descriptor\nvalue won't change even if the input device is disconnected, reconnected, or\nreconfigured.\n\nThe code snippet below shows how to use a [SparseArray](/reference/android/util/SparseArray)\nto associate a player's avatar with a specific controller. In this example, the\n`mShips` variable stores a collection of `Ship` objects. A new\nplayer avatar is created in-game when a new controller is attached by a user,\nand removed when its associated controller is removed.\n\nThe `onInputDeviceAdded()` and `onInputDeviceRemoved()` callback\nmethods are part of the abstraction layer introduced in\n[Supporting Controllers Across Android Versions](/training/game-controllers/compatibility#status_callbacks}). By implementing these\nlistener callbacks, your game can identify the game controller's device ID when a\ncontroller is added or removed. This detection is compatible with Android 2.3\n(API level 9) and higher. \n\n### Kotlin\n\n```kotlin\nprivate val ships = SparseArray\u003cShip\u003e()\n\noverride fun onInputDeviceAdded(deviceId: Int) {\n getShipForID(deviceId)\n}\n\noverride fun onInputDeviceRemoved(deviceId: Int) {\n removeShipForID(deviceId)\n}\n\nprivate fun getShipForID(shipID: Int): Ship {\n return ships.get(shipID) ?: Ship().also {\n ships.append(shipID, it)\n }\n}\n\nprivate fun removeShipForID(shipID: Int) {\n ships.remove(shipID)\n}\n```\n\n### Java\n\n```java\nprivate final SparseArray\u003cShip\u003e ships = new SparseArray\u003cShip\u003e();\n\n@Override\npublic void onInputDeviceAdded(int deviceId) {\n getShipForID(deviceId);\n}\n\n@Override\npublic void onInputDeviceRemoved(int deviceId) {\n removeShipForID(deviceId);\n}\n\nprivate Ship getShipForID(int shipID) {\n Ship currentShip = ships.get(shipID);\n if ( null == currentShip ) {\n currentShip = new Ship();\n ships.append(shipID, currentShip);\n }\n return currentShip;\n}\n\nprivate void removeShipForID(int shipID) {\n ships.remove(shipID);\n}\n```\n\nProcess multiple controller input\n---------------------------------\n\nYour game should execute the following loop to process\ninput from multiple controllers:\n\n1. Detect whether an input event occurred.\n2. Identify the input source and its device ID.\n3. Based on the action indicated by the input event key code or axis value, update the player avatar associated with that device ID.\n4. Render and update the user interface.\n\n[KeyEvent](/reference/android/view/KeyEvent) and [MotionEvent](/reference/android/view/MotionEvent) input\nevents have device IDs associated with them. Your game can take advantage of\nthis to determine which controller the input event came from, and update the\nplayer avatar associated with that controller.\n\nThe following code snippet shows how you might get a player avatar reference\ncorresponding to a game controller device ID, and update the game based on the\nuser's button press on that controller. \n\n### Kotlin\n\n```kotlin\noverride fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {\n if (event.source and InputDevice.SOURCE_GAMEPAD == InputDevice.SOURCE_GAMEPAD) {\n event.deviceId.takeIf { it != -1 }?.also { deviceId -\u003e\n val currentShip: Ship = getShipForID(deviceId)\n // Based on which key was pressed, update the player avatar\n // (e.g. set the ship headings or fire lasers)\n return true\n }\n }\n return super.onKeyDown(keyCode, event)\n}\n```\n\n### Java\n\n```java\n@Override\npublic boolean onKeyDown(int keyCode, KeyEvent event) {\n if ((event.getSource() & InputDevice.SOURCE_GAMEPAD)\n == InputDevice.SOURCE_GAMEPAD) {\n int deviceId = event.getDeviceId();\n if (deviceId != -1) {\n Ship currentShip = getShipForId(deviceId);\n // Based on which key was pressed, update the player avatar\n // (e.g. set the ship headings or fire lasers)\n ...\n return true;\n }\n }\n return super.onKeyDown(keyCode, event);\n}\n```\n\n**Note:**As a best practice, when a user's\ngame controller disconnects, you should pause the game and ask if the user\nwants to reconnect."]]