Controlador de navegação da interface do usuário

Esta página descreve os conceitos básicos da programação para dispositivos de navegação da interface do usuário usando Windows.Gaming.Input.UINavigationController e APIs relacionadas para o Plataforma Universal do Windows (UWP).

Ao ler esta página, você saberá como:

  • Obter uma lista de dispositivos de navegação da interface conectados e seus usuários
  • Detectar se um dispositivo de navegação foi adicionado ou removido
  • Ler entradas de um ou mais dispositivos de navegação da interface do usuário
  • Os gamepads e joysticks de arcade se comportam como dispositivos de navegação

Visão geral do controlador de navegação da interface do usuário

Quase todos os jogos têm pelo menos uma interface do usuário que é separada do jogo, mesmo que sejam apenas menus pré-jogo ou caixas de diálogo no jogo. Os jogadores precisam ser capaz de navegar nessa interface do usuário usando o dispositivo de entrada que escolherem, mas isso força os desenvolvedores a adicionar suporte específico para cada tipo de dispositivo de entrada e também pode introduzir inconsistências entre os jogos e os dispositivos de entrada que podem confundir os jogadores. Por esses motivos, a API UINavigationController foi criada.

Controladores de navegação da interface do usuário são os dispositivos de entrada lógicos que existem para fornecer um vocabulário de comandos comuns de navegação da interface do usuário que podem ser aceitos por uma variedade de dispositivos de entrada físicos. Um controlador de navegação da interface do usuário é apenas uma maneira diferente de olhar para um dispositivo de entrada físico; usamos dispositivo de navegação para fazer referência a qualquer dispositivo de entrada físico encarado como um controlador de navegação. Ao fazer a programação de acordo com um dispositivo de navegação em vez de dispositivos de entrada específicos, os desenvolvedores evitam a sobrecarga do suporte para diferentes dispositivos de entrada e obtêm uma consistência por padrão.

Como o número e a variedade de controles aceitos por cada tipo de dispositivo de entrada podem ser bem diferentes e certos dispositivos de entrada podem permitir um conjunto maior de comandos de navegação, a interface do controlador de navegação divide o vocabulário de comandos em um conjunto obrigatório, que contém os comandos mais comuns e essenciais, e um conjunto opcional, que contém comandos convenientes, não são essenciais. Todos os dispositivos de navegação aceitam todos os comandos do conjunto obrigatório e podem dar suporte a todos, alguns ou nenhum dos comandos no conjunto opcional.

Conjunto obrigatório

Os dispositivos de navegação devem permitir todos os comandos de navegação do conjunto obrigatório; esses são os comandos direcionais (para cima, para baixo, esquerda e direita), exibir, menu, aceitar e cancelar.

Os comandos direcionais destinam-se à navegação principal de foco do plano XY entre elementos de interface do usuário únicos. Os comandos exibir e menu servem para exibir informações do jogo (geralmente momentâneas, às vezes, restritas) e para alternar entre os contextos de jogo e menu, respectivamente. Os comandos aceitar e cancelar servem como respostas afirmativas (sim) e negativas (não), respectivamente.

A tabela a seguir resume esses comandos e o uso pretendido, com exemplos. | Comando | Uso pretendido | -------:| --------------- | Up | Navegação de foco XY para cima | Para baixo | Navegação de foco XY para baixo | Esquerda | Navegação de foco XY à esquerda | Direito | Navegação de foco XY à direita | Exibição | Exibir informações de jogo (placar, estatísticas do jogo, objetivos, mapa do mundo ou área) | Menu | Menu principal/ Pausar (configurações, status, equipamentos, inventário, pausar) | Aceitar | Resposta afirmativa (aceitar, avançar, confirmar, iniciar, sim) | Cancelar | Resposta negativa (rejeitar, reverter, recusar, parar, não)

Conjunto opcional

Os dispositivos de navegação também podem aceitar todos, alguns ou nenhum dos comandos de navegação do conjunto opcional; esses são comandos de paginação (para cima, para baixo, esquerda e direita), de rolagem (para cima, para baixo, esquerda e direita) e contextuais (contexto 1 a 4).

Os comandos contextuais são explicitamente projetados para comandos e atalhos de navegação específicos do aplicativo. Os comandos de paginação e de rolagem servem para navegação rápida entre páginas ou grupos de elementos de interface do usuário e navegação refinada nos elementos de interface do usuário, respectivamente.

A tabela a seguir resume esses comandos e o uso pretendido. | Comando | Uso pretendido | -----------:| ------------ | PageUp | Ir para cima (para a página vertical ou grupo superior/anterior) | PageDown | Pule para baixo (para a página ou grupo vertical inferior/próximo) | PageLeft | Pule para a esquerda (para a página ou grupo horizontal para a esquerda/anterior) | PageRight | Ir para a direita (para a página ou grupo horizontal para a direita/próxima) | ScrollUp | Role para cima (dentro do elemento de interface do usuário focado ou grupo rolável) | ScrollDown | Role para baixo (dentro do elemento de interface do usuário focado ou grupo rolável) | ScrollLeft | Role para a esquerda (dentro do elemento de interface do usuário focado ou grupo rolável) | ScrollRight | Role para a direita (dentro do elemento de interface do usuário focado ou grupo rolável) | Context1 | Ação de contexto principal | Context2 | Ação de contexto secundário | Context3 | Terceira ação de contexto | Context4 | Quarta ação de contexto

Nota Embora um jogo seja livre para responder a qualquer comando com uma função real diferente do uso pretendido, um comportamento surpreendente deve ser evitado. Particularmente, não altere a função real de um comando se precisar do uso pretendido dele, tente atribuir funções novas ao comando que faça mais sentido e atribua funções equivalentes aos comandos equivalentes, como PageUp/PageDown. Por fim, considere quais comandos são compatíveis com cada tipo de dispositivo de entrada e para quais controles eles são mapeados, certificando-se de que os comandos essenciais sejam acessíveis em todos os dispositivos.

Navegação com gamepad, joystick de arcade e roda de corrida

Todos os dispositivos de entrada com suporte do namespace Windows.Gaming.Input são dispositivos de navegação da interface do usuário.

A tabela a seguir resume como o conjunto obrigatório de comandos de navegação é mapeado para vários dispositivos de entrada.

Comando Navegação Entrada do gamepad Entrada do joystick de arcade Entrada do volante de corrida
Up Botão esquerdo para cima/Direcional para cima Joystick para cima Direcional para cima
Down Botão esquerdo para baixo/Direcional para baixo Joystick para baixo Direcional para baixo
Esquerda Botão esquerdo para a esquerda/Direcional para a esquerda Joystick para a esquerda Direcional para a esquerda
Direita Botão esquerdo para a direita/Direcional para a direita Joystick para a direita Direcional para a direita
Exibir Botão Exibir Botão Exibir Botão Exibir
Menu Botão Menu Botão Menu Botão Menu
Aceitar Botão A Botão de ação 1 Botão A
Cancelar Botão B Botão de ação 2 Botão B

A tabela a seguir resume como o conjunto opcional de comandos de navegação é mapeado para vários dispositivos de entrada.

Comando Navegação Entrada do gamepad Entrada do joystick de arcade Entrada do volante de corrida
PageUp Gatilho esquerdo sem suporte Varia
PageDown Gatilho direito sem suporte Varia
PageLeft Botão superior esquerdo sem suporte Varia
PageRight Botão superior direito sem suporte Varia
ScrollUp Botão direito para cima sem suporte Varia
ScrollDown Botão direito para baixo sem suporte Varia
ScrollLeft Botão direito para a esquerda sem suporte Varia
ScrollRight Botão direito para a direita sem suporte Varia
Context1 Botão X sem suporte Botão X (comumente)
Context2 Botão Y sem suporte Botão Y (normalmente)
Context3 Pressionar o botão esquerdo sem suporte Varia
Context4 Pressionar o botão direito sem suporte Varia

Detectar e rastrear controladores de navegação da interface do usuário

Embora os controladores de navegação da interface do usuário sejam dispositivos de entrada lógicos, eles são uma representação de um dispositivo físico e gerenciados pelo sistema da mesma forma. Você não precisa criá-los ou inicializá-los; o sistema fornece uma lista de controladores de navegação da interface do usuário e eventos conectados para avisar você quando um controlador de navegação da interface do usuário é adicionado ou removido.

A lista de controladores de navegação da interface do usuário

A classe UINavigationController fornece uma propriedade estática, UINavigationControllers, que é uma lista somente leitura de dispositivos de navegação da interface do usuário conectados no momento. Como você pode estar interessado apenas em alguns dos dispositivos de navegação conectados, é recomendável manter sua própria coleção em vez de acessá-los por meio da propriedade UINavigationControllers.

O exemplo a seguir copia todos os controladores de navegação da interface do usuário conectados para uma nova coleção.

auto myNavigationControllers = ref new Vector<UINavigationController^>();

for (auto device : UINavigationController::UINavigationControllers)
{
    // This code assumes that you're interested in all navigation controllers.
    myNavigationControllers->Append(device);
}

Adicionando e removendo controladores de navegação da interface do usuário

Quando um controlador de navegação da interface do usuário é adicionado ou removido, os eventos UINavigationControllerAdded e UINavigationControllerRemoved são gerados. Você pode registrar um manipulador de eventos para esses eventos para rastrear os dispositivos de navegação que estão conectados no momento.

O exemplo a seguir inicia o rastreamento de um dispositivo de navegação da interface do Usuário que foi adicionado.

UINavigationController::UINavigationControllerAdded += ref new EventHandler<UINavigationController^>(Platform::Object^, UINavigationController^ args)
{
    // This code assumes that you're interested in all new navigation controllers.
    myNavigationControllers->Append(args);
}

O exemplo a seguir interrompe o rastreamento de um joystick de arcade que foi removido.

UINavigationController::UINavigationControllerRemoved += ref new EventHandler<UINavigationController^>(Platform::Object^, UINavigationController^ args)
{
    unsigned int indexRemoved;

    if(myNavigationControllers->IndexOf(args, &indexRemoved))
	{
        myNavigationControllers->RemoveAt(indexRemoved);
    }
}

Usuários e headsets

Cada dispositivo de navegação pode ser associado a uma conta de usuário para vincular a identidade do usuário à entrada dele. Também pode ter um headset anexado para facilitar os recursos de navegação por voz ou chat. Para saber mais sobre como trabalhar com usuários e headsets, veja Rastreamento de usuários e de seus dispositivos e Headset.

Lendo o controlador de navegação da interface do usuário

Depois de identificar o dispositivo de navegação da interface do usuário de seu interesse, você está pronto para coletar as informações dele. No entanto, ao contrário de outros tipos de entrada com os quais você possa estar acostumado, os dispositivos de navegação não comunicam a alteração de estado acionando eventos. Você faz leituras regulares do estado atual deles fazendo uma sondagem.

Fazendo a sondagem do controlador de navegação da interface do usuário

A sondagem captura um instantâneo do dispositivo de navegação em um momento preciso. Essa abordagem de coleta de entrada é ótima para a maioria dos jogos, pois sua lógica normalmente é executada em um loop determinante em vez de ser orientada por evento; também é normalmente mais simples interpretar os comandos de jogos da entrada coletada de uma vez do que de várias entradas individuais coletadas ao longo do tempo.

Você pode sondar um dispositivo de navegação chamando UINavigationController.GetCurrentReading; essa função retorna um UINavigationReading que contém o estado do dispositivo de navegação.

auto navigationController = myNavigationControllers[0];

UINavigationReading reading = navigationController->GetCurrentReading();

Lendo os botões

Cada um dos botões de navegação da interface do usuário fornecem uma leitura booliana que corresponde a se ele está pressionado (para baixo) ou liberado (para acima). Para garantir a eficiência, as leituras dos botões não são representadas como valores booleanos individuais; elas são agrupadas em um dos dois campos de bits representados pelas enumerações RequiredUINavigationButtons e OptionalUINavigationButtons.

Os botões pertencentes ao conjunto obrigatório são lidas pela propriedade RequiredButtons da estruturar UINavigationReading; os botões pertencentes ao conjunto opcional são lidos pela propriedade OptionalButtons. Como essas propriedades são campos de bits, o mascaramento bit a bit é usado para isolar o valor do botão de seu interesse. O botão está pressionado (para baixo) quando o bit correspondente está definido; caso contrário, ele está liberado (para acima).

O exemplo a seguir determina se o botão Aceitar do conjunto obrigatório está pressionado.

if (RequiredUINavigationButtons::Accept == (reading.RequiredButtons & RequiredUINavigationButtons::Accept))
{
    // Accept is pressed
}

O exemplo a seguir determina se o botão Aceitar do conjunto obrigatório está liberado.

if (RequiredUINavigationButtons::None == (reading.RequiredButtons & RequiredUINavigationButtons::Accept))
{
    // Accept is released (not pressed)
}

Certifique-se de usar a propriedade OptionalButtons e a enumeração OptionalUINavigationButtons ao ler os botões do conjunto opcional.

O exemplo a seguir determina se o botão Contexto 1 do conjunto opcional está pressionado.

if (OptionalUINavigationButtons::Context1 == (reading.OptionalButtons & OptionalUINavigationButtons::Context1))
{
    // Context 1 is pressed
}

Às vezes, convém determinar quando um botão passa de pressionado para liberado ou vice-versa, se vários botões foram pressionados ou liberados ou se um conjunto de botões está organizado de determinada maneira – alguns pressionados, outros, não. Para obter informações sobre como detectar essas condições, consulte Detectando transições do botão e Detectando organizações complexas de botão.

Executar o exemplo de controlador de navegação da interface do usuário

O exemplo InputInterfacingUWP (github) demonstra como os diferentes dispositivos de entrada se comportam como controladores de navegação da interface do usuário.

Confira também

Windows.Gaming.Input.GamepadWindows.Gaming.Input.ArcadeStickWindows.Gaming.Input.RacingWheelWindows.Gaming.Input.IGameController