Búsqueda de Rutas Basada en Cuadrículas
En este tutorial haremos una simulación de búsqueda de caminos basada en una cuadrícula de matriz bidimensional. Esto nos dará la idea básica para crear actividades de búsqueda de caminos en nuestros juegos. Visualizaremos la cuadrícula utilizando objetos cuadrados vacíos como mosaicos y un objeto redondo como nuestro avatar que puede moverse en esa área de la cuadrícula con nuestro comando.
I. Configuración de los objetos
Solo usaremos cuatro objetos en nuestro proyecto. Nuestro avatar verde, un mosaico azul, una barricada blanca y la etiqueta de la cuadrícula para configurar y visualizar nuestra cuadrícula.
Avatar
Nuestro avatar es un objeto vacío que tiene una escala de x e y del 50%. Establece su colisión en una forma redonda para que se vea como el de la imagen a continuación. Este objeto tendrá tres atributos predefinidos: en mosaico, mosaico anterior y mosaico objetivo. Establece los valores predeterminados de estos atributos en cero para que no tengan un valor nulo cuando intentemos recuperarlos más adelante.
Objeto Mosaico
Crea otro objeto vacío que se usará para visualizar los mosaicos en nuestra cuadrícula. Su escala también es del 50% y tiene solo un atributo predefinido: en mosaico. Establece también este valor en cero.
Objeto Barricada
Crea otro objeto vacío que servirá como barricadas en nuestra cuadrícula. Este es un objeto vacío blanco con una escala del 40%. Nuestro avatar no podrá atravesar un mosaico que tenga una barricada encima de él.
Etiqueta de cuadrícula
Esta es solo una etiqueta que tendrá los comportamientos que permitirán la configuración y visualización de nuestra cuadrícula. Tiene atributos predefinidos: inicio x con un valor de 4, y inicio y con un valor de 3. Estos valores son desplazamientos que se usarán como referencias cuando generemos nuestros mosaicos para posicionar nuestra cuadrícula ordenadamente en el centro.
Atributos predefinidos de Avatar/Mosaico:
Definimos un mosaico aquí como un arreglo de 2 tamaños que tendrá un valor de x e y basado en nuestra cuadrícula.
- en mosaico - este es el valor del mosaico en el que nuestro objeto está actualmente en nuestra cuadrícula
- mosaico anterior - un mosaico que fue previamente atravesado por nuestro avatar
- mosaico objetivo - el mosaico al que nuestro avatar irá
II. Configuración de la cuadrícula
Dentro de la etiqueta de la cuadrícula es donde definiremos nuestro arreglo 2D y la generación de nuestra cuadrícula. Hay 2 puntos clave en este objeto: establecer el arreglo y visualizar el arreglo. Primero hagamos el paquete de establecer el arreglo.
Establecer el arreglo - paquete
Primero hay que crear un arreglo vacío llamado 'Grid'. Este arreglo contendrá nuestro arreglo bidimensional. Tendremos un contenedor de cajas llamado 'x row count' que tiene un valor de 24 y otro arreglo vacío llamado 'y row' que tiene 18 valores vacíos.
El primer comportamiento en nuestro paquete es un bucle con un número de repeticiones de 'x row count'. Por cada paso de este bucle, agregaremos un y row vacío al 'Grid array'. Esto creará un arreglo dentro de un arreglo con una dimensión de 24x18.
Observa que hemos conectado un comentario inactivo al inicio de nuestro paquete para negar la ejecución automática de este comportamiento raíz. Un comportamiento raíz es un comportamiento que no se activa en base a ningún evento y se coloca abiertamente en la interfaz.
Visualizar la cuadrícula - paquete
Lo principal que haremos aquí es recorrer cada valor de nuestro 'Grid array' y generar un objeto de mosaico. También agregaremos una condición en nuestro bucle que permitirá la generación de una barricada blanca sobre el objeto de mosaico.
Primero hay que obtener el conteo del arreglo de nuestro 'y row array', el valor del atributo 'start x' de este objeto y el 'start y'.
Crea un bucle que tiene una repetición de 'x row count' y para cada paso de este bucle, agregaremos el valor del índice de ese bucle y el valor del atributo 'start x'. Esto resulta en una posición x absoluta que usaremos para posicionar nuestros mosaicos generados más adelante. El siguiente es el bucle 'y row' que tiene una repetición de 'y row count'. Por cada paso de este bucle, agregaremos el valor del índice de ese bucle y el valor del atributo 'start y', lo que resultará en la posición y absoluta.
Después de agregar los valores bajo el bucle 'y row', hay que generar el objeto azul. Establece el número de objetos vivos en 999 porque necesitaremos muchos de ellos para nuestra cuadrícula, y también con una duración de 0. Luego mueve ese objeto generado a un punto x con un valor del bucle x 'agregar valores', y el punto y del valor del bucle y 'agregar valores'.
El siguiente paso es agregar un arreglo con 2 valores vacíos llamado 'On tile' que solo usaremos como marcador de posición de arreglo. Después de mover el objeto de mosaico, hay que modificar el arreglo 'On tile' reemplazando su valor en el índice 0 con el valor del bucle 'x row loop'. Luego agrega otra modificación de arreglo que reemplaza el valor en el índice 1 con el índice 'y row loop'. Estas son las coordenadas x e y de nuestra cuadrícula que el objeto tendrá como atributo 'on tile'.
Ahora, establece el atributo del objeto generado con una clave dinámica, 'on tile', y con un valor de 'On tile - array'.
Aún bajo el bucle y row, está la condición de generar el objeto blanco de barricada. Tendremos una probabilidad de 2 de 5 de ejecutar este paquete que sumará a la aleatoriedad de nuestra cuadrícula. Luego marcaremos un valor de 1 en las coordenadas x e y de eso en nuestro 'Grid' array que nos dice que esa coordenada tiene una barricada generada.
Primero hay que tener un número aleatorio de 1 a 5. Si ese número es menor o igual a 2, generaremos la barricada. Establece su # de objetos vivos en 999 y mueve ese objeto al mismo punto que el mosaico azul que generamos antes, y también con una duración de 0.
A continuación, guarda la información de que esta coordenada fue ocupada por una barricada, si fue generada. Haremos esto marcando esa coordenada con un valor de 1. Primero hay que obtener el valor en el índice 'x row loop' del 'Grid' array. Este valor nos dará un arreglo de un 'y row'. Modificaremos este 'y row' reemplazando su valor en el índice 'y row loop' con el valor 1, que es el valor marcado. Debido a que esta modificación de valor solo se aplica a ese valor y no al 'Grid' en sí, aún debemos modificar el 'Grid' array. Reemplaza el valor en el índice 'x row loop' del 'Grid' array con el valor de 'modificar y row - array'.
Una vez jugado, debería dar como resultado esta forma.
III. Al presionar el mosaico
Para poder interactuar con la cuadrícula misma, necesitaremos un comportamiento de paquete cada vez que presionemos un mosaico azul. El primer toque resultará en la aparición de nuestro avatar en nuestra cuadrícula, y cualquier toque sucesivo después de ese evento iniciará su búsqueda de caminos.
Dentro del objeto azul hay un paquete de comportamiento que tiene 3 puntos principales: restablecer el mosaico anterior de nuestro avatar, establecer su en mosaico/ establecer su mosaico objetivo, luego establecer una animación de color para visualizar el evento de toque en pantalla.
Primero hay que obtener el atributo 'on tile' del objeto mosaico. Establece el atributo 'previous tile' de nuestro avatar en 0. Nuestro avatar se configurará para evitar regresar a un 'previous tile', por eso restablecemos el 'previous tile' en cada pulsación del mosaico.
A continuación, obtén el atributo 'on tile' de nuestro avatar. La primera condición if es si el valor 'on tile' es igual a cero. Esto significa que si el avatar aún no ha aparecido, entonces esto resultará verdadero. Si es verdadero, entonces estableceremos su atributo 'on tile' con un valor del atributo 'on tile' del objeto mosaico. Luego moveremos la posición de nuestro avatar obteniendo la posición del objeto mosaico, apuntando sus valores x e y a ese punto con una duración de 0.
Si el valor 'on tile' no es igual a cero. estableceremos el atributo 'target tile' de nuestro avatar con el valor del atributo 'on tile' del objeto mosaico. Esto significa que nuestro avatar ya está en nuestra cuadrícula, y luego, podemos ejecutar el paquete de comportamiento, 'encontrar camino'. Aún no tenemos este comportamiento pero lo solucionaremos después de hacer la parte posterior de este tutorial para el paquete de 'encontrar camino'.
Ahora que hemos configurado correctamente nuestro avatar en nuestra cuadrícula, solo tenemos que visualizar este evento de pulsación. Primero hay que tener un comportamiento raíz 'get color' para obtener su color original. Luego, después del evento de pulsación, estableceremos el color del objeto mosaico en negro con una duración de 0, y luego volveremos a establecer su color a su valor original con una duración de 0.2.
Presionar en un mosaico azul debería resultar en esto.
IV. Ejecutar el Paquete Encontrar Camino
Para esta última parte de nuestro tutorial, realizaremos el algoritmo que nos permite encontrar el mosaico más cercano que nuestro avatar puede tomar para alcanzar su destino. Este paquete se ejecutará repetidamente por cada paso de mosaico que nuestro avatar se mueve en nuestra cuadrícula.
Configuraremos el algoritmo dentro de nuestro objeto avatar y tendrá tres puntos principales: encontrar mosaicos adyacentes, encontrar el mosaico adyacente más cercano y moverse a ese mosaico adyacente.
Encontrar los mosaicos adyacentes
En esta parte, recogeremos todos los mosaicos adyacentes a los que nuestro avatar podría trasladarse. Verificaremos sus cuatro mosaicos adyacentes en dirección y si esos mosaicos tienen una barricada encima de ellos o si fueron previamente pisados.
Primero hay que añadir nuestro arreglo 'Mosaicos adyacentes'. Un arreglo 'Dirección' con 2 valores vacíos, y los cuatro arreglos direccionales que tienen 2 valores para cada uno: N (0,1), S (0,-1), E (1,0), W( -1,0).
El primer comportamiento en nuestro paquete es borrar nuestros mosaicos adyacentes. Debido a que repetiremos este paquete, necesitamos restablecer nuestros 'mosaicos adyacentes' recogidos cada vez. Los siguientes cuatro comportamientos son modificaciones al arreglo 'Dirección'. Establecemos el arreglo del arreglo 'Dirección' cuatro veces con los cuatro arreglos direccionales, luego ejecutamos el paquete a continuación. Hacemos esto para crear un bucle con diferentes valores de arreglo 'Dirección' cada vez.
Ahora que tenemos la dirección, solo tenemos que combinar sus valores x e y con el atributo 'on tile' de nuestro avatar. Luego podremos obtener nuestro valor objetivo en el 'Grid' array para saber si ese mosaico estaba marcado con una barricada.
'Dirección x' es el valor de 'Dirección' en el índice 0, 'obtener on tile' el x es el valor de 'obtener on tile' en el índice 0. El objetivo x es la suma de los valores de 'dirección x' y 'obtener on tile x'. Lo mismo va para los valores y pero con un índice objetivo de 1.
'Target y row' es el valor del arreglo 'Grid' en el índice 'Target x'. Y luego, el 'Target index in y row' será el valor del arreglo 'Target y row' en el índice de 'Target y'. Esa es la coordenada en nuestra cuadrícula que podrá decirnos si estaba marcada con una barricada.
Si el valor en el 'Target index in y row' es 1, entonces ese mosaico objetivo fue marcado como bloqueado. Pero si el valor no es igual a 1, podremos continuar en nuestro paquete.
Como nuestro 'Target x' e 'y' pasaron nuestra condición, hemos añadido un nuevo arreglo vacío de mosaico llamado 'Nuevo mosaico adyacente'. Este almacenará los valores de Target x e y como arreglo de mosaico. Estableceremos el valor de Target x en el índice 0 de 'Nuevo mosaico adyacente' y Target y en su índice 1.
Ahora obtenemos el atributo 'previous tile' de nuestro avatar. Si el 'previous tile' no es igual a 'nuevo mosaico adyacente', eso significaría que el nuevo mosaico no fue previamente atravesado. Entonces, podemos agregar de manera segura el 'Nuevo mosaico adyacente' al arreglo 'Mosaicos adyacentes' anexándolo. Estableceremos el valor de 'previous tile' más adelante después de que nuestro avatar se haya movido a otro mosaico.
"Puedes expandir este paquete haciendo arreglos en 8 direcciones que permitan que tu avatar se mueva en direcciones diagonales."
Encontrar el mosaico adyacente más cercano
Ahora que hemos recogido nuestros mosaicos adyacentes confiables, solo necesitamos obtener el mosaico adyacente que esté más cerca del mosaico objetivo de nuestro avatar. Haremos el cálculo utilizando una fórmula de distancia proporcionada por los valores x e y de nuestro mosaico objetivo y los mosaicos adyacentes.
Hay dos puntos clave en este paquete: la inicialización de variables para el cálculo y el cálculo de distancias de mosaico dentro de un bucle.
a. Inicialización de variables
Primero hay que obtener el conteo del arreglo de nuestros mosaicos adyacentes. Luego, obtendremos el atributo 'target tile' de nuestro avatar y obtendremos sus valores x e y. Añadiremos 2 nuevos contenedores de cajas: la 'Min distancia' y el 'Índice mosaico objetivo'. Establecemos el valor inicial de 'Min distancia' en 9999, y el valor de 'Índice mosaico objetivo' en 0. La distancia mínima se establece en un número alto porque necesitamos la distancia más corta desde el inicio. El índice del mosaico objetivo es nuestro índice de referencia en el arreglo 'Mosaicos adyacentes' que tiene la menor distancia a nuestro 'mosaico objetivo'.
Nuestro objetivo principal aquí es obtener el índice del mosaico dentro de nuestro arreglo 'Mosaicos adyacentes' que esté más cerca de nuestro 'mosaico objetivo'.
b. Cálculo de distancias de mosaicos
En este paquete, haremos el cálculo dentro de un bucle que haremos por cada mosaico adyacente. El bucle se repite por 'conteo de mosaicos adyacentes' y obtendremos el valor del mosaico del arreglo 'Mosaicos adyacentes' utilizando el índice de ese bucle.
Obtén los valores x e y de ese mosaico adyacente y luego obtendremos la distancia entre nuestro 'mosaico objetivo' y el 'mosaico adyacente' usando esta fórmula:
distancia = sqrt((x2 - x1)^2+(y2 - y1)^2)
x1 = Target x
x2 = Adyacente x
y1 = Target y
y2 = Adyacente y
Primero restamos sus valores x e y, multiplicamos para obtener sus valores exponenciales, sumamos esos valores y luego sacamos la raíz cuadrada de los valores sumados para obtener el valor de distancia.
Si el valor de 'Distancia' es menor que el valor del contenedor de 'Min distancia', entonces estableceremos el valor del 'índice del mosaico objetivo' al índice actual del bucle, que es el índice de nuestro mosaico recuperado dentro del arreglo 'Mosaicos adyacentes'. También estableceremos el valor del contenedor de 'Min distancia' con el valor de 'Distancia' para compararlo con el siguiente mosaico de nuestro bucle.
Después del final del bucle, hemos comparado cada uno de nuestros mosaicos adyacentes y hemos obtenido el valor del índice del mosaico adyacente que está más cerca de nuestro 'mosaico objetivo'.
Movimiento al mosaico adyacente
En este último paquete de nuestro tutorial, moveremos nuestro avatar al mosaico adyacente más cercano y rehaceremos todo el paquete 'Encontrar Camino' si no nos hemos movido ya a nuestro 'mosaico objetivo'.
Lo primero es comprobar si nuestro 'conteo de mosaicos adyacentes' es mayor que 0. Esto es para asegurarnos de que solo nos moveremos si hemos recuperado al menos un mosaico adyacente confiable.
Luego obtenemos el 'mosaico más cercano' usando el valor de nuestro 'índice de mosaico objetivo' del paquete anterior para obtener el valor del arreglo de 'Mosaicos adyacentes'.
Para obtener el punto exacto al que se moverá nuestro avatar, necesitaremos los valores de mosaico x e y de ese mosaico, y también obtener los valores de atributo 'start x' y 'start y' de nuestra etiqueta de 'Grid'. Luego sumamos el valor x de nuestro 'mosaico más cercano' y el valor 'start x', y también lo mismo con los valores y. Estos valores sumados son nuestros puntos objetivos x e y a donde nuestro avatar se moverá.
Antes de movernos a ese punto, establecemos el 'mosaico anterior' de nuestro avatar con su valor actual de atributo 'on tile'. Podemos obtener este valor 'on tile' de los paquetes anteriores. Luego movemos a nuestro avatar a nuestros puntos objetivo, con una duración de 0.2.
Después de que se complete el comportamiento 'Mover a punto', ahora establecemos el valor del atributo 'on tile' de nuestro avatar con el valor del arreglo 'Obtener mosaico más cercano'. Si el valor del arreglo 'Obtener mosaico más cercano' no es igual a nuestro 'mosaico objetivo', entonces ejecutaremos el paquete 'Encontrar Camino', redoing así todo el paquete otra vez. El valor del atributo 'mosaico objetivo' se puede obtener del paquete anterior.
Al presionar en cualquier mosaico azul, y después de la aparición de nuestro avatar en la cuadrícula, se ejecutará el paquete 'Encontrar Camino'. Esto activará el movimiento del avatar de mosaico a mosaico.
Conclusión
En este tutorial, hemos aprendido a realizar una actividad de búsqueda de caminos de objetos usando un arreglo que llamamos 'Cuadrícula', que se usa para almacenar información sobre si ese mosaico estaba ocupado o no. Puedes expandir esta idea, utilizando identificadores de objetos como almacenamiento de información en lugar de solo un número de dígito para nuestro arreglo 'Grid'. Esto nos dará información más confiable que podemos usar al realizar la búsqueda de caminos. Por ejemplo, podemos obtener los atributos de ese identificador de objeto para saber si está vivo o no, ya sea que nos permita pisar su mosaico o no.
Este tutorial solo sirvió para dar la idea básica de la búsqueda de caminos. Una desventaja de esto es que no crea el camino más corto posible a un mosaico objetivo, y solo verifica su mosaico adyacente actual. Esto puede resultar en un bucle de movimiento que no llega a ninguna parte.
Sin embargo, esto se puede resolver ampliando nuestro algoritmo de búsqueda de caminos. Podemos hacer esto reiterando sobre nuestro mosaico adyacente recuperado para obtener también sus mosaicos adyacentes hasta que encontramos nuestro mosaico objetivo. Cada mosaico adyacente encontrado se agregará a una lista. Para evitar un bucle infinito, agrega una condición que si ese mosaico adyacente ya fue verificado, ese mosaico no se agregará a nuestra lista. Además, añade un límite máximo en el conteo de iteraciones para prevenir un bucle infinito que es causado por el mosaico objetivo si está demasiado lejos o no se puede encontrar. Una vez que esa iteración encuentra el mosaico objetivo, entonces salimos de esa iteración y comenzamos a mover el avatar de mosaico a mosaico usando la lista de mosaicos.

