複数のゲーム コントローラをサポートする

ほとんどのゲームは 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);
}

複数のコントローラからの入力を処理する

ゲームでは次のループを実行して、 複数のコントローラからの入力です。

  1. 入力イベントが発生したかどうかを検出します。
  2. 入力元とそのデバイス ID を特定します。
  3. 入力イベントのキーコードまたは軸の値で示されるアクションに基づいて、 そのデバイス ID に関連付けられているプレーヤーのアバターを更新します。
  4. ユーザー インターフェースをレンダリングして更新します。

KeyEventMotionEvent の入力 イベントにデバイス 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 の設定で ゲーム コントローラの接続が切断された場合は、ゲームを一時停止して、 再接続しようとしています。