Fun Infused Games  |   Smooth Operator

  Home   |    Archive   |    About
Posts prior to 8/2/2010 may be missing data. If you need one of those posts, please contact kriswd40@yahoo.com and I will try and recover/find it.

Static Method for Per-Pixel Collision Detection
Date 4/22/2010    Tags XNA    (0)

Bounding boxes for 2D collisions are nice, but they aren't going to give you the most realistic collisions when your object isn't shaped like a box. Below is a static method that takes in the textures and positions of two sprites and will let you know if they collide or not.


"Look ma, no rectangles!"


The code itself is based off an example from ZiggyWare (though easier to implement), but since that website doesn't exist anymore, I figure I'd share my take on the code.

public static bool CheckPerPixel(Texture2D texture1, Texture2D texture2, Vector2 position1, Vector2 position2)
{
    bool perPixelCollission = false;

    uint[] bitsA = new uint[texture1.Width * texture1.Height];
    uint[] bitsB = new uint[texture2.Width * texture2.Height];

    Rectangle texture1Rectangle = new Rectangle(Convert.ToInt32(position1.X), Convert.ToInt32(position1.Y), texture1.Width, texture1.Height);
    Rectangle texture2Rectangle = new Rectangle(Convert.ToInt32(position2.X), Convert.ToInt32(position2.Y), texture2.Width, texture2.Height);

    texture1.GetData<uint>(bitsA);
    texture2.GetData<uint>(bitsB);

    int x1 = Math.Max(texture1Rectangle.X, texture2Rectangle.X);
    int x2 = Math.Min(texture1Rectangle.X + texture1Rectangle.Width, texture2Rectangle.X + texture2Rectangle.Width);

    int y1 = Math.Max(texture1Rectangle.Y, texture2Rectangle.Y);
    int y2 = Math.Min(texture1Rectangle.Y + texture1Rectangle.Height, texture2Rectangle.Y + texture2Rectangle.Height);

    for (int y = y1; y < y2; ++y)
    {
        for (int x = x1; x < x2; ++x)
        {
            if (((bitsA[(x - texture1Rectangle.X) + (y - texture1Rectangle.Y) * texture1Rectangle.Width] & 0xFF000000) >> 24) > 20 && 
                ((bitsB[(x - texture2Rectangle.X) + (y - texture2Rectangle.Y) * texture2Rectangle.Width] & 0xFF000000) >> 24) > 20)
            {
                perPixelCollission = true;
                break;
            }
        }

        // Reduce amount of looping by breaking out of this.
        if (perPixelCollission)
        {
            break;
        }
    }

    return perPixelCollission;
}
One word of warning, per-pixel collision detections can be slow. I never run this code by itself for my collision detections. Instead I check first for a rectangular collision and only if that occurs do I perform the per-pixel check.

kick it on GameDevKicks.com



This article has been view 3599 times.


Comments

No comments for this article.


Add Comments

Name *
Website
  Name the animal in the picture below:

*  
Comment *
Insert Cancel
Things To Click


Tags
Video Games (7)  Trivia or Die (3)  SQL (1)  iOS (3)  Game Dev (11)  Advise (14)  PC (1)  World of Chalk (2)  FIN (20)  Abduction Action! (27)  XBLIG (32)  Abduction Action (1)  Nastier (4)  ASP.net (18)  Absurd (2)  Volchaos (11)  Web (19)  Fin (1)  XNA (40)  Rant (50)  Cool (2)  Visual Studio (1)  Trivia Or Die (1)  Xbox (1)  C# (14)  Sports (11)  Design (2)  Development (13)  Hypership (28)  WP7 (8)  VolChaos (1)  Nasty (34)  Abdction Action! (1)