Si bien la mayoría de los juegos están diseñados para admitir un solo usuario por dispositivo Android, También puedes admitir múltiples usuarios con controles de juegos conectadas simultáneamente en el mismo dispositivo Android.
Esta lección abarca algunas técnicas básicas para manejar la entrada en tu juego multijugador en dispositivos desde varios controles conectados. Esto incluye mantener una asignación entre los avatares de los jugadores y cada dispositivo controlador y los eventos de entrada del controlador de forma adecuada.
Cómo asignar jugadores a los ID de dispositivos controladores
Cuando se conecta un control de juegos a un dispositivo Android, el sistema
le asigna un ID de dispositivo de número entero. Puedes obtener los IDs de dispositivos conectados
controles de juegos llamando a InputDevice.getDeviceIds()
, como se muestra en Cómo verificar si un control de juegos está conectado. Luego, puedes asociar cada
ID de dispositivo con un jugador en tu juego y procesar las acciones del juego para cada jugador por separado.
Nota: En dispositivos con Android 4.1 (API
nivel 16) y versiones posteriores, podrás obtener el descriptor de un dispositivo de entrada usando
getDescriptor()
, que muestra un único
de cadena persistente para el dispositivo de entrada. A diferencia de un ID de dispositivo, el descriptor
valor no cambiará incluso si el dispositivo de entrada se desconecta, se vuelve a conectar o
no se deben volver a configurar.
En el siguiente fragmento de código, se muestra cómo usar un SparseArray
para asociar el avatar de un jugador con un controlador específico. En este ejemplo,
La variable mShips
almacena una colección de objetos Ship
. Un nuevo
el avatar del jugador se crea en el juego cuando un usuario conecta un nuevo controlador.
y se quita cuando se quita el controlador asociado.
Devolución de llamada onInputDeviceAdded()
y onInputDeviceRemoved()
son parte de la capa de abstracción presentada en
Compatibilidad con controladores en diferentes versiones de Android. Si implementas estas
de objetos de escucha, tu juego puede identificar el ID de dispositivo del controlador para juegos cuando un
agregar o quitar un controlador. Esta detección es compatible con Android 2.3
(nivel de API 9) y versiones posteriores.
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); }
Cómo procesar la entrada de varios controladores
Tu juego debería ejecutar el siguiente bucle para procesar entrada de múltiples controladores:
- Detecta si hubo un evento de entrada.
- Identifica la fuente de entrada y su ID de dispositivo.
- Según la acción indicada por el valor del eje o el código de tecla del evento de entrada, actualiza el avatar del jugador asociado con ese ID de dispositivo.
- Procesa y actualiza la interfaz de usuario.
Entrada de KeyEvent
y MotionEvent
los eventos tienen IDs de dispositivo asociados. Tu juego puede aprovechar
esto para determinar de qué controlador provino el evento de entrada y actualizar el
el avatar del jugador asociado con ese controlador.
En el siguiente fragmento de código, se muestra cómo podrías obtener una referencia del avatar de un jugador. correspondiente al ID de dispositivo del control de juegos y actualizar el juego según el presionar el botón del usuario en ese control.
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); }
Nota: Como práctica recomendada, cuando la ventana de usuario el control de juegos se desconecta, debes pausar el juego y preguntar quiere volver a conectarse.