【问题标题】:Transform Scale Rotation Matrix For Per Pixel Collision为每个像素碰撞变换比例旋转矩阵
【发布时间】: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


【解决方案1】:

比例矩阵的 Z 值需要为 1。

Matrix.CreateScale(_Width, _Height, 1)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多