1
\$\begingroup\$

I am using MonoGame 3.6 and Visual Studio 2017.

I have been trying to find a solution online to do per pixel collision detection using an animated sprite that I am drawing from a sprite sheet.

Using the following code which is not working:

The BoundingRectangle and Position on the AnimatedSprite.cs

public Vector2 Position
    {
        get { return position; }
        set
        {
            position = value;
        }
    }

public virtual Rectangle BoundingRectangle
    {
        get
        {
            return new Rectangle(
                (int)Position.X,
                (int)Position.Y,
                Width,
                Height);
        }

    }


public static bool CheckForPixelCollision(AnimatedSprite a, AnimatedSprite b)
    {
        // Get Color data of each Texture
        Color[] dataA = new Color[a.Width * a.Height];
        Color[] dataB = new Color[b.Width * b.Height];

        a.Texture.GetData(0, a.Animations[a.CurrentAnimation].CurrentFrameRect, dataA, 0, a.Width * a.Height);
        b.Texture.GetData(0, b.Animations[b.CurrentAnimation].CurrentFrameRect, dataB, 0, b.Width * b.Height);

        int top = Math.Max(a.BoundingRectangle.Top, b.BoundingRectangle.Top);
        int bottom = Math.Min(a.BoundingRectangle.Bottom, b.BoundingRectangle.Bottom);
        int right = Math.Max(a.BoundingRectangle.Right, b.BoundingRectangle.Right);
        int left = Math.Min(a.BoundingRectangle.Left, b.BoundingRectangle.Left);

        for (var y = top; y < bottom; y++)
        {
            for (var x = left; x < right; x++)
            {
                Color color1 = dataA[(x - a.BoundingRectangle.Left) + (y - a.BoundingRectangle.Top) * a.Width];
                Color color2 = dataB[(x - b.BoundingRectangle.Left) + (y - b.BoundingRectangle.Top) * b.Width];

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

        return false;
    }

When I run this code, I get OutOfRangeException when it tries to get the color out of the array. I am trying to achieve the following steps:

1) Extract the colors from both AnimatedSprites from their SpriteSheet only for the current frame that is drawing from the Animation

2) Check if any of the pixels in the intersecting rectangle are not transparent and return a collision.

An example of how the code will be called when checking Player movement capabilities:

                var nextPosition = (Sprite.Position + (motion * PlayerSpeedAmplifier));
                var playerTempRectangle = new Rectangle((int)nextPosition.X, (int)nextPosition.Y, PlayerCurrentRectangle.Width, PlayerCurrentRectangle.Height);
foreach (var enemy in listOfEnemies)
                {
                    if (playerTempRectangle.Intersects(enemy.EnemyCurrentRectangle))
                    {
                        if (Helper.CheckForPixelCollision(Sprite, enemy.Sprite))
                        {
                            canMove = false;
                            break;
                        }
                    }
                }

I hope someone can please help. Let me know if you need any additional information.

\$\endgroup\$
  • \$\begingroup\$ Keep in mind that per-pixel collision detection is going to be very slow and isn't really needed in most games. You might be putting a lot of time and energy into something that isn't really going to scale well anyway. \$\endgroup\$ – craftworkgames Jul 19 '18 at 4:22
0
\$\begingroup\$

I found an algorithm that works for my scenario.

https://www.youtube.com/watch?v=YxYRj2njBxE

\$\endgroup\$
  • 2
    \$\begingroup\$ Thanks for posting an answer! However this is currently a link only answer. Could you post the content of the video that solved your issue? (You can leave the link to the video in the answer. though.) \$\endgroup\$ – Alexandre Vaillancourt Jul 18 '18 at 18:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.