¿Cómo manejo la detección de colisión para que los objetos rápidos no puedan atravesar las paredes?

14

Estoy creando un tirador 2D de desplazamiento lateral, y estoy teniendo un pequeño problema con la detección de colisión de las balas. Todo, incluidas las viñetas, son objetos con sus propios polígonos / métodos de actualización.

El problema es que las balas van rápido, y a 60 cuadros por segundo (en qué se ejecuta el juego) una bala saltará a menudo a través de una pared, ya que se mueve más del ancho de la pared durante el intervalo de actualización, y continúe felizmente en su camino ya que los polígonos nunca se superpondrán realmente.

¿Qué puedo hacer sobre esto? Lo único que he podido encontrar es dibujar una línea desde la posición anterior a la nueva posición y hacer una detección de colisión en eso, pero la documentación de slick2d recomienda el dibujo de línea para la detección de colisión. ¿Como puedo resolver esto?

Mala
fuente
No es una respuesta completa, entonces un comentario. Nunca recomendaría dibujar gráficamente una línea, pero matemáticamente puedes hacer esto, es solo una simple intersección del plano de rayos para ver si ocurrió la colisión. Luego, puede hacer una detección de pasos fijos más pequeña para obtener el momento exacto (y toda la información que viene con él) cuando ocurrió la colisión sin tener que correr a una velocidad constantemente más alta como se sugiere en las respuestas. Haga una verificación menos costosa y luego pase el tiempo obteniendo la respuesta más precisa que necesite.
James

Respuestas:

9

Los enfoques estándar son (elija uno):

  1. Aumente su ancho de límite Y / O reduzca la velocidad máxima de su bala para que nunca pueda saltar a través de una pared en una sola actualización (requiere un poco de Pitágoras para calcular las distancias máximas / anchos de límite mínimos);
  2. Realice la detección de colisión continua (CCD), generalmente mediante la emisión de rayos para detectar la colisión con superficies lineales (2) o planas (3D) delante del objeto en movimiento. Esto es más costoso, pero es una solución más completa. Raycasting contra líneas 2D es bastante básico, pero necesita definir todos sus límites como polígonos de borde recto en este caso.

Para el caso, puedes modelar tus balas como rayos, si eso encaja con la apariencia de tu juego, como en left4kdead . De esa manera no es necesario aproximar las balas como rayos, porque ya son rayos. Desde el punto de vista de la apariencia, esto puede verse decente si dibuja la línea con un punto más brillante en el extremo de la viñeta, o simplemente dibuja la línea como un gradiente de claro (extremo de la viñeta) a oscuro (extremo de la cola), dándole una apariencia de movimiento.

Estoy de acuerdo en que, en la mayoría de las circunstancias, el uso de gráficos para la detección de colisiones es un poco equivocado, sin embargo, la detección de colisiones con píxeles perfectos es exactamente eso, y es una técnica aceptada. Supongo que todo depende de lo que quieras lograr y de qué tan rápido. Si no necesitas un juego muy rápido con muchos cuerpos + acción, anímate. De lo contrario, es mejor usar uno de los enfoques que describí anteriormente.

Ingeniero
fuente
Gracias por la gran respuesta, idealmente me gustaría que sea rápido con muchos cuerpos en movimiento. La razón por la que trato las balas como objetos físicos es para que se vean afectados por la gravedad como todo lo demás (por lo que se arquean ligeramente, dependiendo de la velocidad de la bala, etc.). ¿No es esta una buena manera de hacerlo? Este es mi primer juego, así que todavía estoy buscando las mejores prácticas. También podría usar una ecuación parabólica, pero no estoy seguro de cómo configurar los coeficientes relacionados con el ángulo de velocidad / puntería de la bala
Mala
3
Parece demasiado detalle para las balas. En la vida real, cuando disparas una bala, es poco probable que encuentres esa bala debido a la fuerza del rebote, la imprevisibilidad del ángulo del richochet, etc. O bien, simplemente entra en un cuerpo y permanece allí (árbol, persona). Simplemente los haría desaparecer o rebotar y luego desaparecería poco después. Concéntrese en su juego principal, no se preocupe demasiado por estos pequeños detalles. El realismo se enfoca mejor en las cosas que importan.
Ingeniero
Sí, supongo que puedo usar líneas rectas para las balas y tal vez encontrar una manera de hacer que se curven hacia abajo un poco más tarde, si parece importante.
Mala
2
Si la velocidad de las balas no es demasiado alta (es decir, no es tan rápida como para que no puedas verlas viajar a través de la pantalla), entonces puedes aplicar la gravedad a su velocidad sin dejar de modelar su detección de colisión con rayos simples. El usuario no notará que la bala se mueve como una serie de líneas rectas más de lo que notará cómo todos sus otros objetos también están haciendo lo mismo. Para los senderos de bala, calcular y dibujar un sendero curvo (spline) no es difícil y aumentará la ilusión de una curva suave a la trayectoria de la bala.
Sean Middleditch
3

Si desea que sus balas se comporten como objetos físicos realistas (por ejemplo, sus balas son más como flechas o piedras de una catapulta en lugar de disparos), entonces también puede intentar aumentar la frecuencia de sus actualizaciones físicas.

Entonces, aunque su juego podría ejecutarse con 60 fotogramas por segundo, su simulación física podría ejecutarse a 120 actualizaciones por segundo (aquí está el artículo de corrección ubicua de su paso de tiempo que explica una buena configuración física que puede ejecutarse a una velocidad diferente que el bucle de renderizado).

Por supuesto, aumentar el intervalo de actualización en el motor de física pondrá una mayor carga en la CPU. Por lo tanto, este enfoque solo es sensato si sus proyectiles no se mueven muy rápido (lo que suponía ya que puede decir que sus proyectiles se mueven en arco).

bummzack
fuente
¡Gracias! Efectivamente estoy haciendo esto (además de usar proyectiles en forma de línea) y espero que siga siendo factible a medida que el juego se vuelve más complicado
Mala