Algoritmo para calcular una ruta de bala a un objetivo con máx. 2 rebotes

21

Perdón por el pobre título, pero no tenía una mejor manera de expresarlo ...

Así que hay un juego increíble de Nintendo (¡sí!) En Wii llamado WiiPlay . Hay 9 minijuegos, ¡y mi favorito se llama Tanques! . Se trata de destruir tanques enemigos COM sin que te destruyan a ti mismo. Aquí hay una captura de pantalla de un nivel:

ingrese la descripción de la imagen aquí

Una forma de destruir tanques es disparando balas. Existe este tanque enemigo verde lima que dispara balas de alta velocidad que rebotan (contra las paredes y los bloques) dos veces. Puedes ver cómo el tanque del jugador puede ser destruido instantáneamente si se queda donde está ahora, ya que ese tanque de cal en el centro puede disparar una bala que sigue el camino verde que dibujé en la imagen.

Como programador aficionado, me he estado preguntando cómo puede determinar el tanque de cal en qué dirección debe disparar para golpear el tanque del jugador.

Lo pensé yo mismo, pero no se me ocurrió ningún algoritmo posible. Explicaré mis conclusiones en caso de que inspiren a alguien. Solo por simplicidad durante mi explicación, supongo que una pared es cualquier superficie contra la cual una bala puede rebotar . Un rectángulo aislado de bloques forma así cuatro paredes.

Llegué a la conclusión de que los 2 puntos en los que la bala rebota siempre se encuentran en un lado de un paralelogramo o se convierten en vértices opuestos de un paralelogramo. El tanque enemigo que dispara y el tanque del jugador al que apunta no son necesariamente los otros 2 vértices, sino que definitivamente se encuentran en las líneas colineales a cualquiera de los cuatro lados del paralelogramo. Aquí hay una ilustración de las 4 formas posibles en que se puede formar un paralelogramo:

ingrese la descripción de la imagen aquí

HOR-VER significa que la bala primero golpea una pared horizontal, luego golpea una pared vertical.

Y luego estoy atascado. Pensé en moverme alrededor de una línea que conecta el tanque enemigo y el tanque del jugador alrededor del mapa para ver si forma un paralelogramo con dos golpes con cualquier muro, pero esto no siempre funciona porque el tanque enemigo y el tanque del jugador no están necesariamente coincidente con los vértices del paralelogramo.

Además, no estoy seguro del flujo general del algoritmo. ¿El algoritmo toma alguna de las siguientes 2 estructuras, o tal vez estoy equivocado con ambas?

  • Siga descubriendo posibles caminos y marque siempre uno como el mejor (puede ser el más corto, el más oscuro, el más inevitable, o una evaluación combinada y ponderada basada en múltiples criterios) y olvide el resto. El que queda después de todo el cálculo es el mejor para tomar.
  • Primero determine todas las paredes primero alcanzables con la bala (la bala no necesita rebotar contra ninguna otra pared para alcanzar cada una de estas paredes), luego determine todos los rangos alcanzables en cada una de estas paredes (a veces es imposible alcanzar un punto lejano en una pared sin rebote si hay otra pared cerca de usted), luego determine de nuevo todas las paredes accesibles con rebote, y todos los rangos alcanzables en estas paredes. Estos 4 procesos se pueden realizar de manera similar al trazado de rayos. Durante cada proceso, si el rayo golpea el tanque del jugador, descubra el camino de la bala de acuerdo con ese rayo.

En mi opinión, este algoritmo es difícil de entender porque:

  • se puede disparar una bala en cualquier dirección; y
  • hay infinitos puntos en cualquier pared, como en matemáticas, donde hay infinitos puntos en una línea.

Pero la gente de Nintendo lo logró de todos modos, así que ... ¿alguien con una idea?

Hola a todos
fuente
Solo para verificar, estás preguntando cómo se podría hacer esto, no cómo Nintendo decidió hacerlo, ¿verdad?
Ixrec
@lxrec tienes razón, solo te interesa una forma posible de hacerlo, no la forma en que lo hicieron .
Hola a todos el
El juego no necesita encontrar una solución. Cuando presionas el botón para disparar, el juego ya conoce tu posición y dirección que estás enfrentando, entonces solo usa esa información. Trazará la trayectoria y si encuentra el tanque enemigo en el camino, lo golpeará de lo contrario no.
Mandrill
2
Si bien hay "infinitamente" muchos ángulos, puede reducirlos fácilmente a unas pocas clases de equivalencia. Sight and Light de Nicky Case es una demostración genial de renderizar sombras entre polígonos, que es exactamente su problema, excepto que está utilizando caminos de bala en lugar de rayos de luz, y que sus rayos pueden reflejarse dos veces. Tenga en cuenta que el reflejo no es importante para la IA: el reflejo simplemente extiende la línea de visión, aunque esto significa que el mismo objeto puede ser visible desde múltiples ángulos.
amon
@Mandrill Me temo que no entendiste mi pregunta. Estaba preguntando cómo el tanque enemigo puede idear un camino de bala que golpee el tanque del jugador.
Hola a todos los

Respuestas:

9

Dada una línea de visión directa, el problema es obviamente trivial. Sin embargo, estamos tratando con la reflexión. Descubrir adecuadamente qué partes de la escena se pueden ver es un desafío cuando se implementa la reflexión como parte de un rastreador de rayos, ya que esto podría perder algunas aberturas. Una "búsqueda binaria" entre dos ángulos prometedores tampoco es viable: debido a los reflejos, el espacio realmente visible no es continuo, por lo que la heurística "si está a la derecha de A y a la izquierda de B, debe haber un objetivo la solución entre A y B " no está permitida , y perderá soluciones" creativas ". En cambio, recomendaría implementar la reflexión volviendo a ejecutar el trazador desde una posición virtual, la posición donde parece estar nuestro tanque de disparo cuando se ve en el espejo:

target |obstacle
   X   |
    \  |  X real position
     \   /
      \ /
   ----------- mirror surface
        \
         \
          X virtual position

La ventaja es que el rayo reflejado es ahora una línea recta que se origina en la posición virtual. Traté de ilustrar la técnica en el siguiente boceto:

disparando en las esquinas

X marca la posición de disparo, (X) el objetivo. Las áreas coloreadas son visibles.

  1. Línea de visión directa: el objetivo no es visible. Sin embargo, podemos golpear las superficies (1) y (2).

  2. Una reflexión Hay dos posiciones de disparo virtuales dentro de los obstáculos. La posición inferior tiene LOS directo al objetivo, por lo que tenemos nuestra primera solución de disparo: la trayectoria de la bala es la parte del rayo entre el objetivo y la superficie del espejo inferior, y entre el punto de colisión del espejo y la posición de disparo real.

  3. Dos reflexiones: la posición virtual superior desde la primera reflexión puede ver parte del obstáculo inferior a través de la superficie del espejo. Como se permiten dos reflexiones, podemos reflejar esta posición en el obstáculo inferior. Las posiciones están marcadas como (I) la posición real, (II) la posición virtual desde la primera reflexión, y (III) la posición virtual desde la segunda reflexión.

    Desde (III), tenemos LOS directo al objetivo (X), por lo que hemos encontrado otra solución de disparo. La trayectoria de la bala es a lo largo de la línea X – III hasta el segundo punto de colisión del espejo, luego a lo largo de la línea III – II entre los puntos de colisión del espejo, y finalmente a lo largo de la línea II – I desde el primer punto de colisión del espejo hasta la posición real I.

    En realidad, la posición virtual inferior desde la primera reflexión también podría reflejarse en el obstáculo superior, pero esto no conducirá a ninguna solución directa.

Una vez que pueda averiguar qué partes de los obstáculos son visibles (y, por lo tanto, se pueden usar para reflejar la bala), la implementación de la duplicación a través de una búsqueda de profundidad parecería sencilla. Para encontrar superficies de espejo adecuadas, se pueden usar las técnicas descritas en Nicky Case's Sight & Light : en lugar de probar 360 vectores, que pueden perder aberturas y también es un desperdicio, lanzamos rayos solo al borde de los obstáculos.

amon
fuente
No entiendo cómo funciona "lanzar rayos solo hasta los bordes de los obstáculos". ¿Te refieres a comenzar a lanzar rayos hacia el final de las paredes y gradualmente hacia adentro hasta encontrar una solución? Si es así, entiendo que con esta regla la solución se puede encontrar más rápido.
hola a todos los
Después de considerarlo un poco, creo que esta es la mejor respuesta porque, obviamente, con la respuesta matemática que marqué como mejor antes, no se puede tratar directamente con soluciones de un rebote y sin rebote.
Hola a todos el
¡Esto es brillante! ¿Algún consejo sobre cómo crear una representación reflejada de tu nivel sin ser demasiado exigente en tu juego?
retrovius
7

Simplemente extendiendo la idea de Karl Bielefeldt para reflexiones de 2 paredes:ingrese la descripción de la imagen aquí

A y B se dan (los tanques). Primero debe enumerar todos los muros que A puede ver y una lista de todos los muros que B puede ver. Luego haces parejas donde la primera pared está en la lista de puños y la segunda pared es diferente de la primera pared y está en la segunda lista. Debe realizar esta prueba para todos los pares de paredes posibles (a menos que encuentre una manera de eliminar candidatos). Una vez que encuentre R y S para un par de paredes determinado, verifique

1) si A tiene visión directa de R

2) si R pertenece al muro1 (el muro es solo un segmento, no toda la línea)

3) si R tiene acceso directo a S

4) si S pertenece a wall2 (la pared es solo un segmento, no toda la línea)

5) si S tiene acceso directo a B.

Para encontrar R y S : Dado que conoce wall1, puede determinar la ecuación de línea tangente a wall1, ya que R pertenece a la línea tangente a wall 1, tiene una relación entre las 2 coordenadas de R (que termina con un grado de libertad para R) De manera similar a S (tiene una relación entre las coordenadas S ya que este punto pertenece a la línea tanget con wall2). Entonces ahora tiene 2 grados de libertad y debe tener 2 ecuaciones independientes adicionales para determinar una solución. Una ecuación es:

(AA')/(RA')=(SS')/(RS')

la otra ecuación es:

(BB')/(SB')=(RR')/(SR')

Observe que en las ecuaciones anteriores A, A ', B, B' son conocidas o pueden calcularse directamente. R 'y S' son función de las coordenadas de R y S y las ecuaciones de la pared. No terminé las matemáticas, así que no sé cómo se verán las ecuaciones.

Mandril
fuente
Este es un gran enfoque matemático. Pero supongo que el algoritmo requiere mucho tiempo de cálculo para resolver las ecuaciones simultáneas. Hay muchas raíces cuadradas y exponenciación involucradas con las distancias.
Hola a todos los
3

Puede aprovechar el hecho de que el ángulo que sale del rebote debe ser el mismo que el ángulo que ingresa. Para una pared horizontal dada con coordenada cy y dos tanques fijos con coordenadas (a,b)y (d,e), solo hay un ángulo que satisface la ecuación a continuación.

diagrama de ecuación

Simplemente resuelva para xobtener la distancia a lo largo de la pared a la que debe apuntar. Dos paredes funcionan igual. Solo tienes dos ecuaciones y dos incógnitas.

Karl Bielefeldt
fuente
1

Tiene diagramas claros que muestran cómo dirigir los rayos, por lo que dejaré los detalles sobre cómo determinar un par de superficies reflectantes.

Vamos a llamar a la superficie que debe ser golpeado primera superficie A , y la segunda, B .

Trate de golpear los bordes (visibles) de B al disparar contra una . En otras palabras, determine los puntos donde uno vería reflejos de los extremos de B si mirara el espejo A terminado . Esto debe ser fácil de hacer, solo tiene que manejar un punto de reflexión.

Ahora usted sabe dos rayos que golpean los bordes (visibles) de B . Llamémosles rayos extremos Calcule sus reflexiones en B; deben ir a algún lugar más allá de tu objetivo. Puede determinar si el objetivo se encuentra entre ellos, es decir, a la izquierda de un rayo pero a la derecha del otro, o viceversa. Esto es trivial si se usa la ecuación general de la línea recta .

Si el objetivo no está entre los rayos del borde, obviamente no puedes golpearlo con ningún rayo intermedio; elige otro par de superficies.

Si el objetivo está entre los rayos, busque el rayo de impacto intermedio mediante búsqueda binaria. Tienes dos ángulos de disparo correspondientes a los rayos del borde, tu ángulo de golpe se encuentra entre ellos. Siempre que el diámetro angular de su objetivo, como se ve desde el punto de disparo, no sea excesivamente pequeño, necesitará pocas iteraciones hasta que encuentre la dirección de un rayo de golpe.

Aquí hay una foto:

rayos

Aquí los dos rayos del borde se muestran en rojo y azul. Aparentemente puedes encontrar un rayo emitido en un ángulo más pequeño que el rojo pero mayor que el rojo para que ese rayo llegue al objetivo verde.

9000
fuente
¡No, no necesariamente! Piense en su diagrama si hubiera un obstáculo adicional en algún lugar entre los caminos de bala rojo y azul. Si disparas una bala en un ángulo justo entre los ángulos rojo y azul, puedes obtener un golpe más cercano al tanque del jugador, pero también puedes fallar por completo porque algo de la bala podría rebotar en algún obstáculo aleatorio que se encuentre en el medio. Por favor, vea la respuesta de @amon donde discute sobre esta posibilidad.
Hola a todos los
Respuesta de @ amon a favor; Me gusta la idea del reflejo en línea recta. También supongo que el algoritmo debe verificar que la ruta de acceso sea realmente pasable después de encontrarla de esta manera simplificada. Aún más interesante es una posibilidad en la que el objetivo está parcialmente ocluido (posiblemente incluso separado en dos regiones visibles). El método de Amon es más susceptible de manejarlo.
9000
-3

En primer lugar, ¿recuerdas en la clase de física cuando hablaste sobre la refracción de la luz? Bueno, su problema puede resolverse utilizando esos principios. El ángulo de incidencia es igual al ángulo de reflexión. por lo que el tanque enemigo debe atravesar todos los ángulos posibles para el primer rebote para que el segundo rebote pueda golpear al jugador. Sigue con la idea del trazado de rayos también. Ahora, esto se complica cuando el jugador se está moviendo, pero debería ser una buena idea comenzar un algoritmo

JavaFreak
fuente
1
Entiendo los principios de la reflexión. Puedes ver mi respuesta al comentario de @ amon. Tienes razón en que el movimiento del jugador debe tenerse en cuenta, pero creo que se puede dejar como un criterio para elegir un óptimo entre múltiples caminos posibles basados ​​en la evaluación. Sin embargo, esto puede ignorarse porque esto es correlativo con la distancia de la ruta de la bala, es decir , cuanto más larga sea la ruta, más podrá moverse el jugador antes de que la bala llegue a destino.
hola todo el