Imagina un shoot-em-up muy simple, algo que todos sabemos:
Eres el jugador (verde). Su movimiento está restringido al X
eje. Nuestro enemigo (o enemigos) está en la parte superior de la pantalla, su movimiento también está restringido al X
eje. El jugador dispara balas (amarillas) al enemigo.
Me gustaría implementar una IA para el enemigo que debería ser realmente buena para evitar las balas de los jugadores. Mi primera idea fue dividir la pantalla en secciones discretas y asignarles pesos:
Hay dos pesos: el "peso de la bala" (gris) es el peligro impuesto por una bala. Cuanto más cerca esté la bala del enemigo, mayor será el "peso de la bala" ( 0..1
donde 1 es el mayor peligro). Los carriles sin bala tienen un peso de 0. El segundo peso es el "peso de distancia" (verde lima). Para cada carril agrego el 0.2
costo de movimiento (este valor es un poco arbitrario ahora y podría modificarse).
Luego simplemente agrego los pesos (blanco) y voy al carril con el peso más bajo (rojo). Pero este enfoque tiene una falla obvia, porque puede pasar por alto los mínimos locales, ya que el lugar óptimo para ir sería simplemente entre dos balas entrantes (como se indica con la flecha blanca).
Entonces, esto es lo que estoy buscando:
- Debería encontrar un camino a través de la tormenta de balas, incluso cuando no haya un lugar que no imponga la amenaza de una bala.
- El enemigo puede esquivar balas de manera confiable eligiendo una solución óptima (o casi óptima).
- El algoritmo debería ser capaz de tener en cuenta la velocidad de movimiento de la bala (ya que podrían moverse con diferentes velocidades).
- Formas de ajustar el algoritmo para que se puedan aplicar diferentes niveles de dificultad (tontos a enemigos súper inteligentes).
- El algoritmo debe permitir diferentes objetivos, ya que el enemigo no solo quiere evadir las balas, sino que también debe poder disparar al jugador. Eso significa que las posiciones donde el enemigo puede disparar al jugador deben preferirse al esquivar balas.
Entonces, ¿cómo abordarías esto? Al contrario de otros juegos de este género, me gustaría tener solo unos pocos, pero muy "hábiles" enemigos en lugar de masas de enemigos tontos.
fuente
Respuestas:
Creo que su idea básica es sólida, pero no es analógica. Necesita un campo de valor analógico que se ejecute en la pantalla. Entonces, gradiente de difusión 1D, del cual puede derivar un valor en un punto exacto en esa línea, sobre la marcha. Los gradientes de difusión son baratos y pueden ser utilizados por múltiples enemigos a la vez, ya que describen el entorno y no la vista de la entidad (un poco como la iluminación de radiosidad), probablemente por qué ha optado por el enfoque que tiene en su pregunta . Este gradiente debe ser relativamente suave, para evocar un movimiento orgánico del enemigo, y obviamente se actualiza como lo hace tu estado de juego. Quizás media móvil ?
El gradiente debe combinar:
Para esquivar, tenemos que poder encontrar una solución con precisión siempre que exista una solución . Tal es el caso siempre que haya un espacio lo suficientemente pequeño como para que el enemigo pueda esquivarlo. Es decir, solo puede hacer lo que puede hacer, por lo que el enfoque de gradiente no funcionará peor que cualquier otro enfoque en este sentido, diría.
El gradiente de difusión debería empujar al enemigo hacia los óptimos locales (que son los picos en el gráfico) con menos imperativo para moverse, cuanto más cerca estemos de un mínimo local, por lo tanto, un efecto de retorno decreciente al esquivar. Esto abre la puerta a una toma de decisiones más inteligente sobre cuándo el enemigo tiene una buena apertura para disparar.
Si la necesidad de disparar es mayor que la necesidad de moverse, entonces hágalo; su código también puede determinar esto por cuánto difieren. Puede implementar esto como parte del gráfico base, en cuyo caso la posición del jugador reduce los valores circundantes en el gráfico (suponiendo que los enemigos gravitan hasta el punto más bajo), que combina toda la toma de decisiones en un gráfico, o puede mantener el " gráfico "deseo de disparar" separado del gráfico principal "deseo de esquivar", que le ofrecerá un control más directo.
IRL, no me molestaría en esquivar un proyectil hasta que esté dentro de una distancia que sé, a mi velocidad de esquiva máxima, está empezando a ser difícil de evitar. Experiencia de primera mano al tirar piedras como muchacho. Una bala a x distancia que viaja a velocidad y tiene la misma clasificación de peligro que una bala a 2x distancia que viaja a 2y. Por lo tanto, esto debe tenerse en cuenta correctamente.
Las formas de ajustar el algoritmo para la dificultad del enemigo incluyen
Nuevamente, puedes implementar todos los factores en un gráfico (menos control y menos útil para múltiples enemigos), o en varios gráficos que miras juntos para obtener los resultados (más modular, probablemente funciona mejor para múltiples enemigos). Es difícil ser más específico, ya que hay muchas direcciones en las que puede tomar este enfoque.
fuente
Esto puede ser visto como un problema de ruta. En lugar de pensar en cómo el malvado evita las balas, imaginando que las balas son estáticas y el malvado debe viajar a través de ellas hasta la parte inferior de la pantalla.
E = enemigo
B = bala
P = jugador
* = opciones de ruta a la parte inferior de la pantalla
Una vez que el malo ha trazado un camino exitoso, solo necesita dar el siguiente paso cada vez. Probablemente ya existan algunos buenos algoritmos para encontrar rutas como este. Si el baddy se mueve a la misma velocidad que las balas, podría ser un algoritmo de ejemplo;
Comience en el baddy y marque posiciones seguras en espacios vacíos a la izquierda, directamente debajo y debajo a la derecha. Luego considere cada espacio seguro que acaba de crear y repita. Si en algún momento encuentra que no hay espacios seguros debajo, marque el espacio como no seguro y retroceda.
fuente