Estoy haciendo un juego de disparos fijo simple, similar a "Galaga" ,) como parte de una presentación que estoy haciendo. Me pregunto qué estrategias y estructuras de datos usarían las personas para rastrear proyectiles, como los láseres disparados desde la nave espacial. Una implementación súper simple que he usado, antes, es representar cada proyectil como un punto y verificar las colisiones con todos los objetos en la escena.
Sin embargo, esto parece costoso, en escenas grandes con muchos proyectiles; Me pregunto qué otros tipos de estrategias o implementaciones se utilizan para este tipo de casos de uso. ¿Qué usan los juegos como FPS para rastrear proyectiles (balas, proyectiles, etc.)?
game-design
design-patterns
Polaris878
fuente
fuente
Respuestas:
Para proyectiles muy rápidos (como láser o balas), puede usar un Ray .
Un rayo tiene un punto de inicio y un punto final. Una estructura de datos (muy mínima) para un rayo es:
Se ve como esto:
(También puede almacenar en caché el vector de dirección y la longitud, pero usé una definición muy simple arriba).
Si el rayo es un rayo láser que viaja a la velocidad de la luz, simplemente persistiría el rayo (como comenzando en la boquilla de la pistola y terminando en una pared en algún lugar) durante un par de cuadros. Cualquier cosa que se cruce con el rayo de cada cuadro recibe daño.
Si el rayo es un proyectil más lento (como una bala, por ejemplo), el rayo modela la distancia que recorrió la bala en un paso de tiempo. El punto de inicio es donde está el rayo al comienzo del cuadro, y el punto final es donde estará el rayo después de terminar el cuadro. Cualquier cosa en el camino del rayo de bala es dañada por la bala.
Los rayos pueden colisionar eficientemente con esferas, aabbs, cascos convexos, etc. Vea mi proyecto Hullinator para un programa real en ejecución (CTRL + Clic para disparar rayos)
fuente
El uso de un rayo funciona bien para proyectiles que viajan instantáneamente, como las balas. Para los proyectiles que tienen una velocidad más lenta, como el tipo que utilizará para su juego espacial, tiene sentido simplemente rastrear su posición en el mundo del juego como lo haría con cualquier otra entidad. Lo que a menudo hago es tener una clase base llamada Entidad que contiene propiedades de cualquier objeto duradero del juego: posición, rotación, cuadro de colisión, etc. Mi jugador manejado y proyectiles heredan de esto y mi mundo del juego solo necesita saber cómo lidiar la Entidad de superclase, no cada tipo individual de entidad.
Para aumentar el rendimiento, es muy común mantener un grupo alrededor de los objetos que creará y destruirá con frecuencia. Cuando necesite un nuevo proyectil que extraería de este grupo, modifique el nuevo proyectil según sea necesario y devuélvalo al grupo cuando haya caducado.
fuente
Cuando desee optimizar para la detección de colisiones, puede almacenar todos los objetos del juego en un árbol de dos o tres dimensiones . Esta estructura de datos hace que sea muy eficiente recuperar todos los objetos en un área determinada.
Sin embargo, los árboles binarios tienen la desventaja de que se degeneran fácilmente cuando se agregan, eliminan y cambian sus posiciones, por lo que deberá equilibrarlos automáticamente .
Un compromiso que sería más fácil de implementar pero no tan eficiente sería utilizar un enfoque basado en fragmentos. Divide el campo de juego en cubos y realiza un seguimiento de los objetos que tocan cada cubo. Cuando verifica las colisiones con un objeto, solo necesita verificarlo contra las listas de objetos de los cubos que está tocando (reemplace "cubo" con "rectángulo" para un 2d-juego).
fuente