¿El mejor algorithm de determinación de ruta para un juego de defensa de la torre?

¿Qué sugieres que sea el mejor algorithm para un juego de defensa de la torre? Es un juego de fichas en 2D, donde las panetworkinges y las torres bloquean el path, entre los puntos de spawn y sus puntos de destino.

Constantemente, a medida que el jugador coloca una nueva torre para bloquear el path, o para ayudar a disparar a las unidades de desove antes de que lleguen a su destino, será necesario recalcular una nueva ruta para la ruta del punto de desove afectado, y las unidades deben networkingirigirse a esa nuevo path.

Por lo tanto, necesito performance.

Probé el algorithm A *, pero cada vez que el jugador coloca una nueva torre y el path tiene que ser recalculado, las unidades existentes que aún no han pasado la torre se pierden y se quedan quietas, ya que formaban parte del antiguo path que ahora ha perdido su información de ruta.

A * debe ser lo suficientemente rápido. Cada vez que se coloca una torre, debe calcular una nueva ruta para cada punto de generación, y asignar esa ruta a cada unidad que se genere allí. También debe calcular una nueva ruta para las unidades "en el campo". Las unidades en el campo pueden tener sus routes calculadas como la ruta más corta para volver a la pista, como en una ruta a la nueva ruta. O las unidades pueden tener su ruta calculada desde su position actual hasta el destino.

Es probable que pueda save cálculos agrupando unidades en el campo y calcular una ruta común para todas ellas. Por ejemplo, si tiene un grupo de unidades en mosaico (4,7), todas pueden usar la misma ruta, por lo que solo tiene que calcularlo una vez.

Además (dependiendo de cuáles sean sus reglas), debería considerar realizar estos cálculos como un control antes de colocar la torre. Esto impedirá que el jugador coloque torres que bloqueen todas las routes. O como algunos juegos de defensa de la torre funcionan, si el juego bloquea todos los paths, las unidades simplemente ignoran las torres cuando encuentran el path.

Responder:

En lugar de calcular un path de un punto a otro, puede calcular la dirección del movimiento para cada azulejo por separado. Comience desde la salida, marque cada ficha adyacente con un puntero a la salida, luego desde cada una de estas fichas deje que todas las fichas adyacentes sin marcar apunten a esa ficha, etc.

Las matemáticas son realmente las mismas que el algorithm de Dijkstra (A * sin optimization de distancia), simplemente no descarta ningún dato y, por lo tanto, termina con una ruta de muchos a uno.

Deberías terminar con una matriz de datos que se parece a esto, generada en time lineal:

|---|---|---|---| | | | | | | | | X | ->| e | | v | | | | |---|---|---|---| | | | ^ | ^ | | | | X | | | | | | v | | | | |---|---|---|---| | | | ^ | ^ | | ->| ->| | | | | | | | | | |---|---|---|---| | ^ | ^ | | ^ | | | | | | X | | | | | | | | |---|---|---|---| 

Divagaciones aleatorias algo relacionadas:

Con respecto a la ruta de acceso punto a punto, vale la pena señalar que A * pierde mucha ventaja con el algorithm de Dijkstra más simple cuando opera en un laberinto retorcido. A * probablemente aún busque less nodos, pero también es más lento por nodo que Dijkstra.

Para el típico laberinto de defensa de la torre, los puntos de input y salida se ubican en el borde del campo, esto significa que Dijkstra no perderá time buscando un campo grande en la dirección incorrecta. Junto con el laberinto, esto significa que Dijkstra y A * searchán casi el mismo número de nodos, por lo que Dijkstra se lleva la victoria en este caso por ser más rápido por nodo.

De hecho, escribí un juego una vez que hizo este tipo de cosas perfectamente. Y la cantidad de recálculo fue muy pequeña en comparación con A *.

En un map base de cuadrícula (incluso si los caracteres no se mueven en una base de cuadrícula), tiene una matriz bidimensional y marca el final con 0,0.

Agregue los cuatro cuadrados adyacentes a una list.

Luego, usando un ciclo for o while, itere a través de la list, y simplemente dé a cada cuadrado un valor del mínimo de los cuatro cuadrados circundantes + 1.

A continuación, agregue los cuatro cuadrados circundantes a ese cuadrado de la list (si su valor aún no está establecido).

Básicamente, en un map vacío, podría recibir un efecto como este en la matriz:

  • 3,2,1,2,3,4
  • 2,1,0,1,2,3
  • 3,2,1,2,3,4
  • 4,3,2,3,4,5
  • 5,4,3,4,5,6

Sin embargo, en un map con obstáculos …

  • 3,2,1,2,3,4
  • 2,1,0, X, 4,5
  • 3,2,1, X, 5,6
  • 4, X, 2, X, 6, X
  • 5,4,3, X, 7,8

Ahora este método tiene 3 beneficios principales.

Si coloco un bloque en un 4 por ejemplo. ¡Entonces solo deben actualizarse los cuadrados con un valor de 5 o superior! Simplemente tengo un bucle que pasa por los valores de 5 hacia arriba (asegúrese de tener todos los 5 hechos antes de hacer los 6, y todos los 6 antes de los 7, etc.

O podrías hacerlo desde una matriz vacía nuevamente. ¡Es extremadamente rápido!

¡El segundo beneficio es que la cuadrícula es exactamente la misma para todos los enemigos! Todos los enemigos en el map siguen esta matriz. Si está en un 7, ¡entonces quiere moverse a un 6! No importa qué 6, ¡porque todos están a la misma distancia (6 cuadrados) del final!

En tercer lugar, si, durante su bucle para calcular los valores de esta matriz, si no se alcanza un cuadrado, (si el valor permanece sin establecer, y no hay una torre allí), significa que la parte del map está cortado de la base. En la mayoría de las defensas de la torre, esto no está permitido. Entonces, si revisas esto antes de confirmar la location de una torre, significa que sabes si es una construcción legal o ilegal.

Espero que esto haya ayudado, Randomman159

Necesita calcular una nueva ruta para cada unidad existente, y una nueva para las unidades que recién se generan.

Realmente depende del tipo de defensa de torre que estás desarrollando.

Caso 1: si sus torres no pueden bloquear sus cornetworkingores (por lo que no puede cambiar la ruta), simplemente puede desarrollar un sistema de región simple. Es realmente fácil de implementar:

Unit1 ingresa a region1 -> ejecuta a region2 Unit1 ingresa a region2 -> go to region3 …

Todo lo que necesita es ubicar sus regiones de forma que no haya objects bloqueantes entre dos regiones vinculadas.

Caso 2 (Su caso): Sus torres pueden bloquear. Si es el caso, tendrá que diseñar un sistema de algorithm A *. El sistema puede ser más difícil de implementar para los principiantes, pero no se preocupe, hay un gran sistema de identificación de paths A * en la networking que puede reutilizar. Tendrá que volver a calcular la ruta cada vez que algo cambie la ruta real. Pero no se preocupe, ¡un buen sistema A * puede volver a calcular la ruta de miles de unidades en un abrir y cerrar de ojos!

¡Puede mezclar el sistema de región y el hallazgo de ruta A * para get resultados más rápidos! Solo tendrá que calcular la ruta a la siguiente región y no al punto final, de modo que mejorará su performance.