Colisión 2D rápida y precisa

17

Estoy trabajando en un tirador 2D de arriba hacia abajo, y ahora necesito ir más allá de mi sistema básico de colisión de rectángulo delimitador.

Tengo grandes niveles con muchos sprites diferentes, todos los cuales tienen diferentes formas y tamaños. Las texturas para los sprites son todos archivos png cuadrados con fondos transparentes, por lo que también necesito una forma de tener una colisión solo cuando el jugador entra en la parte coloreada de la textura, y no en el fondo transparente.

Planeo manejar la colisión de la siguiente manera:

  1. Comprueba si algún sprite está dentro del alcance del jugador
  2. Haga una prueba de colisión de caja de delimitación recta
  3. Hacer una colisión precisa (donde necesito ayuda)

No me importan las técnicas avanzadas, ya que quiero hacer esto bien con todos mis requisitos en mente, pero no estoy seguro de cómo abordar esto. Qué técnicas o incluso bibliotecas probar. Sé que probablemente necesitaré crear y almacenar algún tipo de forma que represente con precisión cada sprite menos el fondo transparente.

He leído que por píxel es lento, por lo que, dado mis grandes niveles y la cantidad de objetos, no creo que sea adecuado. También he visto Box2d, pero no he podido encontrar mucha documentación, ni ejemplos de cómo ponerlo en funcionamiento con SFML.

Neófito
fuente

Respuestas:

18
  1. Paso uno, cree una cuadrícula y actualícela para cada objeto que se mueva.
  2. Solo verifique las colisiones entre objetos en los mismos cuadrados.
  3. Compruebe si el cuadro delimitador de los objetos se cruza (su rectángulo contenedor).
  4. Verifique la colisión perfecta de píxeles con una versión de baja resolución del esquema (consulte Física del juego).
  5. Realice una comprobación normal del trazado del esquema como se describe en Game Physics (Q 2)

Paso 1:

Crear una matriz de cuadrícula 2D. Cada objeto sabe qué cuadrados ocupa por su posición x, y y su ancho y alto. Si un objeto se aleja, se borra del cuadrado antiguo y actualiza el nuevo cuadrado que está ocupando.

Esto solo toma O (n) en total para n objetos. Para cualquier objeto específico O (1).

Paso 2:

Ejecute todas las comprobaciones de colisiones entre objetos en los mismos cuadrados. No es necesario realizar pruebas de colisiones entre objetos en diferentes cuadrados. Un objeto puede ocupar hasta cuatro cuadrados si es de tamaño promedio. Esto significa muy pocos controles.

Paso 3:

Verifique la intersección entre los rectángulos de los objetos. Si no existe una intersección, deténgase.

Etapa 4:

Verifique las colisiones perfectas de píxeles entre los contornos de los objetos solo dentro del área de intersección. Debería ser lo suficientemente rápido. De lo contrario, cree una matriz booleana en 2D de baja resolución y verifíquela primero, si encuentra colisiones allí, solo necesitaría verificar un pequeño segmento en la matriz 2D de alta resolución para ahorrarle un tiempo precioso.

Lea esto para obtener un concepto sobre cómo dividir su mundo de juego en una cuadrícula de cuadrados:

Hacer un sistema eficiente de detección de colisiones

Lea esto para intuir cómo detectar colisiones perfectas de píxeles .

Juego de física / detección de colisión 2D AS3

Puede mejorar el rendimiento significativamente:

  1. Guardar una versión de baja resolución (1/16) del esquema para verificar primero.

  2. Solo verificando el área donde se cruzan los dos rectificados.

  3. dividiendo el contorno aproximadamente en segmentos, y solo verificando primero las colisiones entre segmentos.

Por favor, siéntase bienvenido a comentar y elaboraré

comprobar en el área de intersección

Wolfdawn
fuente
1
Como dijo Arthur, reemplace sus pasos 1. y 2. con una cuadrícula, y en cuanto a la detección precisa de colisiones, puede usar una versión de baja resolución de sus imágenes.
Markus von Broady
1
Y si realmente lo necesita, también podría usar una técnica similar a mi respuesta aquí: gamedev.stackexchange.com/questions/38481/…
Markus von Broady
Markus señala una buena idea. Debe usar una matriz booleana 2d o una matriz 1d que se trate como 2d y podría guardar 1/2 1/4 1/8 versiones de baja resolución de esa matriz para acelerar las cosas. Esto probablemente no será necesario ya que el cálculo en matrices 2d-booleanas es muy rápido. Todavía es una herramienta útil para tener.
wolfdawn
Si el jugador está completamente contenido dentro de un cuadrado en la cuadrícula, solo puede verificar contra los objetos en ese cuadrado. El jugador puede estar en cuatro casillas adyacentes a la vez. ¿Es eso lo que quieres decir? Si te refieres a la intersección entre rectángulos, sí, solo necesitas verificar las colisiones si se cruzan.
wolfdawn
1
Espero que la actualización ayude a aclarar las cosas. Una vez que tenga algún código escrito, puede publicarlo en la revisión del código y vincularnos para comentarios. codereview.stackexchange.com
wolfdawn