대부분의 게임은 Android 기기당 단일 사용자를 지원하도록 설계되었지만, 동일한 Android 기기에 동시에 연결된 게임 컨트롤러를 사용하여 여러 사용자를 지원할 수도 있습니다.
이 과정에서는 연결된 여러 컨트롤러에서 단일 기기 멀티플레이어 게임의 입력을 처리하기 위한 몇 가지 기본 기법을 다룹니다. 여기에는 플레이어 아바타와 각 컨트롤러 기기 간의 매핑을 유지하고 컨트롤러 입력 이벤트를 적절하게 처리하는 작업이 포함됩니다.
플레이어를 컨트롤러 기기 ID에 매핑
게임 컨트롤러가 Android 기기에 연결되면 시스템은 정수로 된 기기 ID를 할당합니다. 게임 컨트롤러가 연결되어 있는지 확인에서와 같이 InputDevice.getDeviceIds()
를 호출하여 연결된 게임 컨트롤러의 기기 ID를 가져올 수 있습니다. 그런 다음 각 기기 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); }
참고: 사용자의 게임 컨트롤러가 연결 해제되면 게임을 일시중지하고 사용자에게 다시 연결할지 묻는 것이 좋습니다.