¿Cómo puedo atrapar el mouse del usuario dentro de mi juego? No es un juego de pantalla completa, pero lo quiero para que el usuario no pueda arrastrar el mouse fuera de la pantalla.
¿Tengo que verificar las coordenadas del mouse y SDL_WarpCursor para que diga dentro de la ventana (manualmente), o hay una forma automática?
Gracias.
Respuestas:
Si bien puede implementar esto usando SDL_WarpCursor (), he tenido problemas con ese método en algunas plataformas. He tenido problemas reales con algunas plataformas que no realizan de manera confiable la acción WarpCursor (), particularmente cuando lo he estado llamando a cada cuadro.
Además, recuerde que en muchas plataformas, el cursor se maneja a una frecuencia más alta que su aplicación. ¡Esto es particularmente cierto si estás corriendo por debajo de 60 fps! Entonces, incluso si la plataforma está deformando con éxito el mouse en cada cuadro de su juego, el cursor aún podría alejarse de su ventana si está recibiendo actualizaciones entre sus cuadros procesados.
El método correcto para atrapar el mouse bajo SDL es:
Esto le dice a SDL que su intención es tomar el control total del mouse + teclado (consulte la documentación ) y, por lo tanto, mantener el mouse dentro de la ventana sin importar qué. A partir de este momento, el mouse no se moverá fuera de la ventana, independientemente de su velocidad de fotogramas, y no debe llamar a SDL_WarpCursor, excepto si realmente tiene la intención de teletransportar el cursor en algún lugar, en lugar de enviarlo de manera continua.
Mientras esté en este modo de "captura", continuará recibiendo eventos de movimiento del mouse como si el mouse no estuviera restringido dentro de la ventana. (Entonces, si el cursor está en el borde derecho de la pantalla y el usuario mueve su mouse más a la derecha, recibirá un evento de movimiento del mouse que muestra el movimiento a la derecha, aunque la posición del cursor no cambiará). Esto es realmente útil para (por ejemplo) girar controles para juegos FPS, donde solo te importa el movimiento relativo del cursor, no su posición absoluta.
Actualización para SDL2 - 9 de diciembre de 2013
Esta interfaz ha cambiado para SDL2. Si está utilizando SDL1.2, la respuesta anterior sigue siendo correcta. Sin embargo, bajo SDL2 la
SDL_WM_GrabInput(SDL_GrabMode)
función ya no está disponible. La nueva forma de SDL2 de capturar el mouse es:De lo contrario, esto es idéntico a la función anterior: en este modo continuará recibiendo
SDL_MOUSEMOTION
eventos como si el mouse no estuviera restringido dentro de la ventana.fuente
Si bien la respuesta actualizada de Trevor refleja el estado actual de SDL2, también puede atrapar el mouse al crear su
SDL_Window
con elSDL_WINDOW_INPUT_GRABBED
conjunto. Tenga en cuenta que me he encontrado con algunos problemas extraños en Linux (presumiblemente debido a alguna peculiaridad de la ventana X) donde nunca puede salir de la ventana a menos que se llame a SDL_QUIT (incluso si otro evento del sistema operativo le quita el foco).fuente
Para SDL2 parece que también existe la función SDL_SetWindowGrab si desea habilitarla y deshabilitarla.
fuente
Puede usar el evento de movimiento SDL para detectar cuándo se mueve el mouse. Luego, puede llamar a WarpCursor dentro de eso incluso después de disparar un evento para canalizar los valores relX y relY. También puede ocultar el cursor del sistema operativo y dibujar una cruz o algo similar en el centro de la pantalla. Esto garantiza que el mouse parece estar siempre en el medio para el usuario y que aún puede recibir valores de movimiento y similares.
fuente