I have pixel-perfect collision down, but it only works with the texture rotated at 0 radians. Here is my code for determining the pixel-perfect collision-
public static bool IntersectPixels(Texture2D sprite, Rectangle rectangleA, Color[] dataA, Texture2D sprite2, Rectangle rectangleB, Color[] dataB)
{
sprite.GetData<Color>(dataA);
sprite2.GetData<Color>(dataB);
// Find the bounds of the rectangle intersection
int top = Math.Max(rectangleA.Top, rectangleB.Top);
int bottom = Math.Min(rectangleA.Bottom, rectangleB.Bottom);
int left = Math.Max(rectangleA.Left, rectangleB.Left);
int right = Math.Min(rectangleA.Right, rectangleB.Right);
// Check every point within the intersection bounds
for (int y = top; y < bottom; y++)
{
for (int x = left; x < right; x++)
{
// Get the color of both pixels at this point
Color colorA = dataA[(x - rectangleA.Left) + (y - rectangleA.Top) * rectangleA.Width];
Color colorB = dataB[(x - rectangleB.Left) + (y - rectangleB.Top) * rectangleB.Width];
// If both pixels are not completely transparent,
if (colorA.A != 0 && colorB.A != 0)
{
// then an intersection has been found
return true;
}
}
}
// No intersection found
return false;
}
I am having trouble with my collision when it is rotated. How would I go about checking pixel collision with a rotated sprite? Thanks, any help is appreciated.
Ideally, you can exress all transformations with a matrix. That shouldn't be a problem with the helper methods. And if you use matrices, you can easily extend the program without having to change the collision code. Up to now, you can represent a translation with the position of the rectangle.
Let's assume object A has the transformation transA
and object B has transB
. Then you would iterate over all pixels of object A. If the pixel is not transparent, check which pixel of object B is at this very position and check if this pixel is transparent.
The tricky part is determining which pixel of object B is at a given position. This can be achieved with some matrix math.
You know the position in the space of object A. Firstly, we want to transform this local position to a global position on the screen. This is exactly what transA
does. After that, we want to transform the global location to a local location in the space of object B. This is the inverse of transB
. So, we have to transform the local position in A with the following matrix:
var fromAToB = transA * Matrix.Invert(transB);
//now iterate over each pixel of A
for(int x = 0; x < ...; ++x)
for(int y = 0; y < ...; ++y)
{
//if the pixel is not transparent, then
//calculate the position in B
var posInA = new Vector2(x, y);
var posInB = Vector2.Transform(posInA, fromAToB);
//round posInB.X and posInB.Y to integer values
//check if the position is within the range of texture B
//check if the pixel is transparent
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.