Skip to main content
gamedev.net
🔒 Locked

Texture collision

Started by Doughboy 3 replies 800+ views
Original Post
Doughboy
Doughboy
I am designing a contra-type game using textured quads for sprites. I need to perform pixel-perfect collision detection between these sprites. It wouldn''t be too difficult (although time-consuming and probably not optimal) to multiply the quads through their world, view, and projection matrices and then test for intersections between the quads, but is there any good way to test the pixels? There has to be some way to use DirectX Graphics to do this instead of basically creating a whole software renderer for collision detection. I''ve been racking my mind trying to think of some way to use the stencil buffer or something of the like, but I''ve never done something this complicated (this is for a game programming course in college), so I''m not sure how to handle it. Thanks! Dean Kusler
Cornutopia
Cornutopia
Generally ANYTHING is possible somehow but that''s a tough one. Perhaps a pixel shader can detect the pixel that your are replacing somehow...? a specific channel for a colission mask somehow... Just ideas off the top of my head.

This is tricky because the quad can be scaled or warped or whatever so you want texel perfect not pixel perfect collision and that''s not something I''ve seen done (I don''t think!).

It might be faster to use an alternative method. Few games need pixel perfect collision... All of my 2D ones used bounding circles and they worked just fine.

Mark
Cornutopia Games
http://www.cornutopia.net
Sound Effects For Game Developers
http://www.indiesfx.co.uk
Doughboy
Doughboy
Yeah, I figured it would be pretty tough. I suppose I can just test on the textured quads and use that for collisions. If I make the gameplay fast enough, no one will ever notice.

In any case, if someone has some ideas, shout ''em out! Maybe I can market my game demo as having the first "texel-perfect collisions".

Dean Kusler
M3d10n
M3d10n
Per pixel collison in 2D games is generally an overkill, except a few special cases.

First thing for good and fast collision in 2D games is untie the collision data from graphics data.

For characters, enemies and levels, define collision rectangles that moves as their "parents" move.
They don''t exactly need to match the full sprite size for a character, and you may add support for multiple rectangles per-sprite.

You can then, as example, have 5 types of rectangles: "blocked", "player", "enemy", "player projectile" and "enemy projectile". When a "player" rectangle intersects either an "enemy" or "enemy projectile" rectangle, the player takes damage, as example. And all movable sprites have their movement restricted to the "blocked" rectangles.

Also, checking rectangle intersections is simple and fast.
S1CA
S1CA
Yup, agree with what the others have said.

Take a closer look at many of the 8-bit classics, and read interviews with their creators and you''ll find that pixel perfect collision was a lot rarer than you''d think.

Many actually also tuned the collision in favour of the player (bigger bounding areas for the enemies, smaller for the player etc).

Another thing to think about is that the player hasn''t yet seen the frame you''re doing the collision detection on, and have up to a frames worth of delay to be able to react. For fast moving enemy fire using a set of bounding rectangles can actually be more correct than testing the pixel edges.


If you REALLY do want to do pixel perfect collision (I''d suggest experimenting with both once the game is tuned and see which frustrates players more), then I''d do it using COLLISION MASKS.

Generally these days, data used to render (an output/write only operation) such as DirectX textures and vertex buffers should never be used for computing game logic such as collisions. The reasons are many. Performance, portability etc.

For a Collision Mask, just make a 2D array of bytes (or bits if you''re feeling memory concious) where each byte in the mask represents a pixel in the sprite texture. If the byte is set to 0 the pixel isn''t solid (i.e. not collidable), for any other value it is.

The collision detection then consists of:

1) a quick check of the bounding rectangles of both sprites to determine that they "might" be colliding.

2) calculating how many and which pixels of each rectangle overlap. This gives you a smaller rectangle - those are the "possibily overlapping" pixels.

3) Get to the pixels in the "possibly overlapping" area in each of the collision masks (a few additions/subtractions)

4) Compare the bytes (or bits) in "possibly overlapping area" if both are 0, there''s no collision, if either are 1, there''s no collision, if both are 1, there''s a collision.


That really isn''t anywhere near as complicated as writing a software renderer. About 10-20 lines of code I''d say.

If you''re rotating sprites then things are more compilcated. With your 3D vertices transform the coordinates of one into the same space as the other and account for the slope when looking up pixels in the "possibly overlapping" area.

Alternatively you could use a screen sized "work area" where you copy the rotated version of the overlapping area over the other, maybe with an "add" of pixels during the copy for faster detection of the collision - i.e. "if (resulting_mask_to_mask_pixel>1) collision();".


BTW: Do bear in mind DirectX isn''t really a "game making kit", it''s for "directly" exposing features of the hardware on your machine so doesn''t cover, and you shouldn''t expect it to cover things that PC gaming hardware doesn''t do such as AI, collision, game logic etc...


--
Simon O''Connor
3D Game Programmer &
Microsoft DirectX MVP
Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.