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.