0
votes

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

2
do you really need pixel perfect collision? it's really resource expensive method of checking collision. use rather rectangle-polygon-circle collision.Davor Mlinaric
What kind of game is it? how do you move around? Is it important to move around that way?Steven
@Steven it is a 2D maze game(the entire maze itself is an image). I move around using two float variables xSpeed, ySpeed then I use the line of code walkRec.X += xSpeed. The user can only move in four directions(left,right,up,down), there is no diagonal movement. I would say it is very important.TaricDF
@DavorMlinaric yes I do because my PNG image is the maze, so the maze that I use was generated, then I went on piskel to change the color to fit my theme(the walls are white, background is transparent, the game screen is set to Black). So it would not be possible to do the collision your are talking about due to the fact the player would always be colliding with the imageTaricDF
@TaricDF (in theory, not sure if there is built GetPixelColor function of texture) instead of checking pixel collision for every pixel in whole maze and object, you could check if color above, under, left, right of object is "white"... if 1-2 pixels above object is white then there is a wall.Davor Mlinaric

2 Answers

1
votes

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

0
votes

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