Pregunta

Quiero tener un juego donde la vista se mueva a medida que el mouse llegue al borde exterior de la ventana (similar a muchos juegos de estrategia en tiempo real). He leído que hay una sobrecarga significativa al usar MouseMotionListener.

¿Hay alguna forma de tener un segundo componente transparente dentro de la ventana del juego (JPanel) que no afecte el juego, pero se registre cuando el mouse abandone el componente interno a través de MouseAdapter.mouseEntered () / mouseExited ()?

boolean mouseOnScreen;
boolean mouseWithinInnerComponent; //is (10 <= mouse.x <= screenWidth - 10) && (10 <= mouse.y <= screenHeight)

if(mouseOnScreen && !mouseWithinInnerComponent)
{
    //do something...
}

No sé cómo determinar qué límite de pantalla se cruzó sin tener que superponer cuatro de los componentes mencionados anteriormente en las esquinas para formar un borde alrededor de la pantalla que pueda detectar si el mouse está en cualquier borde o esquina . Esto imagino que es bastante costoso (tener que verificar cada componente mientras se ejecuta el juego) ...

boolean mouseOnScreen;
boolean mouseWithinTopComponent; //is (0 <= mouse.y <= 10)
boolean mouseWithinBottomComponent; //is (screenHeight - 10 <= mouse.y <= screenHeight)
boolean mouseWithinLeftComponent; //is (0 <= mouse.x <= 10)
boolean mouseWithinRightComponent; //is (screenWidth - 10 <= mouse.x <= screenWidth)

if(mouseOnScreen)
{
    if(!mouseWithinBottomComponent)
    {
        //move view up
    }
    if(!mouseWithinTopComponent)
    {
        //move view down
    }
    if(!mouseWithinLeftComponent)
    {
        //move view right
    }
    if(!mouseWithinRightComponent)
    {
        //move view left
    }
}

¿Cuántos gastos generales existen con MouseMotionListener? ¿Sería este o un método similar más eficiente si las detecciones solo necesitan hacerse a lo largo de los bordes de una ventana de juego?

NOTA: Esto se usará en modo ventana así como en la posible aplicación de pantalla completa.

¿Fue útil?

Solución

He implementado lo mismo que necesitas usando un MouseMotionListener . No estoy realmente seguro de por qué cree que agregará gastos generales ... Si agrega uno y simplemente le pide a cada uno de sus métodos que imprima en la consola (que es lento) y mueve el mouse, verá que es bastante ágil desde el punto de vista del usuario.

Mi implementación consta de 4 piezas principales: un panel de desplazamiento, regiones rectangulares, un temporizador y un MouseMotionListener .

Primero, creé un panel, llamado AutoScrollPane , que extiende JScollPane . Aunque es un JScrollPane , puede ocultar las barras de desplazamiento. Esto me permite aprovechar la funcionalidad para mover una ventana gráfica en un mapa o similar como en un juego de estrategia en tiempo real como usted dice.

Segundo, para las regiones de desplazamiento, en realidad tengo 8: n, ne, e, se, s, sw, w y nw (es decir, norte, noreste, etc.), con las diagonales permitiendo desplazamiento diagonal Los implemento simplemente como Rectangle s. No se dibujan en la pantalla ni nada: solo instancia 8 rectángulos en mi clase del tamaño apropiado y con coordenadas que coinciden con las regiones de la ventana. De hecho, permito cambiar el tamaño de mi ventana, así que cambio el tamaño de los rectángulos si es necesario.

Tercero, tengo un temporizador que se puede encender y apagar. Cuando está activado, cada "tic" genera un Runnable . El trabajo de Runnable's es desplazar la ventana del panel en la dirección apropiada una cierta distancia. Cada Runnable se entrega a la cola de eventos Swing.

Finalmente, tengo un MouseMotionListener . Su trabajo es interceptar el mouse para ingresar, salir y mover eventos. Cada vez que recibe un evento, verifica la ubicación actual del mouse y si se cruza con uno de los rectángulos. Según el rectángulo, elige una dirección para desplazarse. Realiza un seguimiento de si el mouse estaba en una región de desplazamiento en el evento anterior o no. Con base en esta información, sabe si debe comenzar a desplazarse, detener el desplazamiento o simplemente dejar que lo que esté sucediendo continúe. Quería que mi desplazamiento se detuviera si el mouse sale del panel, por lo tanto, el uso de los eventos de salida / entrada. De todos modos, para comenzar a desplazarse, el oyente guarda la dirección y la distancia para desplazarse y le dice al temporizador que comience. Cuando es hora de detener el desplazamiento (como cuando el mouse sale de una región de desplazamiento), le dice al temporizador que se detenga.

Me tomó un tiempo elegir la granularidad del temporizador y la distancia de desplazamiento correctas para un desplazamiento suave, pero funciona bastante bien. Espero que este resumen proporcione alguna ayuda.

Otros consejos

Creo que fue Martin Fowler quien propuso que la optimización prematura es la raíz de todo mal en el desarrollo de software. ¿Por qué no pruebas MouseMotionListener y solo piensas en optimizar si encuentras que afecta el rendimiento del juego?

No hay nada de malo con un MouseMotionListener Cuando lees sobre los gastos generales, probablemente fue un ejemplo específico

Cualquier cosa que pueda hacer en cualquier lenguaje de programación puede hacerse mal o mal.

Si prestas atención a lo que haces en tu oyente, todo debería estar bien

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top