【发布时间】:2014-06-02 11:31:16
【问题描述】:
我正在尝试使用缩放的纹理 2ds 进行每个像素的碰撞。 它目前没有检测到碰撞,我不知道为什么。
这里是我创建矩阵变换的地方。
private void BuildMatrix()
{
// Build the transformation matrix
Matrix TransformMatrix =
// _Rect.center.x and .y get the centers as this object is based off of a single square pixel.
Matrix.CreateTranslation(new Vector3(-_Rect.Center.X, -_Rect.Center.Y, 0.0f)) *
// _Width is the scale width and height is scale height.
Matrix.CreateScale(_Width, _Height, 0) *
// This one does not have rotation.
Matrix.CreateRotationZ(0) *
// Rect.X / Y are the top left X / Y coordinates for that rectangle.
Matrix.CreateTranslation(new Vector3(_Rect.X, _Rect.Y, 0.0f));
}
这是另一个构建矩阵。
private void BuildMatrix()
{
// Build the transformation matrix
Matrix TransformMatrix =
// The location.center is the center of the texture 2d. Where it is placed on the screen.
Matrix.CreateTranslation(new Vector3(-Location.Center, 0.0f)) *
// Size width / height are the size of the texture after it is scaled.
Matrix.CreateScale(Size.Width, Size.Height, 0) *
// No rotation.
Matrix.CreateRotationZ(0) *
// Location.Position is the is the top coordinates for the texture2d before scaling.
Matrix.CreateTranslation(new Vector3(Location.Position, 0.0f));
}
这里是每像素方法。
public static bool IntersectPixels( Matrix transformA, int widthA, int heightA, Color[] dataA, Matrix transformB, int widthB, int heightB, Color[] dataB)
{
// Calculate a matrix which transforms from A's local space into
// world space and then into B's local space
Matrix transformAToB = transformA * Matrix.Invert(transformB);
// When a point moves in A's local space, it moves in B's local space with a
// fixed direction and distance proportional to the movement in A.
// This algorithm steps through A one pixel at a time along A's X and Y axes
// Calculate the analogous steps in B:
Vector2 stepX = Vector2.TransformNormal(Vector2.UnitX, transformAToB);
Vector2 stepY = Vector2.TransformNormal(Vector2.UnitY, transformAToB);
// Calculate the top left corner of A in B's local space
// This variable will be reused to keep track of the start of each row
Vector2 yPosInB = Vector2.Transform(Vector2.Zero, transformAToB);
// For each row of pixels in A
for (int yA = 0; yA < heightA; yA++)
{
// Start at the beginning of the row
Vector2 posInB = yPosInB;
// For each pixel in this row
for (int xA = 0; xA < widthA; xA++)
{
// Round to the nearest pixel
int xB = (int)Math.Round(posInB.X);
int yB = (int)Math.Round(posInB.Y);
// If the pixel lies within the bounds of B
if (0 <= xB && xB < widthB &&
0 <= yB && yB < heightB)
{
// Get the colors of the overlapping pixels
Color colorA = dataA[xA + yA * widthA];
Color colorB = dataB[xB + yB * widthB];
// If both pixels are not completely transparent,
if (colorA.A != 0 && colorB.A != 0) { return true; } // then an intersection has been found
}
// Move to the next pixel in the row
posInB += stepX;
}
// Move to the next row
yPosInB += stepY;
}
// No intersection found
return false;
}
这是对每像素碰撞的调用。
(Statistics.IntersectPixels(Projectile.TransformMatrix, Projectile.Txt2DImage.Width,
Projectile.Txt2DImage.Height, Projectile.TextureColorArr,
TextBoxContainer.Pillar.TransformMatrix, (int)TextBoxContainer.Pillar.Width,
(int)TextBoxContainer.Pillar.Height, TextBoxContainer.Pillar.TextureColorArr)).ToString();
【问题讨论】:
-
通常更好地管理与框和圆的碰撞。为了解决您的问题,我将使用两个已知的轴对齐框对其进行调试,一个可以是(0,0,100,100),另一个可以是(100,0,100,100),并会在 A 空间中给出值以将它们转换为 B 空间,(0, 0) 在 A 中,应该是 (-100,0) 在 B...等
-
其实代码看起来不错。你检查过矩阵是否正确吗?
SpriteBatch的重载为Draw(),它采用矩阵。有了这个,您可以检查矩阵是否是您的想法。 -
当我为每个矩阵显示变换矩阵时,上面的所有矩阵都显示为 0。我认为这是不正确的,因为弹丸被缩小了 0.025f 并且柱子是 500 x 500 平方。
-
我发现它为什么没有更新。所有的值都不再是 0,但它仍然不起作用。
-
柱子的矩阵显示 M41 : -179890 / M42 : -402444 / M43 : 0 / M44 : 1
标签: c# xna collision-detection xna-4.0 collision