Unity, editores y matemáticas Parte 2.

¡Volvemos para resolver los dilemas que nos quedaron en la parte uno sobre nuestro editor de niveles!

Si no has leído la primera parte, te recomiendo que lo hagas porque sino va a ser muy difícil entender esta entrada.

Nos quedamos en que queremos aumentar el tamaño del mapa.

Si el grid está vació esto es muy fácil, simplemente borramos el que ya tenemos y creamos uno nuevo pero más grande. El problemas se produce cuando tenemos colocados tiles ya en el mapa.

El tile guarda el id de la celda en la que está “apoyado”. Al aumentar el tamaño del mapa, el id de la celda en la que está el tile puede cambiar.

En el post anterior vimos que para aumentar el tamaño del mapa solo teníamos que cambiar los id de las celdas que están más arriba de la fila central. Todos los otros id se mantienen.

Imagen del editor donde se ve que id son iguales en el editor de Unity

 

En la imagen anterior, el mapa de la izquierda de tamaño 5 tiene una celda con id 16. Esta misma celda pasará a tener id 17 al aumentar de tamaño.

Entonces: somos un programa que aumenta el tamaño del mapa. Recibimos un id, digamos el 16 y tenemos que convertirlo para que se adapte un mapa de tamaño +1 del actual (es decir, si nuestro mapa es de tamaño 5, hay que convertirlo para que sea de tamaño 6)

Lo primero que hay que hacer es verificar si es necesario cambiar el id del tile, porque recordar que solo cambian de id las celdas que están más arriba de la fila central.

Si tuviéramos el número de fila en la que se encuentra el tile podríamos saber si está por debajo o por encima de la línea, pero no la tenemos 🙁

Lo que podemos intentar es conseguir el id de la última celda en la fila, ya que los ids son ascendentes, sabemos que a partir de ese id tenemos que cambiar los ids. En el caso anterior son todos los id a partir del 14.

Recordar que tenemos que conseguir este valor solo con el tamaño del mapa, en este caso 5. Vamos a ello.

Si dividimos el grid por la línea central en dos partes, podemos observar que nos quedan dos triángulos. Uno inferior que contiene este último id que queremos averiguar en uno de sus vértices y uno superior con todos los ids que tenemos que cambiar. En la siguiente imagen se puede ver esta división:

Esto nos da un triángulo equilátero invertido. Si podemos contar todos las celdas que forman este triángulo, podríamos obtener el id que queremos. Este triángulo tiene 15 celdas y el id que necesitamos en este caso es 14, es decir, 15 – 1. Esto se cumple para todos los casos.

Lo que nos deja que:

El id o valor que indica si necesitamos cambiar un id es:

Número de celdas de triángulo inferior – 1

Resulta que existe una forma de contar objetos que formar un triángulo equilátero conocida como número triangular.

Dado un número que corresponde al tamaño de la base del triángulo, podemos calcular su número triangular, que corresponde a la cantidad de puntos/celdas que contiene.

Por ejemplo, el número triangular de 4 es 10. Y el número triangular de 5 es 15.

La fórmula para el número triangular es:

Si os fijáis en nuestro mapa, el número de celdas que quedan como “base” para nuestro triángulo invertido corresponde ¡al tamaño del mapa!

Con esta formula podemos obtener la cantidad de celdas que tenemos en el triángulo invertido, lo que nos permite saber el valor del id de la última celda en la fila.

idDeEsquina = obtenerNumeroTriangular(tamano) 1

En nuestro caso que queremos cambiar el valor del id 16 de un tamaño de mapa 5 a 6:

idDeEsquina = 15 – 1 = 14

Como 16 es mayor a 14. Tenemos que cambiar su valor para agrandar el mapa.

—————

Perfecto, ya sabemos si el id que recibimos tenemos que cambiarlo o no. ¿Pero qué pasa cuando hay que cambiarlo?

Recordar que solo tenemos que cambiar los id del triángulo equilátero superior.

 

Después de una dura búsqueda patrones y soluciones, nos dimos cuenta de que podríamos obtener los nuevos id sumando un valor específico por cada fila.

 

A medida que nos alejamos de la fila central el valor aumenta. En la fila siguiente a la central hay que sumar 1, en la siguiente 2, en la siguiente 5… La fórmula que obtuvimos fue:

nuevoID = viejoID + (numeroFila * 2) 1

Tener en cuenta que este número de fila que estamos utilizando es el número de fila con respecto al triángulo superior. Donde la base es la fila una y se va aumentando sucesivamente:

Volviendo al caso práctico: somos el programa, recibimos el id 16 y sabemos que hay que cambiarlo. Sabiendo la fila en la que está, (lo cual no es un dato que tenemos) podremos saber cuanto hay que aumentarle para darle su nuevo id. Tenemos que calcular la fila en la que se encuentra un id, dado el tamaño del mapa.

Con lo que ya sabemos de números triangular, podemos tratar el triángulo superior obtenido como si fuera una representación de un número triangular. Además podemos darle valores a la representación triangular de un número de la misma manera que nosotros asignamos id (de izquierda a derecha y de arriba abajo).

Como sabemos el id de la última celda de la fila central, podemos utilizarlo para buscar la correspondencia entre el número de id que queremos cambiar (el 16) y esta representación:

Obtenemos que queremos saber en que fila está el número 2 (16 – 14). Para lograr esto podemos comparar si es mayor o igual que el primero de su fila y es menor o igual al último de su fila. En este caso 1 y 4.

La forma que encontramos para obtener cual es el primero y último de una fila es comparando desde la cúspide del triángulo (número triangular de la base) e iterar hacía abajo hasta encontrar el número. Explico. (Recordar que todo esto lo hacemos para obtener la fila y poder sumarle el valor correspondiente al id)

Si queremos buscar el 2 y sabemos que el triángulo tiene de base 4, podemos calcular su número triangular y empezar a comparar desde ahí.

El número triangular de 4 es 10. Como es la cúspide, el primero de la fila y el último de la fila es el 10. Solo hay un punto en esta fila.

Como el número que buscamos no es 10, seguimos bajando a la siguiente fila.

Ahora, el último número de la fila actual (no sabemos cual es) será el primero de la fila anterior (10) menos 1. En este caso 10 – 1 = 9.

Y el primero de la fila actual (no sabemos cual es) será el último de la fila actual (9, lo acabamos de calcular) menos la cantidad de veces que hayamos bajado de fila (1).

En este caso 9 – 1 = 8.

Cada vez que aumentamos seguimos bajando en filas hay más puntos. Con esto podemos calcular el primero de la fila a partir del último de la fila.

Continuando.

Como 2 no está entre 8 y 9, seguimos bajando a la siguiente fila.

Ultimo de la fila = primero fila anterior (8) – 1 = 7

Primero de la fila = 7 – cantidad de veces que se ha bajado de fila (2) = 5

Nuestro número, el 2, no está entre 5 y 7, por lo que hay que bajar a la siguiente fila.

Ultimo de la fila = primero fila anterior (5) – 1 = 4

Primero de la fila = 4 – cantidad de veces que se ha bajado de fila (3) = 1

El número 2 que buscábamos está en está fila.

Sabemos que las filas totales del triángulo es igual al tamaño de la base del triángulo, y también sabemos cuantas veces hemos cambiado de fila empezando desde arriba. Por lo que, la fila a la que pertenece el número 2 es 4 – 3 = 1.

Recordar que todo esto lo queremos para aplicar esta fórmula:

nuevoID = viejoID + (numeroFila * 2) 1

nuevoID = 16 + (1 * 2) – 1 = 17

 

Hemos conseguido calcular el id de una celda cuando aumentamos el tamaño del mapa. No ha sido nada fácil, pero esto nos ha permitido tener mucha flexibilidad a la hora de crear mapas. Ya no estamos limitados por el tamaño del mapa inicial, que usualmente suele ser erróneo.

La verdad es que sin los conocimientos matemáticas del equipo, esto hubiera sido muy difícil de resolver. He creado esta entrada para mostrar que durante la creación de videojuegos se nos presentan muchos problemas inesperados y que, independientemente de nuestro rol, cualquier conocimiento nos puede ayudar para resolver los problemas que surjan.

Por ahora eso es todo con respecto al tamaño del mapa. También hemos implementado reducción del tamaño pero no vale la pena hacer una entrada solo para eso. Basta con decir que en vez de sumar, hay que restar.

Si os ha gustado hacérnoslo saber. Todavía hay muchas cosas que se pueden explicar, como por ejemplo, desplazar un mapa ya creado a través del grid.