O Google Play Games está na versão Beta aberta.

Primeiros passos com o SDK de entrada

Este tópico descreve como configurar e exibir a sobreposição do SDK de entrada em jogos com suporte ao Google Play Games. As tarefas, incluindo a adição do SDK ao jogo e a geração de um mapa de entrada, contêm a ação do jogo para as atribuições de entrada do usuário. Para jogos com suporte a mudanças de vinculação de teclas, você também precisa rastrear e sincronizar as mudanças com o SDK.

Antes de começar

Antes de adicionar o SDK de entrada ao jogo, adicione suporte para teclado e mouse.

Adicionar o SDK

O SDK de entrada ainda não está disponível para download. Ele vai estar disponível como uma dependência do Maven para projetos Java e Kotlin, além de um unitypackage e o tgz para desenvolvedores do Unity.

Lembre-se de mostrar interesse em estar entre os primeiros a acessar o novo SDK.

Gerar mapeamento de entrada

O mapeamento de entrada representa as ações do jogo nas atribuições de entrada do usuário a serem exibidas na sobreposição do SDK de entrada. Para gerar o mapeamento de entrada, é necessário criar um InputMap e, em seguida, retorná-lo com um InputMappingProvider.

Veja um exemplo de um InputMappingProvider:

Kotlin

class MyInputMapProvider : InputMappingProvider() {
    override fun onProvideInputMap(): InputMap {
        TODO("Not yet implemented")
    }
}

Java

public class MyInputMapProvider extends InputMappingProvider {
    @NonNull
    @Override
    public InputMap onProvideInputMap() {
        // TODO: return an InputMap
    }
}

C#

private class MyInputMappingProvider : InputMappingProvider
{
    public InputMap OnProvideInputMap()
    {
        // TODO("Not yet implemented")
    }
}

As próximas seções descrevem como criar um InputMap para ser retornado do InputMappingProvider.

Definir uma ação de entrada

A classe InputAction é usada para mapear uma tecla ou uma combinação de teclas para uma ação do jogo.

Este exemplo mapeia a tecla de espaço para a ação de pular:

Kotlin

val jumpInputAction = InputAction.create(
    "Jump",
    InputEventIds.JUMP.id,
    InputControls.create(
        listOf(KeyEvent.KEYCODE_SPACE),
        emptyList()
    )
)

Java

InputAction jumpInputAction = InputAction.create(
        "Jump",
        InputEventIds.JUMP.ordinal(),
        InputControls.create(
                Collections.singletonList(KeyEvent.KEYCODE_SPACE),
                Collections.emptyList()
        )
);

C#

var jumpInputAction = new InputAction
{
    ActionLabel = "Jump",
    UniqueId = (int)InputEventIds.Jump,
    InputControls = new InputControls
    {
        AndroidKeycodes = new[]
        {
            AndroidKeyCode.KEYCODE_SPACE
        }
    }
};

Captura de tela da sobreposição de entrada que indica que a ação de pular está vinculada à
tecla de espaço.

As ações também podem representar entradas de mouse. Este exemplo define o botão direito do mouse para a ação de mover:

Kotlin

val cmbMove = InputAction.create(
    "Move",
    InputEventIds.CMB_MOVE.id,
    InputControls.create(
        emptyList(),
        listOf(InputControls.MOUSE_RIGHT_CLICK)
    )
)

Java

InputAction cmbMove = InputAction.create(
        "Move",
        InputEventIds.CMB_MOVE.ordinal(),
        InputControls.create(
                Collections.emptyList(),
                Collections.singletonList(InputControls.MOUSE_RIGHT_CLICK)
        )
);

C#

var cmbMove = new InputAction
{
    ActionLabel = "Move",
    UniqueId = (int)InputEventIds.CmbMove,
    InputControls = new InputControls
    {
        MouseActions = new[]
        {
            MouseAction.MouseRightClick
        }
    }
};

Captura de tela da sobreposição de entrada em que a ação de mover está vinculada ao clique com o
botão direito do mouse.

As combinações de teclas são especificadas transmitindo vários códigos de teclas para a InputAction. Neste exemplo, Espaço + Shift é mapeado para a ação de correr, que funciona mesmo quando a tecla de espaço é mapeada para pular.

Kotlin

val cmbDash = InputAction.create(
    "Dash",
    InputEventIds.CMB_DASH.id,
    InputControls.create(
        listOf(KeyEvent.KEYCODE_SPACE, KeyEvent.KEYCODE_SHIFT_LEFT),
        emptyList()
    )
)

Java

InputAction cmbDash = InputAction.create(
        "Dash",
        InputEventIds.CMB_DASH.ordinal(),
        InputControls.create(
                Arrays.asList(KeyEvent.KEYCODE_SHIFT_LEFT, KeyEvent.KEYCODE_SPACE),
                Collections.emptyList()
        )
);

C#

var cmbDash = new InputAction
{
    ActionLabel = "Dash",
    UniqueId = (int)InputEventIds.CmbDash,
    InputControls = new InputControls
    {
        AndroidKeycodes = new[]
        {
            AndroidKeyCode.KEYCODE_SPACE, AndroidKeyCode.KEYCODE_SHIFT_LEFT
        }
    }
};

Captura de tela da sobreposição de entrada em que a combinação Shift + Espaço está vinculada a
ação de correr.

O SDK de entrada permite combinar botões do mouse e do teclado para um único comando. Este exemplo indica que shift e clique com o botão direito do mouse pressionados adicionam um waypoint neste jogo:

Kotlin

val cmbWaypoint = InputAction.create(
    "Add Waypoint",
    InputEventIds.CMB_WAYPOINT.id,
    InputControls.create(
        listOf(KeyEvent.KEYCODE_SHIFT_LEFT),
        listOf(InputControls.MOUSE_RIGHT_CLICK)
    )
)

Java

InputAction cmbWaypoint = InputAction.create(
        "Add Waypoint",
        InputEventIds.CMB_WAYPOINT.ordinal(),
        InputControls.create(
                Collections.singletonList(KeyEvent.KEYCODE_SHIFT_LEFT),
                Collections.singletonList(InputControls.MOUSE_RIGHT_CLICK)
        )
);

C#

var cmbWaypoint = new InputAction
{
    ActionLabel = "Add Waypoint",
    UniqueId = (int)InputEventIds.CmbWaypoint,
    InputControls = new InputControls
    {
        AndroidKeycodes = new[]
        {
            AndroidKeyCode.KEYCODE_SHIFT_LEFT
        },
        MouseActions = new[]
        {
            MouseAction.MouseRightClick
        }
    }
};

Captura de tela da sobreposição de entrada em que a ação "Adicionar waypoint" está vinculada a
Shift + botão direito do mouse.

Esta seção descreve os métodos chamados no exemplo de código:

Kotlin

InputAction.create tem estes parâmetros:

  • actionLabel é a string exibida na IU para representar a ação. A localização não é processada de maneira automática. Cabe a você realizar qualquer localização antecipadamente.
  • uniqueId é um ID de número inteiro para identificar essa ação. Cada ação precisa ter um identificador exclusivo consistente para que uma enumeração seja usada neste exemplo. Consulte IDs de chaves de rastreamento para mais informações.
  • inputControls define os controles de entrada que a ação usa. Eles vão ser mapeados para glifos consistentes na interface do usuário.

InputControls.create cria as entradas associadas a uma ação. Os parâmetros são:

  • keycodes é uma lista de números inteiros que representam entradas de teclado associadas a uma ação e definida na classe KeyEvent.
  • mouseActions é uma lista de números inteiros que representam entradas de mouse associadas à ação e definida nos próprios InputControls.

Java

InputAction.create tem estes parâmetros:

  • actionLabel é a string exibida na IU para representar a ação. A localização não é processada de maneira automática. Cabe a você realizar qualquer localização antecipadamente.
  • uniqueId é um ID de número inteiro para identificar essa ação. Cada ação precisa ter um identificador exclusivo consistente para que uma enumeração seja usada neste exemplo. Consulte IDs de chaves de rastreamento para mais informações.
  • inputControls define os controles de entrada que a ação usa. Eles vão ser mapeados para glifos consistentes na interface do usuário.

InputControls.create cria as entradas associadas a uma ação. Os parâmetros são:

  • keycodes é uma lista de números inteiros que representam entradas de teclado associadas a uma ação. Eles são definidos na classe KeyEvent.
  • mouseActions é uma lista de números inteiros que representam entradas de mouse associadas a essa ação. Ela é definida nos próprios InputControls.

C#

InputAction tem estes campos:

  • ActionLabel é a string exibida na IU para representar a ação. A localização não é processada de maneira automática. Cabe a você realizar qualquer localização antecipadamente.
  • UniqueId é um ID de número inteiro para identificar essa ação. Cada ação precisa ter um identificador exclusivo consistente para que uma enumeração seja usada neste exemplo. Consulte Rastrear IDs de chave.
  • InputControls define os controles de entrada que essa ação usa. Eles vão ser mapeados para glifos consistentes na interface do usuário.

InputControls representa as entradas associadas a uma ação e tem estes campos:

  • AndroidKeycodes é uma lista de números inteiros que representam entradas de teclado associadas a uma ação. Eles são definidos na classe AndroidKeycode.
  • MouseActions é uma lista de valores de MouseAction que representam entradas de mouse associadas à ação.

Definir um grupo de entrada

Um InputGroup é um grupo de objetos InputAction semelhantes. Exemplo:

  • Você pode especificar diferentes conjuntos de entradas para a navegação nos menus e a movimentação no jogo.
  • Você pode especificar diferentes conjuntos de entradas, dependendo do modo de locomoção no jogo, como dirigir ou caminhar.
  • Você pode especificar diferentes conjuntos de entradas com base no estado atual do jogo, como navegar em um mapa do mundo ou percorrer um nível individual.

Se você dividir as entradas em grupos temáticos, o jogador vai poder encontrar as teclas de atalho corretas para a situação atual com mais facilidade.

Kotlin

val movementInputGroup = InputGroup.create(
    "Basic Movement",
    listOf(jumpInputAction, leftInputAction, rightInputAction, useInputAction)
)

Java

InputGroup movementInputGroup = InputGroup.create(
        "Basic Movement",
        Arrays.asList(jumpInputAction, leftInputAction, rightInputAction, useInputAction)
);

C#

var movementInputGroup = new InputGroup
{
    GroupLabel = "Basic Movement",
    InputActions = new List<InputAction>
    {
        jumpInputAction,
        leftInputAction,
        rightInputAction,
        useInputAction
    }
}

Esta seção descreve as chamadas de método usadas no exemplo de código:

Kotlin

InputGroup.create tem estes parâmetros:

  • groupLabel é uma string a ser exibida na IU que pode ser usada para agrupar um conjunto de ações de maneira lógica. Essa string não é localizada para você.
  • inputActions é uma lista de objetos InputAction que você definiu na última etapa. Todas essas ações vão ser exibidas visualmente abaixo do título desse grupo.

Java

InputGroup.create tem estes parâmetros:

  • groupLabel é uma string a ser exibida na IU que pode ser usada para agrupar um conjunto de ações de maneira lógica. Essa string não é localizada para você.
  • inputActions é uma lista de objetos InputAction que você definiu na última etapa. Todas essas ações vão ser exibidas visualmente abaixo do título desse grupo.

C#

InputGroup tem estes campos:

  • GroupLabel é uma string a ser exibida na IU que pode ser usada para agrupar um conjunto de ações de maneira lógica. Essa string não é localizada para você.
  • InputActions é uma lista de objetos InputAction que você definiu na última etapa. Todas essas ações vão ser exibidas visualmente abaixo do título desse grupo.

Criar um mapa de entrada

Um InputMap é uma coleção de todos os objetos InputGroup disponíveis em um jogo e, portanto, todos os objetos InputAction que um jogador pode esperar realizar.

No exemplo abaixo, objetos MovementInputGroup são agrupados com objetos MouseSettings. Os objetos MouseSettings indicam que a sensibilidade do mouse pode ser ajustada e que o mouse é invertido no eixo y:

Kotlin

return InputMap.create(
    listOf(movementInputGroup, specialInputGroup),
    MouseSettings.create(true, true)
)

Java

return InputMap.create(
        Arrays.asList(movementInputGroup, specialInputGroup),
        MouseSettings.create(true, true)
);

C#

return new InputMap
{
    InputGroups = new List<InputGroup> {movementInputGroup, specialInputGroup},
    MouseSettings = new MouseSettings
    {
        AllowMouseSensitivityAdjustment = true,
        InvertMouseMovement = true
    }
}

Enviar um mapa de entrada

Depois que um InputMapProvider for gravado para um jogo que retorna um InputMap válido, ele precisa ser registrado com o SDK de entrada. Se as entradas de um jogo nunca mudarem, esse registro precisa ser feito apenas uma vez durante a vida útil do jogo, já que o InputMapProvider não é afetado pelos eventos de ciclo de vida do Android.

Kotlin

private val myInputMapProvider by lazy {
    MyInputMapProvider()
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    val inputMappingClient = Input.getInputMappingClient(this)
    inputMappingClient.registerInputMappingProvider(myInputMapProvider)
}

Java

private final MyInputMapProvider myInputMapProvider = new MyInputMapProvider();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    InputMappingClient inputMappingClient = Input.getInputMappingClient(this);
    inputMappingClient.registerInputMappingProvider(myInputMapProvider);
}

C#

public void Start() {
    InputMappingClient inputMappingClient = Input.GetInputMappingClient();
    inputMappingClient.registerInputMappingProvider(myInputMapProvider);
}

Cancele o registro do provedor de mapeamento de entrada quando o jogo for encerrado, mesmo que o SDK seja inteligente o suficiente para evitar o vazamento de recursos se você não fizer isso.

Kotlin

override fun onDestroy() {
    val inputMappingClient = Input.getInputMappingClient(this)
    inputMappingClient.unregisterInputMappingProvider(myInputMapProvider)

    super.onDestroy()
}

Java

@Override
protected void onDestroy() {
    InputMappingClient inputMappingClient = Input.getInputMappingClient(this);
    inputMappingClient.unregisterInputMappingProvider(myInputMapProvider);

    super.onDestroy();
}

C#

public void OnDestroy() {
    InputMappingClient inputMappingClient = Input.GetInputMappingClient();
    inputMappingClient.unregisterInputMappingProvider(myInputMapProvider);
}

Rastrear IDs de chave

É preciso rastrear IDs exclusivos para cada InputAction definida. A enumeração abaixo rastreia os IDs exclusivos de todos os exemplos deste tópico. Como os IDs são usados para rastrear as principais mudanças, não use um hash do nome da ação localizado.

Kotlin

enum class InputEventIds(val id: Int) {
    JUMP(0),
    LEFT(1),
    RIGHT(2),
    USE(3),
    SPECIAL_JUMP(4),
    SPECIAL_DUCK(5),
}

Java

public enum InputEventIds {
    JUMP,
    LEFT,
    RIGHT,
    USE,
    SPECIAL_JUMP,
    SPECIAL_DUCK
}

C#

public enum InputEventIds
{
    JUMP,
    LEFT,
    RIGHT,
    USE,
    SPECIAL_JUMP,
    SPECIAL_DUCK
}

Teste

Há duas maneiras de testar se o SDK de entrada foi implementado corretamente. Abra o SDK na IU do Google Play Games para ver o que um jogador pode ver ou no adb shell para testes e verificações automatizados.

Interface do usuário

Para testar na IU do Google Play Games, pressione Shift + Tab para abrir o Painel de jogo. No painel, clique em Controles para visualizar a lista de controles vinculados no momento.

Imagem ilustrando o fluxo descrito acima. Shift+Tab abre o Painel de jogo. Depois, a sobreposição de controles é aberta ao clicar em &quot;Controles&quot;. Essa sobreposição mostra um grupo chamado &quot;Movimentos básicos&quot; com as opções &quot;Pular&quot;, &quot;Esquerda&quot; e &quot;Direita&quot;. Os controles mostram como executar cada ação. Por exemplo, a opção &quot;Pular&quot; tem &quot;W + tecla para cima&quot; escrito abaixo dela. À direita, há uma imagem grande com as teclas &quot;w&quot; e &quot;para cima&quot;. Há também uma seção chamada &quot;Entrada especial&quot; com a palavra &quot;Duck&quot; (abaixar) escrita nela.

Linha de comando

As entradas também podem ser verificadas pelo adb na linha de comando, o que pode ajudar nos testes automatizados do recurso.

Para ver o mapa de entrada atual, use o comando adb shell abaixo (substitua MY.PACKAGE.NAME pelo nome do jogo):

adb shell dumpsys input_mapping_service --get MY.PACKAGE.NAME

Você vai ver uma saída semelhante a esta se tiver registrado o InputMap:

Getting input map for com.example.inputsample...
Successfully received the following inputmap:
# com.google.android.libraries.play.games.InputMap@d73526e1
input_groups {
  group_label: "Basic Movement"
  input_actions {
    action_label: "Jump"
    input_controls {
      keycodes: 51
      keycodes: 19
    }
    unique_id: 0
  }
  input_actions {
    action_label: "Left"
    input_controls {
      keycodes: 29
      keycodes: 21
    }
    unique_id: 1
  }
  input_actions {
    action_label: "Right"
    input_controls {
      keycodes: 32
      keycodes: 22
    }
    unique_id: 2
  }
  input_actions {
    action_label: "Use"
    input_controls {
      keycodes: 33
      keycodes: 66
      mouse_actions: MOUSE_LEFT_CLICK
      mouse_actions_value: 0
    }
    unique_id: 3
  }
}
input_groups {
  group_label: "Special Input"
  input_actions {
    action_label: "Jump"
    input_controls {
      keycodes: 51
      keycodes: 19
      keycodes: 62
      mouse_actions: MOUSE_LEFT_CLICK
      mouse_actions_value: 0
    }
    unique_id: 4
  }
  input_actions {
    action_label: "Duck"
    input_controls {
      keycodes: 47
      keycodes: 20
      keycodes: 113
      mouse_actions: MOUSE_RIGHT_CLICK
      mouse_actions_value: 1
    }
    unique_id: 5
  }
}
mouse_settings {
  allow_mouse_sensitivity_adjustment: true
  invert_mouse_movement: true
}

Sincronizar mudanças na vinculação de teclas

Muitos jogos permitem que os jogadores personalizem as vinculações de teclas. Portanto, verifique se os dados retornados por InputMapProvider estão atualizados com as configurações atuais do jogador. Se necessário, você pode chamar registerInputMappingProvider em segurança com o mapa de entrada mais recente sempre que os jogadores mudarem o esquema de entrada.

Localização

O SDK de entrada não usa o sistema de localização do Android. Como resultado, é necessário fornecer strings localizadas ao enviar um InputMap. No entanto, isso também permite usar o sistema de localização do mecanismo do jogo.

Próxima etapa

Depois de integrar o SDK de entrada ao jogo, é possível continuar com todos os requisitos restantes do Google Play Games. Para mais informações, consulte Primeiros passos com o Google Play Games.