[XNA] Técnicas de detección de colisiones (2D)

Existen numerosas técnicas de detección de colisiones entre sprites (no exclusivas de XNA, son comunes en el mundo del desarrollo de videojuegos). Lo más fácil y eficiente (de cara a procesamiento y obtención de buenos resultados de performance) es utilizar rectángulos. Como se muestra en la imagen:

El problema obvio es la imprecisión en la detección de la colisión. Segun esto, un impreciso acercamiento entre los dos objetos ya supondría una colisión. Como demuestra la siguiente imagen:

En muy pocas ocasiones, pues, esta técnica tan simple nos valdrá. Aunque existen otras variantes más precisas, y todavía eficientes, basadas en la detección de colisiones mediante rectángulos. Una de ellas sería dividir cada uno de los sprites en rectángulos más pequeños, y englobarlos todos en uno más grande. Entonces, primero intentaríamos detectar la colisión mediante los rectángulos grandes, y solo si esta es afirmativa, intentaríamos detectar la colisión entre los rectángulos más pequeños (y estos son los que decidirían si hay colisión o no).Segun esta técnia, no habría colisión entre los siguientes sprites:

Si todavía queremos ser más perfeccionistas en cuanto a la optimización del rendimiento, podemos dividir la pantalla en N rectángulos «virtuales», y hacer un primer filtro comprobando si el rectángulo de nuestro sprite se encuentra en el mismo cuadrante que el sprite contra el cual queremos comprobar la colisión.

Ahora bien… todavía puede no ser suficiente este nivel de precisión… puede que necesitemos una precisión de píxel a píxel. A eso se le llama comunmente en el desarrollo de videojuegos «pixel perfect collision». Acerca de esto existe un tutorial excelente en Ziggyware, por lo que no voy a profundizar más en este tema en este artículo.

Lo bueno de la técnica «pixel perfect collision» es su precisión. Lo malo? Nada es gratis en esta vida… los problemas de rendimiento que puede causar cuando el número de sprites sea grande pueden darnos dolores de cabeza. Para reducir estos problemas… se puede combinar la técnica del pixel perfect collision con la de los múltiples rectángulos. Es decir, para comprobar si dos sprites colisionan mediante este método «costoso», antes comprobaremos si en rectángulos que interseccionan.

Crear estos rectángulos de forma precisa mediante codificación (y muchas veces prueba / error) puede costarnos demasiado tiempo y energía… así que podríamos utilizar para ello el Vector Sprite Editor que nos proponen de nuevo en Ziggyware.

Otra variante que me parece muy interesante, y menos documentada, es la técnica de pixel perfect collision utilizando un mapa de colisiones. Esto consiste en la asunción de que si hay que hacer una comprobación píxel a píxel de la colisión… por lo menos reduzcamos el número de píxels para que este cálculo sea menos costoso! Parece obvio, pero como se hace? La idea es sencilla, trabajando con una imagen de menor resolución, o mapa de colisiones.

Podemos observar que será mucho más fácil (y mucho menos costoso) realizar una detección de colisiones con la imágen de la derecha que con la de la izquierda, por el simple motivo de que tiene muchos menos píxeles, y por tanto menos comprobaciones y cálculos a realizar.

Para generar el mapa de colisiones, tenemos varias opciones:

  1. Se generan los dos bitmaps (detallado y pixelado), y se cargan ambos en nuestro sprite, usando uno para mostrarlo por pantalla, y el otro para calcular las colisiones.
  2. Dinámicamente se carga el bitmap del sprite y se pixela. Si usamos esta opción es muy importante que sólo procesemos cada imagen una vez… sinó sería peor el remedio que la enfermedad. Lo ideal será realizar este proceso al inicio del juego, o idealmente al inicio de cada pantalla, obteniendo un tiempo de carga inicial algo mayor, pero una experiencia en el juego más rápida.

 

En la web de Creators de XNA existen excelentes ejemplos de código acerca de la detección y respuesta a colisiones que os recomiendo.

 

Dicho esto… ya tenemos conocimiento de algunas de las técnicas más comunes para detección de colisiones en juegos 2D no basados en Tiles (o casillas).

Felices colisiones!

5 comentarios sobre “[XNA] Técnicas de detección de colisiones (2D)”

  1. Quiero añadir que la técnica de detección de colisiones con múltiples rectangulos a veces puede ser contraproducente en cuanto a rendimiento, si no se usa bien… (al final son muchos «if»), así que cuidado 🙂

  2. El articulo me ha gustado mucho y es que sirve de buena base para orientarse aunque me ha dado mucha pena descubrir que la pagina ziggyware, la cual por todo internet citan como una fuente impagable sobre xna, ya no este activa y pinte como que nunca vuelva a estarlo.

    Por lo cual en relacion al tutorial de pixel perfect collision me he quedado con ganas (salvo que alguien tenga una copia ^^).

  3. He probado a hacer busquedas en google e incluso con cache: y esta visto que nada, pues una pena porque todos comentan que estaba llenisima de buena info. Pero aun asi me alegra haber encontrado tu blog porque hay muchos articulos sobre xna que me interesan mucho e ire leyendo y probando a incorporar en un juego que ando desarrollando.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *