¿Cómo identifico los clics del mouse versus el mouse down en los juegos?

8

¿Cuál es la forma más común de manejar los clics del mouse en los juegos?

Dado que todo lo que tiene para detectar la entrada del mouse es si un botón está arriba o abajo.

Actualmente solo confío en que el mouse hacia abajo sea un clic, pero este enfoque simple me limita mucho en lo que quiero lograr. Por ejemplo, tengo un código que solo debe ejecutarse una vez con un clic del mouse, pero usar el mouse hacia abajo como clic del mouse puede hacer que el código se ejecute más de una vez, dependiendo de cuánto tiempo se mantenga presionado el botón. ¡Entonces necesito hacerlo con un clic!

Pero, ¿cuál es la mejor manera de manejar un clic? Es un clic cuando el mouse va de arriba hacia abajo o de abajo hacia arriba o es un clic si el botón estuvo presionado por menos de x cuadros / milisegundos y luego, si es así, se considera un mouse hacia abajo y un clic si está abajo para x cuadros / milisegundos o un clic y luego el mouse hacia abajo?

Puedo ver que cada uno de los enfoques puede tener sus usos, pero ¿cuál es el más común en los juegos? ¿Y quizás pregunte más específicamente cuál es el más común en los juegos RTS?

Tristan
fuente
1
Estás en el camino correcto. Agregue algo acerca de que el mouse hacia abajo y el mouse hacia arriba deben estar cerca uno del otro (o dentro de los límites del objeto al que se hizo clic) y ya lo tiene. Hacer clic en un botón, luego arrastrarlo y soltarlo no es un clic del mouse. Pero hacer clic en el botón y soltar cualquier parte del botón es hacer clic con el mouse.
Tim Holt

Respuestas:

12

Estás en el camino correcto al descubrir cuándo el mouse está haciendo la transición de abajo hacia arriba y escribiendo un controlador para eso. Para muchos juegos, es lo suficientemente bueno para tratar un evento mouseUp como un clic.

Dependiendo de su juego, es probable que desee manejar ambos eventos; por ejemplo, en un RTS, es probable que desee incorporar la selección de cuadro de arrastre y la selección de un solo clic. La diferencia está en determinar cuánto tiempo estuvo el mouse en el estado Down antes de liberarlo.

(Sí, básicamente respondiste tu propia pregunta)

Cuenta
fuente
2
Como señalaron otros comentaristas, es probable que también desee comprobar que se apuntó al mismo objetivo en mouseDown y mouseUp cuando se trabaja con un solo clic.
Bill
No estoy muy seguro. Por ejemplo, a los botones de Windows no les importa dónde estaba el mouse con el mouse hacia abajo, siempre que el botón reciba el evento mouse up. Quizás otros sistemas operativos se preocupan más.
John McDonald
@John McD No es tanto un requisito técnico como un requisito de "averiguar lo que su usuario realmente quería hacer clic".
Bill el
1
@John McD. eso no es cierto. Presione el botón del mouse hacia abajo en algún lugar de su escritorio, mueva el cursor al menú Inicio y suéltelo. ¿Aparece el menú Inicio? No es para mi.
Kylotan
@Kylotan, estaría en lo correcto, aunque el "botón" del menú de inicio se comporta de manera diferente a todos los demás botones estándar. Parece que los botones estándar en Windows realmente requieren los eventos de mouse down y mouse up, aunque su mouse puede moverse fuera de los límites del botón en el medio. Minimizar, maximizar y cerrar todo el trabajo de esta manera, así como los botones normales dentro de las aplicaciones. Pero tenga en cuenta que no se produce ninguna acción (excepto con el botón de inicio) hasta que se suelta el botón del mouse, la gente como yo lo notará. Annyway ... Bill tiene razón, todo se reduce a requisitos.
John McDonald
4

No existe el "mejor": los necesita a todos.

Si estoy disparando un arma, no quiero esperar a que se suelte el mouse para activar el efecto de disparo del arma. Y si arrastra un cuadro alrededor de un grupo de unidades, comienza la acción de arrastrar con el mouse hacia abajo.

Por otro lado, si estoy haciendo clic en un elemento de la GUI, entonces quiero esperar el clic completo porque a eso estoy acostumbrado.

Por lo tanto, probablemente debería implementar el mouse hacia abajo, el mouse hacia arriba, el arrastre del mouse (el mouse hacia arriba en un lugar significativamente diferente al mouse hacia abajo) y el clic del mouse (mouse hacia arriba en el mismo lugar que el mouse hacia abajo), y conectarlos a partes de su juego como te parece bien.

Kylotan
fuente
1

La forma en que la mayoría de los sistemas de ventanas lo manejan, así como los juegos en los que he trabajado (y tuve que implementarlos parcialmente) es tener un bit en cada botón que detecta si el mouse ingresó en el estado de abajo del mouse sobre el botón dado. Solo establece el marco en el que el mouse baja y solo se borra cuando se suelta el botón del mouse. Si y solo si se suelta el mouse sobre el botón y se establece el bit, dispare el evento de clic del botón.

(Probablemente también desee una bandera que se establece verdadera cuando se establece el bit y el mouse se mueve sobre su botón, para que pueda cambiar el botón para usar una textura presionada en lugar de la normal).

Este es el esquema básico detrás de la mayoría de los botones. Continúe y encuentre un mensaje de diálogo. Presione el botón de cancelar pero no lo suelte. El botón se presiona mientras el mouse está sobre él y vuelve a la normalidad si el mouse deja de desplazarse sobre él, pero volverá a presionarlo si se mueve nuevamente sobre él. Solo ejecuta su acción si lo sueltas y lo superas. No use un recuento de milisegundos, eso es principalmente para detectar clics dobles dentro de su umbral.

(y si realmente quiere ser elegante, tenga eventos que pueda conectar a cada una de esas transiciones, por ejemplo, MouseOver al entrar y al salir, MouseDown ingresar / salir, MouseUp ingresar / salir, MouseClicked ingresar / salir, etc. )

Alex Ames
fuente
1

Los botones del mouse y las teclas del teclado pueden tener varios eventos diferentes, lo que está disponible depende de su elección de idioma / biblioteca, lo más común:

Tecla abajo, se dispara cuando se presiona un botón.
Tecla arriba, se dispara cuando se suelta un botón.
Tecla retardada hacia abajo, se dispara cuando se presiona un botón y luego se dispara repetidamente en algún intervalo dependiente del sistema hasta que se suelta la tecla.

Además de esto, también puede haber una llamada para saber si una tecla se mantiene presionada o no.

Es importante que sepa exactamente qué herramienta está utilizando, más comúnmente necesitará las dos primeras, si no están disponibles, compílelas a partir de lo que esté disponible.

El método estándar para registrar que se presiona un botón en pantalla usando el mouse es afirmar que se apuntó el mismo botón tanto en el evento hacia abajo como hacia arriba. Sin embargo, para muchos elementos del juego esto puede ser demasiado lento, por lo que para muchas acciones puede ser prudente hacer que sucedan en el evento inactivo.

aaaaaaaaaaaa
fuente
0

XOr puede ser tu amigo en esta situación.

bool oldIsButtonUp = true;

void pollMouse(bool isButtonUp) {
    if ((oldIsButtonUp ^ isButtonUp) && isButtonUp) {
        sendMouseClickEvent();
    }
    oldIsButtonUp = isButtonUp;
}

Esto llamará a sendMouseClickEvent () siempre que el estado del botón del mouse cambie de falso a verdadero.

Asgeir
fuente
44
O bien, a fin de no hacer un programador crear un truthtable en su (ella?) Cabeza: if (!oldIsButtonUp && isButtonUp) {.
deceleratedcaviar
-1

Una versión XNA de este código sería algo así (simplificado solo para detectar el evento de mouse down, para detectar clics dobles necesitará algo más sofisticado);

MouseState previousMouseState; 
protected override void Initialize() 
{ 
    // TODO: Add your initialization logic here 
    //store the current state of the mouse 
    previousMouseState = Mouse.GetState(); 
} 


protected override void Update(GameTime gameTime) 
{ 
    // .. other update code 


    //is there a mouse click? 
    //A mouse click begins if the button goes from a released state 
    //in the previous frame  to a pressed state  
    //in the current frame 
    if (previousMouseState.LeftButton == ButtonState.Released  
        && Mouse.GetState().LeftButton == ButtonState.Pressed) 
    { 
        //do your mouse click response... 

    } 

    //save the current mouse state for the next frame 
    // the current  
    previousMouseState = Mouse.GetState(); 

    base.Update(gameTime); 
} 
Conocer
fuente
Además de esto, hay un código para MouseUp, no MouseClick: ¿con qué frecuencia se realiza la actualización? ¿Qué pasaría si un clic es más corto que el tiempo de juego?
Kromster
depende del juego, pero en XNA la actualización ocurre aproximadamente 60 fps por defecto. Sería muy difícil presionar Y soltar un botón del mouse en este período de tiempo.
Ken
En realidad, es un código para detectar un evento de mouse down.
Ken
No puedo ver una respuesta real a la pregunta real en este ejemplo de código XNA abstracto
Kromster
Sin embargo, gracias por las correcciones, hice una pequeña prueba y, de hecho, Click toma 16-100 ms, que es un poco más que la duración de la actualización. Aún así, no recomendaría que la entrada de procesamiento en un bucle de actualización para el paso de tiempo pueda ser inferior a 60 fps, especialmente sin las entradas en cola.
Kromster