대부분의 게임은 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) }
자바
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) }
자바
@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); }
참고: 사용자의 게임 컨트롤러 연결이 끊기면 게임을 일시중지하고 사용자에게 다시 연결할지 묻는 것이 좋습니다.