Movimento relativo do mouse e CoreWindow

Nos jogos, o mouse é uma opção de controle comum que é familiar para muitos jogadores e também é essencial para muitos gêneros de jogos, incluindo jogos de tiro em primeira e terceira pessoa e jogos de estratégia em tempo real. Aqui, discutimos a implementação de controles relativos do mouse, que não usam o cursor do sistema e não retornam coordenadas absolutas da tela; em vez disso, eles rastreiam o delta de pixels entre os movimentos do mouse.

Alguns aplicativos, como jogos, usam o mouse como um dispositivo de entrada mais geral. Por exemplo, um modelador 3D pode usar a entrada do mouse para orientar um objeto 3D simulando um trackball virtual; ou um jogo pode usar o mouse para mudar a direção da câmera de visualização por meio de controles de aparência do mouse.

Nesses cenários, o aplicativo requer dados relativos do mouse. Os valores relativos do mouse representam a distância que o mouse se moveu desde o último quadro, em vez dos valores absolutos da coordenada x-y em uma janela ou tela. Além disso, os aplicativos geralmente ocultam o cursor do mouse, pois a posição do cursor em relação às coordenadas da tela não é relevante ao manipular um objeto ou cena 3D.

Quando o usuário executa uma ação que move o aplicativo para um modo de manipulação de objeto/cena 3D relativo, o aplicativo deve:

  • Ignore o manuseio padrão do mouse.
  • Habilite o manuseio relativo do mouse.
  • Oculte o cursor do mouse definindo-o como um ponteiro nulo (nullptr).

Quando o usuário executa uma ação que move o aplicativo para fora de um modo de manipulação de objeto/cena 3D relativo, o aplicativo deve:

  • Habilite o manuseio padrão/absoluto do mouse.
  • Desative o manuseio relativo do mouse.
  • Defina o cursor do mouse para um valor não nulo (o que o torna visível).

Observação
Com esse padrão, a localização do cursor absoluto do mouse é preservada ao entrar no modo relativo sem cursor. O cursor reaparece no mesmo local de coordenadas da tela que era antes de ativar o modo de movimento relativo do mouse.

Manipulando o movimento relativo do mouse

Para acessar valores delta relativos do mouse, registre-se para o evento MouseDevice::MouseMoved , conforme mostrado aqui.



// register handler for relative mouse movement events
Windows::Devices::Input::MouseDevice::GetForCurrentView()->MouseMoved +=
        ref new TypedEventHandler<MouseDevice^, MouseEventArgs^>(this, &MoveLookController::OnMouseMoved);




void MoveLookController::OnMouseMoved(
    _In_ Windows::Devices::Input::MouseDevice^ mouseDevice,
    _In_ Windows::Devices::Input::MouseEventArgs^ args
    )
{
    float2 pointerDelta;
    pointerDelta.x = static_cast<float>(args->MouseDelta.X);
    pointerDelta.y = static_cast<float>(args->MouseDelta.Y);

    float2 rotationDelta;
    rotationDelta = pointerDelta * ROTATION_GAIN;	// scale for control sensitivity

    // update our orientation based on the command
    m_pitch -= rotationDelta.y;						// mouse y increases down, but pitch increases up
    m_yaw   -= rotationDelta.x;						// yaw defined as CCW around y-axis

    // limit pitch to straight up or straight down
    float limit = (float)(M_PI/2) - 0.01f;
    m_pitch = (float) __max( -limit, m_pitch );
    m_pitch = (float) __min( +limit, m_pitch );

    // keep longitude in useful range by wrapping
    if ( m_yaw >  M_PI )
        m_yaw -= (float)M_PI*2;
    else if ( m_yaw < -M_PI )
        m_yaw += (float)M_PI*2;
}

O manipulador de eventos neste exemplo de código, OnMouseMoved, renderiza a exibição com base nos movimentos do mouse. A posição do ponteiro do mouse é passada para o manipulador como um objeto MouseEventArgs .

Ignore o processamento de dados absolutos do mouse do evento CoreWindow::P ointerMoved quando seu aplicativo mudar para lidar com valores relativos de movimento do mouse. No entanto, ignore essa entrada somente se o evento CoreWindow::P ointerMoved tiver ocorrido como resultado da entrada do mouse (em oposição à entrada por toque). O cursor é ocultado definindo o CoreWindow::P ointerCursor como nullptr.

Voltando ao movimento absoluto do mouse

Quando o aplicativo sair do objeto 3D ou do modo de manipulação de cena e não usar mais o movimento relativo do mouse (como quando ele retorna a uma tela de menu), retorne ao processamento normal do movimento absoluto do mouse. Neste momento, pare de ler os dados relativos do mouse, reinicie o processamento de eventos padrão do mouse (e ponteiro) e defina CoreWindow::P ointerCursor como valor não nulo.

Observação
Quando seu aplicativo está no modo de manipulação de objeto/cena 3D (processando movimentos relativos do mouse com o cursor desligado), o mouse não pode invocar a interface do usuário de borda, como os botões, a pilha de retorno ou a barra de aplicativos. Portanto, é importante fornecer um mecanismo para sair desse modo específico, como a tecla Esc comumente usada.