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

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

Ao ler esta página, você aprenderá:

  • Como reunir uma lista de dispositivos de navegação de interface do usuário conectados e seus usuários
  • Como detectar que um dispositivo de navegação foi adicionado ou removido
  • Como ler a entrada de um ou mais dispositivos de navegação da interface do usuário
  • Como os gamepads e os joysticks de fliperama 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 alguma interface de usuário separada da jogabilidade, mesmo que sejam apenas menus pré-jogo ou diálogos no jogo. Os jogadores precisam ser capazes de navegar nesta interface usando qualquer dispositivo de entrada que escolheram, mas sobrecarrega os desenvolvedores para adicionar suporte específico para cada tipo de dispositivo de entrada e também pode introduzir inconsistências entre jogos e dispositivos de entrada que confundem os jogadores. Por esses motivos, a API UINavigationController foi criada.

Os controladores de navegação da interface do usuário são dispositivos de entrada lógica que existem para fornecer um vocabulário de comandos comuns de navegação da interface do usuário que podem ser suportados por uma variedade de dispositivos de entrada físicos . Um controlador de navegação de interface do usuário é apenas uma maneira diferente de olhar para um dispositivo de entrada físico; usamos o dispositivo de navegação para nos referirmos a qualquer dispositivo de entrada físico que está sendo visto como um controlador de navegação. Ao programar em um dispositivo de navegação em vez de dispositivos de entrada específicos, os desenvolvedores evitam o fardo de oferecer suporte a diferentes dispositivos de entrada e obtêm consistência por padrão.

Como o número e a variedade de controles suportados por cada tipo de dispositivo de entrada podem ser muito diferentes e como determinados dispositivos de entrada podem querer dar suporte a um conjunto mais avançado de comandos de navegação, a interface do controlador de navegação divide o vocabulário de comandos em um conjunto necessário contendo os comandos mais comuns e essenciais e um conjunto opcional contendo comandos convenientes, mas não essenciais. Todos os dispositivos de navegação suportam todos os comandos no conjunto necessário e podem suportar todos, alguns ou nenhum dos comandos no conjunto opcional.

Conjunto necessário

Os dispositivos de navegação devem suportar todos os comandos de navegação no conjunto necessário; estes são os comandos direcionais (para cima, para baixo, para a esquerda e para a direita), exibir, menu, aceitar e cancelar.

Os comandos direcionais destinam-se à navegação primária de foco XY entre elementos de interface do usuário únicos. Os comandos de visualização e menu destinam-se a exibir informações de jogo (geralmente momentâneas, às vezes modalmente) e para alternar entre contextos de jogo e menu, respectivamente. Os comandos accept e cancel destinam-se a respostas afirmativas (sim) e negativas (não), respectivamente.

A tabela a seguir resume esses comandos e seus usos pretendidos, com exemplos. | Comando | Uso pretendido | -------:| --------------- | Para cima | Navegação com foco XY para cima | Para baixo | Navegação de foco XY para baixo | Esquerda | Navegação de foco XY para a esquerda | Direito | Navegação de foco XY à direita | Visão | Exibir informações de jogo (placar, estatísticas do jogo, objetivos, mapa-múndi ou área) | Cardápio | Menu principal / Pausa (configurações, status, equipamento, inventário, pausa) | 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 dar suporte a todos, alguns ou nenhum dos comandos de navegação no conjunto opcional; esses são os comandos de paginação (para cima, para baixo, para a esquerda e para a direita), rolagem (para cima, para baixo, para a esquerda e para a direita) e contextuais (contexto 1-4).

Os comandos contextuais destinam-se explicitamente a comandos específicos do aplicativo e atalhos de navegação. Os comandos de paginação e rolagem destinam-se à navegação rápida entre páginas ou grupos de elementos da interface do usuário e à navegação refinada dentro dos elementos da interface do usuário, respectivamente.

A tabela a seguir resume esses comandos e seus usos pretendidos. | Comando | Uso pretendido | -----------:| ------------ | PageUp | Saltar para cima (para a página ou grupo vertical superior/anterior) | PageDown | Saltar para baixo (para a página ou grupo vertical inferior/seguinte) | PáginaEsquerda | Ir para a esquerda (para a página ou grupo horizontal para a esquerda/anterior) | PageRight | Saltar para a direita (para a direita/próxima página ou grupo horizontal) | Rolagem para cima | Rolar para cima (dentro do elemento de interface do usuário focado ou grupo rolável) | Rolagem para baixo | Rolar para baixo (dentro do elemento de interface do usuário focado ou grupo rolável) | Rolagem para a esquerda | Rolar para a esquerda (dentro do elemento de interface do usuário focado ou grupo rolável) | Rolagem para a direita | Rolar para a direita (dentro do elemento de interface do usuário focado ou grupo rolável) | Contexto1 | Ação de contexto primário | Contexto2 | Ação de contexto secundário | Contexto3 | Ação do terceiro contexto | Contexto4 | Quarto contexto: ação

Observação 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. Em particular, não altere a função real de um comando se precisar do uso pretendido, tente atribuir novas funções ao comando que faz mais sentido e atribua funções de contrapartida a comandos de contrapartida, 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 críticos sejam acessíveis de todos os dispositivos.

Gamepad, stick de arcade e navegação no volante de corrida

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

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

Comando de navegação Entrada do gamepad Entrada de stick de arcade Entrada do volante
Operante Botão esquerdo para cima/D-pad up Stick em cima D-pad para cima
Para baixo Botão esquerdo para baixo/D-pad para baixo Stick para baixo D-pad para baixo
Esquerda Botão esquerdo do botão esquerdo/D-pad à esquerda Stick para a esquerda D-pad esquerdo
Right Botão direito do polegar esquerdo/D-pad à direita Stick para a direita D-pad direito
Visualizar Botão Exibir Botão Exibir Botão Exibir
Menu Botão de menu Botão de menu Botão de menu
Aceitar Botão A Botão Ação 1 Botão A
Cancelar Botão B Botão 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 de navegação Entrada do gamepad Entrada de stick de arcade Entrada do volante
PageUp Gatilho esquerdo Não suportado varia
PageDown Gatilho direito Não suportado varia
PageLeft LB (botão superior esquerdo) Não suportado varia
PageRight RB (botão superior direito) Não suportado varia
Rolagem para cima Botão direito para cima Não suportado varia
Rolar para baixo Botão direito para baixo Não suportado varia
Rolagem para a esquerda Botão direito para a esquerda Não suportado varia
Rolar para a direita Botão direito do mouse para a direita Não suportado varia
Contexto1 Botão X Não suportado Botão X (geralmente)
Contexto2 Botão Y Não suportado Botão Y (comumente)
Contexto3 Pressionar o botão esquerdo Não suportado varia
Contexto4 Pressione o botão direito do mouse Não suportado 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ógica, eles são uma representação de um dispositivo físico e são gerenciados pelo sistema da mesma maneira. Você não precisa criá-los ou inicializá-los; o sistema fornece uma lista de controladores e eventos de navegação da interface do usuário conectados para notificá-lo 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 que estão 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 UINavigationControllers propriedade.

O exemplo a seguir copia todos os controladores de navegação da interface do usuário conectados em 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 acompanhar os dispositivos de navegação que estão conectados no momento.

O exemplo a seguir começa a rastrear 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 stick 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 sua identidade à sua entrada e pode ter um fone de ouvido conectado para facilitar o bate-papo por voz ou os recursos de navegação. Para saber mais sobre como trabalhar com usuários e headsets, consulte Acompanhamento de usuários e 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 no qual você está interessado, você está pronto para coletar informações dele. No entanto, ao contrário de alguns outros tipos de entrada com os quais você pode estar acostumado, os dispositivos de navegação não comunicam a alteração de estado gerando eventos. Em vez disso, você faz leituras regulares de seus estados atuais sondando-os.

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

A sondagem captura um instantâneo do dispositivo de navegação em um ponto preciso no tempo. Essa abordagem para coleta de entrada é uma boa opção para a maioria dos jogos porque sua lógica normalmente é executada em um loop determinístico em vez de ser orientada por eventos; Também é tipicamente mais simples interpretar os comandos do jogo a partir de entradas coletadas de uma só vez do que de muitas entradas únicas coletadas ao longo do tempo.

Você sonda 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();

Como ler os botões

Cada um dos botões de navegação da interface do usuário fornece uma leitura booleana que corresponde a se está pressionado (para baixo) ou liberado (para cima). Para eficiência, as leituras de botão não são representadas como valores booleanos individuais; em vez disso, eles são todos empacotados em um dos dois campos de bits representados pelas enumerações RequiredUINavigationButtons e OptionalUINavigationButtons .

Os botões pertencentes ao conjunto necessário são lidos da RequiredButtons propriedade da estrutura UINavigationReading ; os botões pertencentes ao conjunto opcional são lidos da OptionalButtons propriedade. Como essas propriedades são campos de bits, o mascaramento bit a bit é usado para isolar o valor do botão no qual você está interessado. O botão é pressionado (para baixo) quando o bit correspondente é definido; caso contrário, é liberado (para cima).

O exemplo a seguir determina se o botão Aceitar no conjunto necessário é pressionado.

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

O exemplo a seguir determina se o botão Aceitar no conjunto necessário é liberado.

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

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

O exemplo a seguir determina se o botão Contexto 1 no conjunto opcional é pressionado.

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

Às vezes, você pode querer determinar quando um botão faz a transição de pressionado para liberado ou liberado para pressionado, se vários botões são pressionados ou liberados ou se um conjunto de botões é organizado de uma maneira específica - alguns pressionados, outros não. Para obter informações sobre como detectar essas condições, consulte Como detectar transições de botão e Como detectando arranjos complexos de botões.

Executar o exemplo do 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