No nível do sistema, o Android informa códigos de evento de entrada dos controles de jogos. como códigos de tecla e valores de eixo do Android. É possível receber esses códigos no jogo e valores e os convertem em ações específicas no jogo.
Quando os jogadores se conectam fisicamente ou pareiam sem fio um controle de jogo para
os dispositivos Android, o sistema detecta automaticamente o controlador
como um dispositivo de entrada e começa a relatar os eventos de entrada. Seu jogo pode receber
esses eventos de entrada implementando os seguintes métodos de callback no seu ativo
Activity
ou View
em foco (você deve
implementar os callbacks para a Activity
ou
View
, mas não ambos):
- De
Activity
:dispatchGenericMotionEvent(android.view. MotionEvent)
Chamado para processar eventos de movimento genéricos, por exemplo, movimentos do joystick.
dispatchKeyEvent(android.view.KeyEvent)
Chamado para processar eventos importantes, como a imprensa ou um lançamento de uma botão gamepad ou botão direcional.
- De
View
:onGenericMotionEvent(android.view.MotionEvent)
Chamado para processar eventos de movimento genéricos, por exemplo, movimentos do joystick.
onKeyDown(int, android.view.KeyEvent)
Chamado para processar o pressionamento de uma tecla física, como um gamepad ou Botão direcional.
onKeyUp(int, android.view.KeyEvent)
Chamado para processar a liberação de uma tecla física, como um gamepad ou Botão direcional.
A abordagem recomendada é capturar os eventos do
objeto View
específico com que o usuário interage.
Inspecione os seguintes objetos fornecidos pelos callbacks para conseguir informações
sobre o tipo de evento de entrada recebido:
KeyEvent
- Um objeto que descreve direcional
eventos de botão direcional e gamepad. Os eventos principais são acompanhados por um
key code que indica o botão específico acionado, como
DPAD_DOWN
ouBUTTON_A
. Você pode obter o o código da tecla chamandogetKeyCode()
ou usando a callbacks de eventos, comoonKeyDown()
. MotionEvent
- Um objeto que descreve entradas do joystick e do gatilho lateral
movimentos. Os eventos de movimento são acompanhados por um código de ação e um conjunto de
valores de eixo. O código de ação especifica a mudança de estado que ocorreu
como um joystick sendo movido. Os valores do eixo descrevem a posição e outros
propriedades de movimento para um controle físico específico, como
AXIS_X
ouAXIS_RTRIGGER
. Você pode conferir o código de ação chamandogetAction()
e o valor do eixo chamandogetAxisValue()
.
Esta lição se concentra em como você pode lidar com entradas dos tipos mais comuns de
controles físicos (botões do gamepad, botões direcionais e
joysticks) em uma tela de jogo implementando o mencionado acima
View
métodos de callback e processamento
objetos KeyEvent
e MotionEvent
.
Verificar se um controle de jogo está conectado
Ao informar eventos de entrada, o Android não distingue
entre os eventos originados em um dispositivo de controle que não seja de jogo e os eventos que vieram
em um controle de jogo. Por exemplo, uma ação de tela touch gera uma
evento AXIS_X
que representa o X
coordenada da superfície sensível ao toque, mas o joystick gera uma
Evento AXIS_X
que representa a posição X do joystick. Se
seu jogo se preocupa em lidar com entradas do controlador, primeiro verifique
se o evento de entrada vem de um tipo de origem relevante.
Para verificar se um dispositivo de entrada conectado é um controle de jogo, chame
getSources()
para obter um campo de bits combinado de
tipos de origem de entrada compatíveis com esse dispositivo. Em seguida, é possível testar
os seguintes campos serão definidos:
- Um tipo de origem
SOURCE_GAMEPAD
indica se o dispositivo de entrada tem botões de gamepad (por exemplo,BUTTON_A
). Observe que esta fonte não indica estritamente se o controle de jogo tem botões D-pad, embora a maioria dos gamepads tenha controles direcionais. - Um tipo de origem
SOURCE_DPAD
indica que o dispositivo de entrada tem botões D-pad (por exemplo,DPAD_UP
). - Um tipo de origem de
SOURCE_JOYSTICK
indica que o dispositivo de entrada tem controles analógicos (por exemplo, um joystick que registra movimentos ao longo deAXIS_X
eAXIS_Y
).
O snippet de código a seguir mostra um método auxiliar que permite verificar se os dispositivos de entrada conectados são controles de jogo. Nesse caso, o método recupera os IDs de dispositivos para os controles de jogos. É possível associar cada dispositivo ID com um jogador no seu jogo e processar as ações do jogo para cada um dos usuários conectados de vídeo separadamente. Para saber mais sobre como oferecer suporte a vários controles de jogos conectados simultaneamente no mesmo dispositivo Android, consulte Ofereça suporte a vários controles de jogos.
Kotlin
fun getGameControllerIds(): List<Int> { val gameControllerDeviceIds = mutableListOf<Int>() val deviceIds = InputDevice.getDeviceIds() deviceIds.forEach { deviceId -> InputDevice.getDevice(deviceId).apply { // Verify that the device has gamepad buttons, control sticks, or both. if (sources and InputDevice.SOURCE_GAMEPAD == InputDevice.SOURCE_GAMEPAD || sources and InputDevice.SOURCE_JOYSTICK == InputDevice.SOURCE_JOYSTICK) { // This device is a game controller. Store its device ID. gameControllerDeviceIds .takeIf { !it.contains(deviceId) } ?.add(deviceId) } } } return gameControllerDeviceIds }
Java
public ArrayList<Integer> getGameControllerIds() { ArrayList<Integer> gameControllerDeviceIds = new ArrayList<Integer>(); int[] deviceIds = InputDevice.getDeviceIds(); for (int deviceId : deviceIds) { InputDevice dev = InputDevice.getDevice(deviceId); int sources = dev.getSources(); // Verify that the device has gamepad buttons, control sticks, or both. if (((sources & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD) || ((sources & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK)) { // This device is a game controller. Store its device ID. if (!gameControllerDeviceIds.contains(deviceId)) { gameControllerDeviceIds.add(deviceId); } } } return gameControllerDeviceIds; }
Além disso, verifique os recursos de entrada individuais compatível com um controle de jogo conectado. Isso pode ser útil, por exemplo, se você quer que o jogo use somente entradas do conjunto de controles físicos entende.
Para detectar se um código de tecla ou código de eixo específico é suportado por um use estas técnicas:
- No Android 4.4 (API de nível 19) ou versões mais recentes, é possível determinar se um código
compatível com um controle de jogo conectado chamando
hasKeys(int...)
: - No Android 3.1 (nível 12 da API) ou versões mais recentes, todos os eixos disponíveis
compatível com um controle de jogo conectado, chamando
getMotionRanges()
: Depois, em cada ObjetoInputDevice.MotionRange
retornado. ChamegetAxis()
para receber o ID do eixo.
Processar o pressionamento do botão do gamepad
A figura 1 mostra como o Android mapeia os códigos de tecla e os valores dos eixos para controles na maioria dos controles de jogos.
![](https://developer.android.com/static/images/training/game-controller-profiles.png?authuser=0000&hl=pt)
Figura 1. Perfil de um controle de jogo genérico.
As frases de destaque na figura referem-se ao seguinte:
Códigos de tecla comuns gerados ao pressionar botões do gamepad incluem:
BUTTON_A
,
BUTTON_B
,
BUTTON_SELECT
,
e BUTTON_START
. Algum jogo
Eles também acionam o código de tecla DPAD_CENTER
quando o centro da barra transversal do botão direcional é pressionado. Seu
jogo pode inspecionar o código de tecla chamando getKeyCode()
ou de callbacks de eventos principais, como
onKeyDown()
,
e, se representar um evento que seja relevante para seu jogo, processe-o como um
uma ação do jogo. A Tabela 1 lista as ações de jogo recomendadas para os casos mais comuns.
botões do gamepad.
Tabela 1. Ações de jogo recomendadas para gamepad botões.
Ação do jogo | Código da tecla do botão |
---|---|
Iniciar jogo no menu principal ou pausar/retomar durante o jogo | BUTTON_START * |
Menu de exibição | BUTTON_SELECT *
e KEYCODE_MENU * |
Igual ao comportamento de navegação Voltar do Android descrito nos Design de navegação guia. | KEYCODE_BACK |
Voltar para um item anterior em um menu | BUTTON_B |
Confirmar a seleção ou executar a ação principal do jogo | BUTTON_A e
DPAD_CENTER |
* Seu jogo não pode depender da presença das opções "Iniciar", "Selecionar" ou "Menu" .
Dica : considere mostrar uma tela de configuração no jogo para permitir que os usuários personalizem os próprios mapeamentos de controles de jogo para ações do jogo.
O snippet a seguir mostra como modificar
onKeyDown()
a
associar BUTTON_A
e
Pressionar o botão DPAD_CENTER
com uma ação de jogo.
Kotlin
class GameView(...) : View(...) { ... override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean { var handled = false if (event.source and InputDevice.SOURCE_GAMEPAD == InputDevice.SOURCE_GAMEPAD) { if (event.repeatCount == 0) { when (keyCode) { // Handle gamepad and D-pad button presses to navigate the ship ... else -> { keyCode.takeIf { isFireKey(it) }?.run { // Update the ship object to fire lasers ... handled = true } } } } if (handled) { return true } } return super.onKeyDown(keyCode, event) } // Here we treat Button_A and DPAD_CENTER as the primary action // keys for the game. private fun isFireKey(keyCode: Int): Boolean = keyCode == KeyEvent.KEYCODE_DPAD_CENTER || keyCode == KeyEvent.KEYCODE_BUTTON_A }
Java
public class GameView extends View { ... @Override public boolean onKeyDown(int keyCode, KeyEvent event) { boolean handled = false; if ((event.getSource() & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD) { if (event.getRepeatCount() == 0) { switch (keyCode) { // Handle gamepad and D-pad button presses to // navigate the ship ... default: if (isFireKey(keyCode)) { // Update the ship object to fire lasers ... handled = true; } break; } } if (handled) { return true; } } return super.onKeyDown(keyCode, event); } private static boolean isFireKey(int keyCode) { // Here we treat Button_A and DPAD_CENTER as the primary action // keys for the game. return keyCode == KeyEvent.KEYCODE_DPAD_CENTER || keyCode == KeyEvent.KEYCODE_BUTTON_A; } }
Observação: no Android 4.2 (API
de nível 17) e inferiores, o sistema trata
BUTTON_A
como o Android
Tecla Voltar por padrão. Caso seu app seja compatível com os seguintes sistemas
versões, trate
BUTTON_A
como jogo principal
à ação. Para determinar o SDK do Android atual
versão no dispositivo, consulte o
Valor de Build.VERSION.SDK_INT
.
Processar entradas pelo botão direcional
O botão direcional de quatro direções é um controle físico comum em muitos jogos
e controladores. O Android informa que o botão direcional para cima e para baixo pressiona como
AXIS_HAT_Y
eventos com um intervalo
de -1,0 (para cima) a 1,0 (para baixo), e o botão direcional ESQUERDO ou DIREITO pressiona como
AXIS_HAT_X
eventos com intervalo de -1,0
(esquerda) até 1.0 (direita).
Alguns controles informam o pressionamento do botão direcional com um código de tecla. Se o jogo se preocupa com o pressionamento do botão direcional, trate os eventos do eixo do chapéu e o botão direcional códigos de teclas como os mesmos eventos de entrada, conforme recomendado na Tabela 2.
Tabela 2. Ações de jogo padrão recomendadas para o botão direcional e os valores do eixo do chapéu.
Ação do jogo | Código do botão direcional | Código do botão do ângulo de visão |
---|---|---|
Mover para cima | KEYCODE_DPAD_UP |
AXIS_HAT_Y (para valores de 0 a -1,0) |
Mover para baixo | KEYCODE_DPAD_DOWN |
AXIS_HAT_Y (para valores de 0 a 1,0) |
Mover para a esquerda | KEYCODE_DPAD_LEFT |
AXIS_HAT_X (para valores de 0 a -1,0) |
Mover para a direita | KEYCODE_DPAD_RIGHT |
AXIS_HAT_X (para valores de 0 a 1,0) |
O snippet de código a seguir mostra uma classe auxiliar que permite verificar o chapéu eixo e valores de código de tecla de um evento de entrada para determinar a direção do botão direcional.
Kotlin
class Dpad { private var directionPressed = -1 // initialized to -1 fun getDirectionPressed(event: InputEvent): Int { if (!isDpadDevice(event)) { return -1 } // If the input event is a MotionEvent, check its hat axis values. (event as? MotionEvent)?.apply { // Use the hat axis value to find the D-pad direction val xaxis: Float = event.getAxisValue(MotionEvent.AXIS_HAT_X) val yaxis: Float = event.getAxisValue(MotionEvent.AXIS_HAT_Y) directionPressed = when { // Check if the AXIS_HAT_X value is -1 or 1, and set the D-pad // LEFT and RIGHT direction accordingly. xaxis.compareTo(-1.0f) == 0 -> Dpad.LEFT xaxis.compareTo(1.0f) == 0 -> Dpad.RIGHT // Check if the AXIS_HAT_Y value is -1 or 1, and set the D-pad // UP and DOWN direction accordingly. yaxis.compareTo(-1.0f) == 0 -> Dpad.UP yaxis.compareTo(1.0f) == 0 -> Dpad.DOWN else -> directionPressed } } // If the input event is a KeyEvent, check its key code. (event as? KeyEvent)?.apply { // Use the key code to find the D-pad direction. directionPressed = when(event.keyCode) { KeyEvent.KEYCODE_DPAD_LEFT -> Dpad.LEFT KeyEvent.KEYCODE_DPAD_RIGHT -> Dpad.RIGHT KeyEvent.KEYCODE_DPAD_UP -> Dpad.UP KeyEvent.KEYCODE_DPAD_DOWN -> Dpad.DOWN KeyEvent.KEYCODE_DPAD_CENTER -> Dpad.CENTER else -> directionPressed } } return directionPressed } companion object { internal const val UP = 0 internal const val LEFT = 1 internal const val RIGHT = 2 internal const val DOWN = 3 internal const val CENTER = 4 fun isDpadDevice(event: InputEvent): Boolean = // Check that input comes from a device with directional pads. event.source and InputDevice.SOURCE_DPAD != InputDevice.SOURCE_DPAD } }
Java
public class Dpad { final static int UP = 0; final static int LEFT = 1; final static int RIGHT = 2; final static int DOWN = 3; final static int CENTER = 4; int directionPressed = -1; // initialized to -1 public int getDirectionPressed(InputEvent event) { if (!isDpadDevice(event)) { return -1; } // If the input event is a MotionEvent, check its hat axis values. if (event instanceof MotionEvent) { // Use the hat axis value to find the D-pad direction MotionEvent motionEvent = (MotionEvent) event; float xaxis = motionEvent.getAxisValue(MotionEvent.AXIS_HAT_X); float yaxis = motionEvent.getAxisValue(MotionEvent.AXIS_HAT_Y); // Check if the AXIS_HAT_X value is -1 or 1, and set the D-pad // LEFT and RIGHT direction accordingly. if (Float.compare(xaxis, -1.0f) == 0) { directionPressed = Dpad.LEFT; } else if (Float.compare(xaxis, 1.0f) == 0) { directionPressed = Dpad.RIGHT; } // Check if the AXIS_HAT_Y value is -1 or 1, and set the D-pad // UP and DOWN direction accordingly. else if (Float.compare(yaxis, -1.0f) == 0) { directionPressed = Dpad.UP; } else if (Float.compare(yaxis, 1.0f) == 0) { directionPressed = Dpad.DOWN; } } // If the input event is a KeyEvent, check its key code. else if (event instanceof KeyEvent) { // Use the key code to find the D-pad direction. KeyEvent keyEvent = (KeyEvent) event; if (keyEvent.getKeyCode() == KeyEvent.KEYCODE_DPAD_LEFT) { directionPressed = Dpad.LEFT; } else if (keyEvent.getKeyCode() == KeyEvent.KEYCODE_DPAD_RIGHT) { directionPressed = Dpad.RIGHT; } else if (keyEvent.getKeyCode() == KeyEvent.KEYCODE_DPAD_UP) { directionPressed = Dpad.UP; } else if (keyEvent.getKeyCode() == KeyEvent.KEYCODE_DPAD_DOWN) { directionPressed = Dpad.DOWN; } else if (keyEvent.getKeyCode() == KeyEvent.KEYCODE_DPAD_CENTER) { directionPressed = Dpad.CENTER; } } return directionPressed; } public static boolean isDpadDevice(InputEvent event) { // Check that input comes from a device with directional pads. if ((event.getSource() & InputDevice.SOURCE_DPAD) != InputDevice.SOURCE_DPAD) { return true; } else { return false; } } }
Use essa classe auxiliar no jogo sempre que quiser processar
usando o botão direcional (por exemplo, no
onGenericMotionEvent()
ou
onKeyDown()
).
Exemplo:
Kotlin
private val dpad = Dpad() ... override fun onGenericMotionEvent(event: MotionEvent): Boolean { if (Dpad.isDpadDevice(event)) { when (dpad.getDirectionPressed(event)) { Dpad.LEFT -> { // Do something for LEFT direction press ... return true } Dpad.RIGHT -> { // Do something for RIGHT direction press ... return true } Dpad.UP -> { // Do something for UP direction press ... return true } ... } } // Check if this event is from a joystick movement and process accordingly. ... }
Java
Dpad dpad = new Dpad(); ... @Override public boolean onGenericMotionEvent(MotionEvent event) { // Check if this event if from a D-pad and process accordingly. if (Dpad.isDpadDevice(event)) { int press = dpad.getDirectionPressed(event); switch (press) { case LEFT: // Do something for LEFT direction press ... return true; case RIGHT: // Do something for RIGHT direction press ... return true; case UP: // Do something for UP direction press ... return true; ... } } // Check if this event is from a joystick movement and process accordingly. ... }
Processar movimentos do joystick
Quando os jogadores movem um joystick nos controles, o Android relata um
MotionEvent
que contém o
O código de ação ACTION_MOVE
e a versão atualizada
posições dos eixos do joystick. Seu jogo pode usar os dados fornecidos pelo
o MotionEvent
para determinar se um movimento do joystick
se importa com o que aconteceu.
Observe que os eventos de movimento do joystick podem agrupar várias amostras de movimento.
em um único objeto. O objeto MotionEvent
contém
a posição atual de cada eixo de joystick, bem como vários valores históricos
para cada eixo. Ao relatar eventos de movimento com o código de ação ACTION_MOVE
(como movimentos do joystick), o Android agrupa o
valores de eixo para eficiência. Os valores históricos de um eixo consistem nos
conjunto de valores distintos mais antigos que o valor do eixo atual e mais recentes
informados em eventos de movimento anteriores. Consulte a
Referência de MotionEvent
para mais detalhes.
Use as informações históricas para renderizar um jogo com mais precisão
movimento do objeto com base na entrada do joystick. Para
recuperar os valores atuais e históricos, chamar
getAxisValue()
ou getHistoricalAxisValue()
. Também é possível encontrar o número de impressões históricas
no evento de joystick, chamando
getHistorySize()
:
O snippet a seguir mostra como modificar
Callback onGenericMotionEvent()
para processar a entrada do joystick. Primeiro, você deve
processar os valores históricos de um eixo e, em seguida, processar sua posição atual.
Kotlin
class GameView(...) : View(...) { override fun onGenericMotionEvent(event: MotionEvent): Boolean { // Check that the event came from a game controller return if (event.source and InputDevice.SOURCE_JOYSTICK == InputDevice.SOURCE_JOYSTICK && event.action == MotionEvent.ACTION_MOVE) { // Process the movements starting from the // earliest historical position in the batch (0 until event.historySize).forEach { i -> // Process the event at historical position i processJoystickInput(event, i) } // Process the current movement sample in the batch (position -1) processJoystickInput(event, -1) true } else { super.onGenericMotionEvent(event) } } }
Java
public class GameView extends View { @Override public boolean onGenericMotionEvent(MotionEvent event) { // Check that the event came from a game controller if ((event.getSource() & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK && event.getAction() == MotionEvent.ACTION_MOVE) { // Process all historical movement samples in the batch final int historySize = event.getHistorySize(); // Process the movements starting from the // earliest historical position in the batch for (int i = 0; i < historySize; i++) { // Process the event at historical position i processJoystickInput(event, i); } // Process the current movement sample in the batch (position -1) processJoystickInput(event, -1); return true; } return super.onGenericMotionEvent(event); } }
Antes de usar a entrada do joystick, é necessário determinar se ele está ao centro e calcular os movimentos do eixo de maneira correspondente. Normalmente, os joysticks ter uma área plana, ou seja, um intervalo de valores próximo à coordenada (0,0) no qual o eixo é considerado centralizado. Se o valor do eixo relatado por O Android está dentro da área plana, você deve tratar o controle como em repouso, ou seja, imóvel ao longo dos dois eixos.
O snippet abaixo mostra um método auxiliar que calcula o movimento junto com
cada eixo. Você invoca esse auxiliar no método processJoystickInput()
descritos abaixo.
Kotlin
private fun getCenteredAxis( event: MotionEvent, device: InputDevice, axis: Int, historyPos: Int ): Float { val range: InputDevice.MotionRange? = device.getMotionRange(axis, event.source) // A joystick at rest does not always report an absolute position of // (0,0). Use the getFlat() method to determine the range of values // bounding the joystick axis center. range?.apply { val value: Float = if (historyPos < 0) { event.getAxisValue(axis) } else { event.getHistoricalAxisValue(axis, historyPos) } // Ignore axis values that are within the 'flat' region of the // joystick axis center. if (Math.abs(value) > flat) { return value } } return 0f }
Java
private static float getCenteredAxis(MotionEvent event, InputDevice device, int axis, int historyPos) { final InputDevice.MotionRange range = device.getMotionRange(axis, event.getSource()); // A joystick at rest does not always report an absolute position of // (0,0). Use the getFlat() method to determine the range of values // bounding the joystick axis center. if (range != null) { final float flat = range.getFlat(); final float value = historyPos < 0 ? event.getAxisValue(axis): event.getHistoricalAxisValue(axis, historyPos); // Ignore axis values that are within the 'flat' region of the // joystick axis center. if (Math.abs(value) > flat) { return value; } } return 0; }
Juntando tudo, veja como você pode processar os movimentos do joystick seu jogo:
Kotlin
private fun processJoystickInput(event: MotionEvent, historyPos: Int) { val inputDevice = event.device // Calculate the horizontal distance to move by // using the input value from one of these physical controls: // the left control stick, hat axis, or the right control stick. var x: Float = getCenteredAxis(event, inputDevice, MotionEvent.AXIS_X, historyPos) if (x == 0f) { x = getCenteredAxis(event, inputDevice, MotionEvent.AXIS_HAT_X, historyPos) } if (x == 0f) { x = getCenteredAxis(event, inputDevice, MotionEvent.AXIS_Z, historyPos) } // Calculate the vertical distance to move by // using the input value from one of these physical controls: // the left control stick, hat switch, or the right control stick. var y: Float = getCenteredAxis(event, inputDevice, MotionEvent.AXIS_Y, historyPos) if (y == 0f) { y = getCenteredAxis(event, inputDevice, MotionEvent.AXIS_HAT_Y, historyPos) } if (y == 0f) { y = getCenteredAxis(event, inputDevice, MotionEvent.AXIS_RZ, historyPos) } // Update the ship object based on the new x and y values }
Java
private void processJoystickInput(MotionEvent event, int historyPos) { InputDevice inputDevice = event.getDevice(); // Calculate the horizontal distance to move by // using the input value from one of these physical controls: // the left control stick, hat axis, or the right control stick. float x = getCenteredAxis(event, inputDevice, MotionEvent.AXIS_X, historyPos); if (x == 0) { x = getCenteredAxis(event, inputDevice, MotionEvent.AXIS_HAT_X, historyPos); } if (x == 0) { x = getCenteredAxis(event, inputDevice, MotionEvent.AXIS_Z, historyPos); } // Calculate the vertical distance to move by // using the input value from one of these physical controls: // the left control stick, hat switch, or the right control stick. float y = getCenteredAxis(event, inputDevice, MotionEvent.AXIS_Y, historyPos); if (y == 0) { y = getCenteredAxis(event, inputDevice, MotionEvent.AXIS_HAT_Y, historyPos); } if (y == 0) { y = getCenteredAxis(event, inputDevice, MotionEvent.AXIS_RZ, historyPos); } // Update the ship object based on the new x and y values }
Para oferecer suporte a controles de jogos mais sofisticados recursos além de um único joystick, siga estas práticas recomendadas:
- Gerencie dois controles direcionais analógicos. Muitos controles de jogo têm
um joystick esquerdo e direito. Para o direcional analógico esquerdo, o Android
Informa movimentos horizontais como eventos
AXIS_X
e movimentos verticais como eventosAXIS_Y
. Para o direcional analógico direito, o Android relata movimentos horizontais comoAXIS_Z
eventos e movimentos verticais comoAXIS_RZ
. Certifique-se de lidar que os dois controles se fixam no seu código. - Lidar com o pressionamento dos gatilhos superiores (mas fornecer entradas alternativas)
métodos). Alguns controles têm os ombros esquerdo e direito
gatilhos. Se esses gatilhos estiverem presentes, o Android vai informar que um pressionamento do gatilho esquerdo
como um evento
AXIS_LTRIGGER
, pressionar o gatilho direito comoAXIS_RTRIGGER
. No Android 4.3 (API de nível 18), um controlador que produzAXIS_LTRIGGER
também informa um um valor idêntico para o eixoAXIS_BRAKE
. A o mesmo vale paraAXIS_RTRIGGER
eAXIS_GAS
. O Android informa todos os acionadores analógicos pressiona com um valor normalizado de 0,0 (liberado) a 1,0 (totalmente pressionado). Não todos os controles têm gatilhos, então considere permitir que os jogadores façam isso ações do jogo com outros botões.