TaricDF
TaricDF

Reputation: 59

C# - Per Pixel Collision Detection

Here's my situation I'm making a 2D maze game(XNA 4.0). I have figured out that the best way to do collision detection is by using per-pixel detection. While searching it up on the internet I have found people explaining or showing code for two things colliding(i.e. mouse & player, player & player, two shapes). What I would like to do is have this collision detect whether the player collides with a wall or not(the background is black but the maze walls are white). Could someone explain how to do this or to give some sort of starting point with the code. Much Appreciated.

P.S. A link to a website or anything relating to my question would also be helpful

Upvotes: 0

Views: 1723

Answers (2)

GHC
GHC

Reputation: 339

The best way to go about this CPU-intensive operation is checking for hitbox collision first, then the per-pixel collision.

Most of this code can be found in this helpful video.

static bool IntersectsPixel(Rectangle hitbox1, Texture2D texture1, Rectangle hitbox2, Texture2D texture2)
{
    Color[] colorData1 = new Color[texture1.Width * texture1.Height];
    texture1.GetData(colorData1);
    Color[] colorData2 = new Color[texture2.Width * texture2.Height];
    texture2.GetData(colorData2);

    int top = Math.Max(hitbox1.Top, hitbox2.Top);
    int bottom = Math.Min(hitbox1.Bottom, hitbox2.Bottom);
    int right = Math.Max(hitbox1.Right, hitbox2.Right);
    int left = Math.Min(hitbox1.Left, hitbox2.Left);

    for(y = top; y< bottom; y++)
    {
        for(x = left; x < right; x++)
        {
            Color color1 = colorData1[(x - hitbox1.Left) + (y - hitbox1.Top) * hitbox1.Width]
            Color color2 = colorData2[(x - hitbox2.Left) + (y - hitbox2.Top) * hitbox2.Width]

            if (color1.A != 0 && color2.A != 0)
                return true;
        }
    }
        return false;
}

You can call this method like so:

if (IntersectsPixel(player.hitbox, player.texture, obstacle.hitbox, obstacle.texture))
{
    // Action that happens upon collision goes here
}

Hope I could help you out,
- GHC

Upvotes: 2

Eric Yang
Eric Yang

Reputation: 2750

Create a matrix of bools representing your sprite and a matrix of bools representing your maze (the matrix representing your sprite needs to have the same dimensions as your maze).

then you can do something simple like iterate over all x-y coordinates and check whether or not they're both true

// as an optimization, store a bounding box to minimize the 
// coordinates  of what you need to check
for(int i = 0; i < width, i++) {
    for(int j = 0; j < height, j++) {
        if(sprite[i][j] && maze[i][j]) {
             collision = true
             //you  might want to store the coordinates
        }
    }
}

If you want to be very fancy you can flatten your maze matrix and use bit operations

Upvotes: 0

Related Questions