Posicionamiento de indicadores en pantalla para apuntar a objetivos fuera de pantalla

En los juegos de desplazamiento en 2D (y algunos juegos en 3D), a menudo tendrás que mostrarle al jugador la ubicación de un objetivo que está fuera de la pantalla, ya sea un enemigo, un aliado o un objetivo del juego. Muchos juegos usan una flecha que flota cerca del borde de la pantalla para indicar en qué dirección se encuentra el objetivo. En este tutorial, explicaré un método que usa un álgebra simple para encontrar dónde colocar esa flecha indicadora.


Formulario de intercepción de pendiente


La forma de intercepción de pendiente es una forma de describir una línea recta en 2D con álgebra lineal. Utiliza un cuesta abajo, que normalmente utiliza el símbolo metro, que define la inclinación de la línea, y una compensar o interceptar, que usa el simbolo segundo, que define donde la linea cruza el eje y.

\ [y = mx + b \]

Gracias a esta relación, si tenemos un valor podemos usar la ecuación general para calcular fácilmente el otro valor, tanto conceptual como matemáticamente.

Ya que estamos encontrando la posición relativa a la pantalla, una superficie plana, hacemos todos los cálculos en 2D, incluso si el juego está en 3D..

Propina: Si está trabajando en 3D, deberá transformar la ubicación mundial en la ubicación de la pantalla de su objeto 3D. La mayoría de los motores principales han incorporado funciones para hacer esto; Consulta la documentación de tu motor para más..

Si podemos encontrar una línea en la pantalla que describa en qué dirección está el objeto al que nos dirigimos, podemos determinar el punto donde cruza un borde determinado y luego usar un poco de prueba y error para descubrir de qué lado de la pantalla estará adjunto a.


Haciendo suposiciones


Si imaginamos que nuestra pantalla está en una cuadrícula, y que el punto de origen (0, 0) está justo en el centro de la pantalla, entonces es fácil calcular los valores que describen la línea.

Como la línea atravesará el centro, sabemos que nuestra intersección, segundo, debe ser cero Y si la rejilla se coloca así, podemos calcular la pendiente muy fácilmente., metro: es simplemente el objetivo y/X. (En la imagen de arriba, nuestro objetivo es el cursor del mouse).

Una vez que tengamos la pendiente, podemos usar la sustitución para calcular dónde la línea cruzaría los bordes de la pantalla. Por ejemplo, si queremos encontrar cuál es el valor de y en el punto donde la línea cruza el borde de la pantalla, entonces usamos la forma original y = mx, dónde X Se establece en el borde de la pantalla. Si quisiéramos encontrar dónde cruza la parte superior o inferior de la pantalla, dividimos ambos lados por metro para que la ecuación se convierta en: x = y / m - entonces nos limitamos a establecer y hasta el borde de la pantalla.

Mientras la cuadrícula se coloca de esta manera, el borde de la pantalla sería la mitad del ancho de la pantalla, negativo para la izquierda y positivo para la derecha. Para el eje vertical, de manera similar, el borde de la pantalla está a la mitad de su altura, pero si el aumento es positivo o negativo puede variar entre los motores.

Por lo tanto, un juego de 800x600px tendrá sus bordes de pantalla en x = -400px, x = + 400px, y = -300px, y y = + 300px.


Espacio de coordenadas

Lo anterior estaría bien si el origen del sistema de coordenadas fuera el centro de la pantalla, pero rara vez es así. La mayoría de los motores tienen el origen en la esquina superior izquierda o inferior izquierda.

Antes de realizar nuestros cálculos, debemos cambiar nuestro espacio de coordenadas para que todos nuestros valores sean relativos al centro de la pantalla, en lugar del origen predeterminado que utiliza nuestro motor..

Espacio de coordenadas cambiantes. Puntos no a escala.

¿Suena complejo? Realmente no. Solo necesitamos descubrir cuánto queremos mover el espacio de coordenadas y restarlo de nuestra posición objetivo. Entonces, si queremos mover nuestra cuadrícula a la mitad del ancho de la pantalla, restamos la mitad del ancho de la pantalla del objetivo. y valor.


Aquí hay uno que preparé antes

En el ejemplo anterior, el tamaño de la pantalla es 800x600px, con el espacio de coordenadas desplazado de manera que (0, 0) Está en el centro del monitor. El objetivo fuera de pantalla está en (800, 400) usando el mismo espacio de coordenadas.

Como la coordenada y del objetivo es positiva (y, en este motor, el eje y apunta hacia arriba), sabemos que no estará en el borde inferior de la pantalla, por lo que inicialmente encontramos su posición en el borde superior de la pantalla. , cual es (600, 300).

Podemos decir matemáticamente que este punto todavía está fuera de la pantalla porque su coordenada x (600) es mayor que la mitad del ancho (800/2 = 400), entonces nos movemos para encontrar su posición en el lado de la pantalla.

De nuevo, solo tenemos que marcar un lado de la pantalla, porque si nuestra coordenada x es positiva, entonces el punto debe estar en el lado derecho de la pantalla. (Si fuera negativo, tendría que estar en el lado izquierdo).

Una vez encontremos el punto en el lado derecho de la pantalla. - (400, 200) - lo sabemos debe Sea correcto, ya que hemos descartado todos los lados de la pantalla a través de un proceso de eliminación..


Añadir una pequeña pizca de trigonometría

Además de posicionar el indicador, es posible que desee girarlo también para obtener un efecto adicional, especialmente si es una flecha. Hay una función práctica que forma parte de la mayoría de las clases de matemáticas que resuelven este problema con bastante facilidad: atan2 ().

los atan2 () La función toma dos parámetros: una coordenada x y una coordenada y. Devuelve un ángulo que indica la dirección desde (0, 0) a (x, y).

 rotación = Math.atan2 (centerMouse.top, centerMouse.left); rotación = rotación * 180 / Math.PI; // convertir radianes a grados

Hay un par de cosas a tener en cuenta con atan2 () Eso puede variar entre lenguajes y motores. En primer lugar, los argumentos son a menudo atan2 (y, x), mientras que la mayoría de las otras funciones matemáticas toman la coordenada x primero. Además, la rotación a menudo se devuelve en radianes en lugar de grados..

Propina: No voy a entrar en las diferencias entre radianes y grados, excepto para decir que la conversión de uno a otro es fácil: simplemente multiplicas los radianes por (180 / Pi) para convertirlos en grados, y multiplicarlos por (Pi / 180) si quieres volver a cambiarlos.


Últimos cheques

Hay una última cosa que debemos comprobar antes de hacer un indicador de apagado de pantalla, y es si nuestro objetivo está realmente fuera de pantalla, ya que no tiene mucho sentido apuntar en la dirección de nuestro objetivo si ya podemos ver nuestro objetivo. Una vez más, vamos a usar matemática bastante simple para resolver esto.

Ya que nuestra pantalla es un rectángulo sin rotar, no necesitamos hacer nada con ángulos, solo tenemos que verificar si nuestro punto de destino es más bajo que el de arriba, más alto que el de abajo, a la izquierda del borde derecho., y A la derecha del borde izquierdo de la pantalla..

pantalla var = ancho: 200; altura: 100 // alerta de valores ficticios (isTargetOnScreen (left: 50; top: 60)); // Alerta verdadera (isTargetOnScreen (left: 250; top: 10)); // La función falsa isTargetOnScreen (target) if (target.top> 0 && target.top < screen.height && target.left < screen.width && target.left > 0) // el objetivo está en pantalla, usa una superposición o no hace nada. devuelve verdadero  else // el objetivo está fuera de la pantalla, busque la posición del indicador. falso retorno; 

Usando los valores ficticios anteriores, encontramos que el objetivo está en pantalla. Estos valores pueden provenir de cualquier lugar que almacene información sobre el objeto que está siguiendo.

Tenga en cuenta que el código anterior asume que estamos en el espacio de coordenadas donde (0, 0) está en el esquina de la pantalla, como la mayoría de los motores tendrán por defecto. Por lo tanto, este paso se debe realizar antes de desplazar el espacio de coordenadas al centro como lo hacemos al calcular la posición del indicador.


Poniendolo todo junto

Aquí hay una demostración rápida para mostrar estos conceptos en acción (vea el código en GitHub):

Veamos el código:

  • En primer lugar, verificamos si el objetivo está realmente fuera de la pantalla; Si está en pantalla, ya sabemos dónde colocar el cursor, si queremos hacerlo..
  • Cambiamos el espacio de coordenadas para que el origen esté en el centro de la pantalla..
  • Si observamos la posición del mouse, podemos saber fácilmente si está en la mitad superior o inferior de la pantalla..
  • Usando esa información y la sustitución algebraica, calculamos dónde estaría ese punto en la parte superior o inferior de la pantalla.
  • Miramos el punto que acabamos de calcular y verificamos si es realmente una posición en la pantalla, o si está demasiado lejos a la izquierda o la derecha.
  • Si el punto está fuera de la pantalla, calculamos un nuevo punto en el lado de la pantalla, en lugar de la parte superior o inferior.
  • Ahora deberíamos tener el punto correcto en el espacio de coordenadas incorrecto, por lo que hacemos lo contrario de lo que hicimos en el primer paso para devolverlo al sistema de coordenadas correcto.

Conclusión

Ahí lo tiene: un útil fragmento de código para agregar a la interfaz de usuario de su juego. Ahora que puede apuntar al jugador en la dirección de un objetivo, considere cómo puede mostrar la distancia también.