在旋转精灵上实现每像素碰撞

本文关键字:像素 碰撞 实现 旋转 精灵 | 更新日期: 2023-09-27 17:49:30

我正在使用c#在XNA中创建一款2D游戏,我使用的精灵将在spritebatch.Draw()方法中跟踪玩家的位置并相应地旋转。我现在正在尝试执行逐像素的碰撞检测,我相信精灵的旋转会让它失效。冲突检查如下:

private bool collision(Rectangle object1, Color[,] dataA, Rectangle object2, Color[,] dataB)
    {
        if (object1.Bottom < object2.Top)
            return perPixel(object1, dataA, object2, dataB);
       if (object1.Top > object2.Bottom)
           return perPixel(object1, dataA, object2, dataB);
       if (object1.Left > object2.Right)
           return perPixel(object1, dataA, object2, dataB);
       if (object1.Right < object2.Left)
           return perPixel(object1, dataA, object2, dataB);
       return true;
    }
    private bool perPixel(Rectangle object1, Color[,] dataA, Rectangle object2, Color[,] dataB)
    {
        //Bounds of collision
        int top = Math.Max(object1.Top, object2.Top);
        int bottom = Math.Min(object1.Bottom, object2.Bottom);
        int left = Math.Max(object1.Left, object2.Left);
        int right = Math.Min(object1.Right, object2.Right);
        //Check every pixel
        for (int y = top; y < bottom; y++)
        {
            for (int x = left; x < right; x++)
            {
                Color colourA = dataA[x, y];
                Color colourB = dataB[x, y];
                if (colourA.A != 0 && colourB.A != 0)
                {
                    return true;
                }
            }
        }
        return false;
    }

如果有帮助的话,只有一组被检查的精灵会被旋转。

在旋转精灵上实现每像素碰撞

当我在旋转精灵上进行碰撞检测时,我遇到了一个非常类似的问题。我所做的就是旋转矩形以角度来包围精灵,这里的角度是spritebatch。draw ()

的旋转参数传递的角度

我所说的一个非常幼稚的实现是。

for each X in RectangleofSpriteToBeRotated{
   for each Y in RectangleofSpriteToBeRotated{
    Vector2 temp = Vector2.Transform(PointXY, Matrix.CreateRotationZ(Theta));
     //Save Point Temp in a new 2D Array 
    }
}

如果你不明白我在说什么,请评论,我会尽量详细说明。

更新:你应该尝试这样做,我假设第二个精灵应该旋转,我没有运行这段代码

private bool collision(Rectangle object1, Color[,] dataA, Rectangle object2, Color[,] dataB)
    {
    var  RotatedP0=  new Vector2.Transform( new Vector2( object2.Top,object2.Left ),Matrix.CreateRotationZ(theta));
    var  RotatedP1=  new Vector2.Transform( new Vector2 (object2.Bottom,object2.Right),Matrix.CreateRotationZ(theta ) );    

        if (object1.Bottom < RotatedP0.Y)
            return perPixel(object1, dataA, object2, dataB);
       if (object1.Top > RotatedP1.Y)
           return perPixel(object1, dataA, object2, dataB);
       if (object1.Left > RotatedP1.X)
           return perPixel(object1, dataA, object2, dataB);
       if (object1.Right < RotatedP0.X)
           return perPixel(object1, dataA, object2, dataB);
       return true;
    }
    private bool perPixel(Rectangle object1, Color[,] dataA, Rectangle object2, Color[,] dataB)
    {
        //Bounds of collision
        int top = Math.Max(object1.Top, object2.Top);
        int bottom = Math.Min(object1.Bottom, object2.Bottom);
        int left = Math.Max(object1.Left, object2.Left);
        int right = Math.Min(object1.Right, object2.Right);
        //Check every pixel
        for (int y = top; y < bottom; y++)
        {
            for (int x = left; x < right; x++)
            {
                Color colourA = dataA[x, y];
                Vector2 v = Vector2.Transform(new Vector2(x,y), Matrix.CreateRotationZ(theta));
                Color colourB = dataB[ (int) v.X, (int) v.Y];
                if (colourA.A != 0 && colourB.A != 0)
                {
                    return true;
                }
            }
        }
        return false;
    }