Unlimited WordPress themes, graphics, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Game Development
  2. Game Development
Gamedevelopment

Movimiento de carácter hexagonal utilizando coordenadas axiales

by
Difficulty:IntermediateLength:LongLanguages:

Spanish (Español) translation by Luis Chiabrera (you can also view the original English article)

Final product image
What You'll Be Creating

En la primera parte de la serie, exploramos los diferentes sistemas de coordenadas para juegos hexagonales basados en fichas con la ayuda de un juego hexagonal de Tetris. Una cosa que puede haber notado es que todavía dependemos de las coordenadas de desplazamiento para dibujar el nivel en la pantalla usando la matriz levelData.

También puede ser curioso saber cómo podemos determinar las coordenadas axiales de un mosaico hexagonal a partir de las coordenadas de píxeles en la pantalla. El método utilizado en el tutorial de buscaminas hexagonal se basa en las coordenadas de desplazamiento y no es una solución simple. Una vez que descubramos esto, procederemos a crear soluciones para el movimiento de caracteres hexagonales y la ruta.

1. Conversión de coordenadas entre píxeles y ejes

Esto implicará algunas matemáticas. Usaremos el diseño horizontal para todo el tutorial. Comencemos encontrando una relación muy útil entre el ancho y la altura del hexágono regular. Por favor, consulte la imagen a continuación.

Hexagonal tile its angles lengths are displayed

Considere el hexágono azul regular a la izquierda de la imagen. Ya sabemos que todos los lados son de la misma longitud. Todos los ángulos interiores son 120 grados cada uno. Al conectar cada esquina al centro del hexágono obtendremos seis triángulos, uno de los cuales se muestra con líneas rojas. Este triángulo tiene todos los ángulos internos iguales a 60 grados.

Como la línea roja divide los dos ángulos de las esquinas en el medio, obtenemos 120/2 = 60. El tercer ángulo es 180- (60 + 60) = 60 ya que la suma de todos los ángulos dentro del triángulo debe ser de 180 grados. Por lo tanto, esencialmente, el triángulo es un triángulo equilátero, lo que significa que cada lado del triángulo tiene la misma longitud. Entonces, en el hexágono azul, las dos líneas rojas, la línea verde y cada segmento de línea azul son de la misma longitud. De la imagen, está claro que la línea verde es hexTileHeight / 2.

Continuando con el hexágono de la derecha, podemos ver que como la longitud del lado es igual a hexTileHeight / 2, la altura de la porción triangular superior debe ser hexTileHeight / 4 y la altura de la parte triangular inferior debe ser hexTileHeight / 4, que totales a la altura completa del hexágono, hexTileHeight.

Ahora considere el pequeño triángulo rectángulo en la esquina superior izquierda con un ángulo verde y uno azul. El ángulo azul es de 60 grados ya que es la mitad del ángulo de la esquina, lo que a su vez significa que el ángulo verde es de 30 grados (180- (60 + 90)). Usando esta información, llegamos a una relación entre la altura y el ancho del hexágono regular.

Conversión de coordenadas axiales a píxel

Antes de abordar la conversión, revisemos la imagen del diseño horizontal hexagonal donde hemos resaltado la fila y la columna en las que una de las coordenadas permanece igual.

Horizontal hexagonal layout with rows and columns highlighted where coordinates remain same

Teniendo en cuenta el valor de la pantalla y, podemos ver que cada fila tiene un desplazamiento y de 3 * hexTileHeight / 4, mientras baja en la línea verde, el único valor que cambia es i. Por lo tanto, podemos concluir que el valor del píxel y solo depende de la coordenada axial i.

Donde s es la longitud del lado, que se encontró que es hexTileHeight / 2.

El valor de la pantalla x es un poco más complicado que esto. Al considerar las fichas dentro de una sola fila, cada ficha tiene un desplazamiento x de hexTileWidth, que claramente depende únicamente de la coordenada j axial. Pero cada fila alternativa tiene un desplazamiento adicional de hexTileWidth / 2 dependiendo de la coordenada axial i.

Nuevamente, considerando la línea verde, si imaginamos que era una cuadrícula, entonces la línea habría sido vertical, satisfaciendo la ecuación x = j * hexTileWidth. Como la única coordenada que cambia a lo largo de la línea verde es i, la compensación dependerá de ello. Esto nos lleva a la siguiente ecuación.

Así que aquí los tenemos: las ecuaciones para convertir coordenadas axiales en coordenadas de pantalla. La función de conversión correspondiente es la siguiente.

El código revisado para dibujar la cuadrícula hexagonal es el siguiente.

Convertir píxeles en coordenadas axiales

Invertir esas ecuaciones con la simple sustitución de una variable nos llevará a la pantalla a ecuaciones de conversión axiales.

Aunque las coordenadas axiales requeridas son números enteros, las ecuaciones darán como resultado números de coma flotante. Por lo tanto, tendremos que redondearlos y aplicar algunas correcciones, confiando en nuestra ecuación principal x + y + z = 0. La función de conversión es la siguiente.

Echa un vistazo al elemento interactivo, que utiliza estos métodos para mostrar mosaicos y detectar grifos.

2. Movimiento del personaje

El concepto central del movimiento del personaje en cualquier cuadrícula es similar. Realizamos una encuesta para la entrada del usuario, determinamos la dirección, buscamos la posición resultante, verificamos si la posición resultante cae dentro de una pared en la cuadrícula, sino que movemos el personaje a esa posición. Puede consultar mi tutorial de movimiento de caracteres isométricos para ver esto en acción con respecto a la conversión de coordenadas isométricas.

Las únicas cosas que son diferentes aquí son la conversión de coordenadas y las direcciones del movimiento. Para una cuadrícula hexagonal alineada horizontalmente, hay seis direcciones de movimiento disponibles. Podríamos usar las teclas del teclado A, W, E, D, X y Z para controlar cada dirección. La distribución predeterminada del teclado coincide perfectamente con las instrucciones, y las funciones relacionadas son las siguientes.

Entonces, podemos calcular directamente la nueva posición usando la trigonometría usando Cos 60 y Sine 60. Desde este movementVector, descubrimos la nueva posición resultante y verificamos si cae dentro de una pared en la grilla como se muestra a continuación.

Agregamos el movementVector al vector de posición del héroe para obtener la nueva posición para el centro del sprite del héroe. Luego, encontramos la posición de las cuatro esquinas del sprite héroe y verificamos si están colisionando. Si no hay colisiones, establecemos la nueva posición para el sprite héroe. Veamos eso en acción.

Por lo general, este tipo de movimiento que fluye libremente no está permitido en un juego basado en la cuadrícula. Por lo general, los personajes se mueven de un mosaico a otro, es decir, el centro del mosaico al centro del mosaico, según los comandos o toca. Confío en que puedas descifrar la solución por ti mismo.

3. Pathfinding

Así que aquí estamos en el tema de la búsqueda de caminos, un tema muy aterrador para algunos. En mis tutoriales anteriores, nunca intenté crear nuevas soluciones de identificación de ruta, pero siempre preferí usar soluciones fácilmente disponibles que se prueban en la batalla.

Esta vez, estoy haciendo una excepción y reinventaré la rueda, principalmente porque hay varias mecánicas de juego posibles y ninguna solución en particular sería beneficiosa para todos. Por lo tanto, es útil saber cómo se hace todo para generar sus propias soluciones personalizadas para su mecánica de juego.

El algoritmo más básico que se utiliza para determinar rutas en cuadrículas es el Algoritmo de Dijkstra. Comenzamos en el primer nodo y calculamos los costos involucrados al movernos a todos los nodos vecinos posibles. Cerramos el primer nodo y nos movemos al nodo vecino con el menor costo involucrado. Esto se repite para todos los nodos cerrados hasta que lleguemos al destino. Una variante de esto es el algoritmo A *, donde también usamos una heurística además del costo.

Se usa una heurística para calcular la distancia aproximada desde el nodo actual al nodo de destino. Como realmente no conocemos el camino, este cálculo de distancia siempre es una aproximación. Entonces una mejor heurística siempre dará un mejor camino. Ahora, dicho esto, la mejor solución no necesita ser la que proporcione la mejor ruta, ya que también debemos considerar el uso de recursos y el rendimiento del algoritmo, cuando todos los cálculos deben realizarse en tiempo real o una vez por bucle actualizado.

La heurística más fácil y simple es la distancia heurística de Manhattan o distancia Manhattan. En una grilla 2D, esta es realmente la distancia entre el nodo de inicio y el nodo final en línea recta, o la cantidad de bloques que necesitamos para caminar.

Variante hexagonal de Manhattan

Para nuestra grilla hexagonal, necesitamos encontrar una variante para la heurística de Manhattan para aproximar la distancia. Mientras caminamos sobre las fichas hexagonales, la idea es encontrar la cantidad de fichas que debemos recorrer para llegar al destino. Déjame mostrarte la solución primero. Mueva el mouse sobre el elemento interactivo a continuación para ver qué tan lejos están los otros mosaicos del mosaico debajo del mouse.

En el ejemplo anterior, encontramos el mosaico debajo del mouse y encontramos la distancia de todos los otros mosaicos. La lógica es encontrar la diferencia de i y j coordenadas axiales de ambas fichas primero, digamos di y dj. Encuentra los valores absolutos de estas diferencias, absi y absj, ya que las distancias son siempre positivas.

Observamos que cuando di y dj son positivos y cuando tanto di como dj son negativos, la distancia es absi + absj. Cuando di y dj son signos opuestos, la distancia es el valor más grande entre absi y absj. Esto lleva a la función de cálculo heurístico getHeuristic como a continuación.

Una cosa para notar es que no estamos considerando si el camino es realmente transitable o no; solo asumimos que es manejable y establece el valor de la distancia.

Encontrar el camino hexagonal

Procedamos con la ruta de nuestra grilla hexagonal con el nuevo método heurístico. Como usaremos recursividad, será más fácil de entender una vez que analicemos la lógica central de nuestro enfoque. Cada tesela hexagonal tendrá una distancia heurística y un valor de costo asociado con ella.

  • Tenemos una función recursiva, digamos findPath (tile), que toma en un mosaico hexagonal, que es el mosaico actual. Inicialmente, esta será la ficha de inicio.
  • Si el mosaico es igual a la ficha final, la recursión finaliza y hemos encontrado la ruta. De lo contrario, procedemos con el cálculo.
  • Encontramos todos los vecinos caminables de la baldosa. Recorreremos todas las fichas contiguas y aplicaremos una lógica adicional a cada una de ellas a menos que estén cerradas.
  • Si un vecino no se visitó previamente y no se cerró, encontramos la distancia de la ficha vecina a la ficha final utilizando nuestra heurística. Establecemos el costo de la ficha vecina al costo actual de la ficha + 10. Configuramos el mosaico vecino como visitado. Configuramos la ficha anterior de la ficha vecina como la ficha actual. Hacemos esto también para un vecino previamente visitado si el costo actual de la ficha + 10 es menor que el costo de ese vecino.
  • Calculamos el costo total como la suma del valor de costo de la  ficha vecina y el valor de distancia heurística. Entre todos los vecinos, seleccionamos el vecino que proporciona el costo total más bajo y llamamos a findPath en ese mosaico vecino.
  • Configuramos el mosaico actual para que se cierre para que no se considere más.
  • En algunos casos, no podremos encontrar ningún mosaico que satisfaga las condiciones, y luego cerraremos el mosaico actual, abriremos el mosaico anterior y lo reharemos.

Hay una condición obvia de falla en la lógica cuando más de un mosaico satisface las condiciones. Un mejor algoritmo encontrará todos los caminos diferentes y seleccionará el que tenga la longitud más corta, pero no lo haremos aquí. Compruebe la ruta en acción a continuación.

Para este ejemplo, estoy calculando vecinos de forma diferente que en el ejemplo de Tetris. Al usar coordenadas axiales, las fichas vecinas tienen coordenadas que son más altas o más bajas en un valor de 1.

La función recursiva findPath es la siguiente.

Puede requerir lecturas adicionales y múltiples para comprender adecuadamente lo que está sucediendo, pero créame, vale la pena el esfuerzo. Esta es solo una solución muy básica y podría mejorarse mucho. Para mover el personaje a lo largo de la ruta calculada, puede consultar mi ruta isométrica siguiendo el tutorial.

Marcar el camino se hace usando otra función recursiva simple, paintPath (tile), que se llama primero con el azulejo final. Simplemente marcamos previousNode del mosaico si está presente.

Conclusión

Con la ayuda de los tres tutoriales hexagonales que he compartido, deberías poder comenzar con tu siguiente juego basado en fichas hexagonales.

Tenga en cuenta que hay otros enfoques también, y hay muchas lecturas adicionales por ahí si está preparado para ello. Háganme saber a través de los comentarios si necesita algo más para explorar en relación con los juegos hexagonales basados en fichas.

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.