CoreWindow o movimiento de mouse relativoRelative mouse movement and CoreWindow

En los juegos, el mouse es una opción de control común que es conocida por muchos de los jugadores, y es también esencial para muchos géneros de juegos, como los juegos de disparos en primera y tercera persona, y los juegos de estrategia en tiempo real.In games, the mouse is a common control option that is familiar to many players, and is likewise essential to many genres of games, including first- and third-person shooters, and real-time strategy games. Aquí analizamos la implementación de controles de mouse relativos, que no usan el cursor del sistema y no devuelven coordenadas de pantalla absolutas. En su lugar, siguen el delta de píxeles entre los diferentes movimientos del mouse.Here we discuss the implementation of relative mouse controls, which don't use the system cursor and don't return absolute screen coordinates; instead, they track the pixel delta between mouse movements.

Algunas aplicaciones, como los juegos, usan el mouse como un dispositivo de entrada más general.Some apps, such as games, use the mouse as a more general input device. Por ejemplo, un modelador 3D puede usar la entrada de mouse para orientar un objeto 3D simulando una bola de seguimiento virtual, o un juego puede usar el mouse para cambiar la dirección de la cámara de visualización mediante controles con apariencia de mouse.For example, a 3-D modeler might use mouse input to orient a 3-D object by simulating a virtual trackball; or a game might use the mouse to change the direction of the viewing camera via mouse-look controls.

En estos escenarios, la aplicación requiere de datos de mouse relativos.In these scenarios, the app requires relative mouse data. Los valores de mouse relativos representan la distancia que recorrió el mouse desde el último fotograma, en lugar de los valores de coordenadas x e y absolutos dentro de una ventana o pantalla.Relative mouse values represent how far the mouse moved since the last frame, rather than the absolute x-y coordinate values within a window or screen. Además, las aplicaciones a menudo ocultan el cursor del mouse dado que la posición del cursor con respecto a las coordenadas de pantalla no es relevante al manipular una escena o un objeto 3D.Also, apps often hide the mouse cursor since the position of the cursor with respect to the screen coordinates is not relevant when manipulating a 3-D object or scene.

Cuando el usuario realiza una acción que mueve la aplicación dentro de un modo de manipulación de escena u objeto 3D relativo, la aplicación debe realizar lo siguiente:When the user takes an action that moves the app into a relative 3-D object/scene manipulation mode, the app must:

  • Ignorar el control del mouse predeterminadoIgnore default mouse handling.
  • Habilitar el control del mouse relativoEnable relative mouse handling.
  • Ocultar el cursor del mouse configurando un puntero nulo (nullptr)Hide the mouse cursor by setting it a null pointer (nullptr).

Cuando el usuario realiza una acción que mueve la aplicación fuera de un modo de manipulación de escena u objeto 3D relativo, la aplicación debe realizar lo siguiente:When the user takes an action that moves the app out of a relative 3-D object/scene manipulation mode, the app must:

  • Habilitar el control del mouse absoluto/predeterminadoEnable default/absolute mouse handling.
  • Desactivar el control del mouse relativoTurn off relative mouse handling.
  • Establecer el cursor del mouse en un valor no nulo (que lo hace visible)Set the mouse cursor to a non-null value (which makes it visible).

NotaNote
Con este patrón, la ubicación del cursor del mouse absoluto se conserva al entrar en el modo relativo sin cursor.With this pattern, the location of the absolute mouse cursor is preserved on entering the cursorless relative mode. El cursor reaparece en la misma ubicación de coordenada de pantalla en la que estaba antes de habilitar el modo de movimiento de mouse relativo.The cursor re-appears in the same screen coordinate location as it was previous to enabling the relative mouse movement mode.

Controlar el movimiento de mouse relativoHandling relative mouse movement

Para acceder a los valores delta de mouse relativo, regístrate para el evento MouseDevice::MouseMoved tal como se muestra aquí.To access relative mouse delta values, register for the MouseDevice::MouseMoved event as shown here.



// 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;
}

El controlador de eventos de este ejemplo de código, OnMouseMoved, representa la vista sobre la base de los movimientos del mouse.The event handler in this code example, OnMouseMoved, renders the view based on the movements of the mouse. La posición del puntero del mouse se pasa al controlador como un objeto MouseEventArgs.The position of the mouse pointer is passed to the handler as a MouseEventArgs object.

Omite procesar en exceso los datos de mouse absoluto del evento CoreWindow::PointerMoved cuando la aplicación cambie al control de valores de movimiento de mouse relativo.Skip over processing of absolute mouse data from the CoreWindow::PointerMoved event when your app changes to handling relative mouse movement values. No obstante, solamente omite esta entrada si el evento CoreWindow::PointerMoved se produjo como resultado de la entrada de mouse (en contraposición con la entrada táctil).However, only skip this input if the CoreWindow::PointerMoved event occurred as the result of mouse input (as opposed to touch input). El cursor se oculta estableciendo el valor de CoreWindow::PointerCursor en nullptr.The cursor is hidden by setting the CoreWindow::PointerCursor to nullptr.

Volver al movimiento de mouse absolutoReturning to absolute mouse movement

Cuando la aplicación salga del modo de manipulación de escenas u objetos 3D, y ya no use el movimiento de mouse relativo (por ejemplo, cuando devuelve una pantalla de menú) vuelve al procesamiento normal del movimiento de mouse absoluto.When the app exits the 3-D object or scene manipulation mode and no longer uses relative mouse movement (such as when it returns to a menu screen), return to normal processing of absolute mouse movement. En este punto, deja de leer los datos de mouse relativo, reinicia el procesamiento de eventos de mouse (y puntero) estándar y establece CoreWindow::PointerCursor en un valor no nulo.At this time, stop reading relative mouse data, restart the processing of standard mouse (and pointer) events, and set CoreWindow::PointerCursor to non-null value.

NotaNote
Cuando tu aplicación se encuentra en el modo de manipulación de escenas u objetos 3D (procesamiento de movimientos de mouse relativo con el cursor desactivado), el mouse no puede invocar la interfaz de usuario perimetral como los accesos, la pila de retroceso o la barra de la aplicación.When your app is in the 3-D object/scene manipulation mode (processing relative mouse movements with the cursor off), the mouse cannot invoke edge UI such as the charms, back stack, or app bar. Por lo tanto, es importante proporcionar un mecanismo para salir de este modo específico, como la tecla Esc que se usa habitualmente.Therefore, it is important to provide a mechanism to exit this particular mode, such as the commonly used Esc key.