.NET Tutorial 34. XNA y pixel perfect collision

En el tutorial 16 vimos como verificar colisiones 2d usando "regiones". Usando XNA vamos a ir un paso más allá. En vez de realizar la comprobación por regiones veremos que es posible verificar las colisiones a nivel de pixeles, lo cual es mucho más preciso y da un poco igual la "forma" de nuestros sprites.

Al igual que en el tutorial 16 tendremos lo siguiente:


(Haz click para agrandar)

Por defecto se evalúa la colisión solo cuando hay intersección entre las dos regiones:

Aunque pulsando la tecla I se evaluará siempre la colisión:


(Haz click para agrandar)

Y aquí el resultado de la colisión a nivel de pixel:

Pues bien, ¿cómo se consigue realizar una colisión a nivel de pixels?

Pues usando la propiedad GetData que incorpora XNA.

En nuestro código tenemos lo siguiente:

Private Boss As Texture2D
Private BossTextureData() As Color

Private Player As Texture2D
Private PlayerTextureData() As Color

Tanto  Boss como Player representan las texturas que se cargan desde el Content de XNA, mientras que BossTextureData y PlayerTextureData representan un array unidimensional con los datos de cada pixel: Canal Alfa, Red, Green y Blue.

Las texturas se cargan tal y como hemos visto en los tutoriales anteriores:

Boss = Content.Load(Of Texture2D)("finalboss_0001")

La información de los pixels de la textura los cargamos así:

ReDim BossTextureData((Boss.Width * Boss.Height) – 1)
Boss.GetData(BossTextureData)

Al utilizar GetData estamos guardando toda la información de los pixels en BossTextureData.
Como veis, es un array unimensional de objetos Color.

Al ser unidimensional, ¿Cómo accedemos al pixel de la posición (100, 35) ?

Pues así:

Color = BossTextrureData (x + y*AnchoTextura)

o lo que es lo mismo:

Color = BossTextureData (100+35*AnchoTextura)

Recordareis que la componente Alfa es la Color.A, la componente "roja" es la Color.R, la verde la Color.G y la azul la Color.B

Si en el área de colisión (marcada de amarillo en este tutorial) la componente alfa del boss es <> 0 y además si la componente alfa del jugador es <> 0 hay pixels "que se están pisando" dentro de esa regió, por lo tanto, hay colisión.

Fácil, limpio y realmente rápido 🙂

Podemos usar tambén esta técnica para realizar esto:

Nota: El vídeo es de un remake del Bruce Lee de spectrum y que voy actualizando cuando tengo algo de tiempo y ganas 🙂

En este caso, tengo una "máscara" que le dice al jugador por donde puede pisar o escalar. Se utiliza la misma técnica que la colisión por pixels.

 

Saludos.
mov eax,ollydbg; Int 13h  

Descargar proyecto .NET Tutorial 34
(180 KB. Visual Studio 2008 Professional / XNA GS 3.1)

Descargar binarios del .NET Tutorial 34
(788 KB. Requiere .NET Framework 3.5 / XNA Framework 3.1