在旋转的精灵上实现每个像素的碰撞 [英] Implementing per pixel collision on rotated sprites

查看:64
本文介绍了在旋转的精灵上实现每个像素的碰撞的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用C#在XNA中构建2D游戏,并且我使用的精灵将跟踪玩家的位置并在spritebatch.Draw()方法中相应地旋转。我现在正在尝试实现每个像素的碰撞检测,并且我相信子画面的旋转会使其消失。冲突检查如下。

 私人布尔冲突(矩形对象1,颜色[,]数据A,矩形对象2,颜色[, ] dataB)
{

if(object1.Bottom&object2.Top)
return perPixel(object1,dataA,object2,dataB);
if(object1.Top> object2.Bottom)
返回perPixel(object1,dataA,object2,dataB);
if(object1.Left> object2.Right)
返回perPixel(object1,dataA,object2,dataB);
if(object1.Right< object2.Left)
返回perPixel(object1,dataA,object2,dataB);

返回true;
}

私人布尔值perPixel(Rectangle object1,Color [,] dataA,Rectangle object2,Color [,] dataB)
{
//碰撞范围
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);

//检查每个像素
是否为(int y = top; y< bottom; y ++)
{
for(int x = left; x<右; x ++)
{
颜色colourA = dataA [x,y];
颜色colourB = dataB [x,y];

如果(colourA.A!= 0&& colourB.A!= 0)
{
返回true;
}
}
}
返回false;
}

只有一组被检查的精灵会旋转,如果那样的话

解决方案

当我对旋转的sprit进行碰撞检测时,我遇到了一个非常相似的问题。
我基本上所做的是旋转由spriteBatch.Draw()的旋转参数传递的角度,旋转由spriteBatch.Draw()

传递的角度。

  RectangleofSpriteToBeRotated {中的每个X 
中的每个X RectangleofSpriteToBeRotated {

Vector2 temp = Vector2.Transform(PointXY,Matrix.CreateRotationZ(Theta));
//将点温度保存在新的2D数组中
}
}

如果您确实不明白我在说什么,请发表评论,我会尽力阐述。



更新:
您应该尝试这样做,我假设应该旋转第二个Sprite,但我没有运行此代码

 私人布尔冲突(矩形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)
返回perPixel(object1,dataA,object2,dataB);
if(object1.Left> RotatedP1.X)
返回perPixel(object1,dataA,object2,dataB);
if(object1.Right< RotatedP0.X)
return perPixel(object1,dataA,object2,dataB);

返回true;
}

私人布尔值perPixel(Rectangle object1,Color [,] dataA,Rectangle object2,Color [,] dataB)
{
//碰撞范围
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);

//检查每个像素
是否为(int y = top; y< bottom; y ++)
{
for(int x = left; x<右; x ++)
{

颜色colourA = dataA [x,y];

Vector2 v = Vector2.Transform(new Vector2(x,y),Matrix.CreateRotationZ(theta));

颜色colourB = dataB [(int)v.X,(int)v.Y];

如果(colourA.A!= 0&& colourB.A!= 0)
{
返回true;
}
}
}
返回false;
}


I am building a 2D game in XNA using C#, and I am using sprites that will track the player's position and rotate accordingly in the spritebatch.Draw() method. I am now trying to implement per-pixel collision detection, and I believe that the rotation of the sprites is throwing it off. The collision checks are as follows.

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;
    }

Only one of the sets of sprites being checked against will be rotated, if that will help.

解决方案

I faced a very similar problem , when i was doing collision detection on a rotated sprited. What i basically did was rotate the rectangle bounding the sprite by an angle theta , here theta was the angle passed in the rotation parameter of spriteBatch.Draw()

A very naive implementation of what i am saying is.

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 
    }
}

If you do/did not understand what i am saying then please comment , i will try to elaborate.

Update: You should try doing this, I am assuming that the Second Sprite should be rotated, i haven't run this code

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;
    }

这篇关于在旋转的精灵上实现每个像素的碰撞的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆