C#游戏编程:精灵碰撞

C#游戏编程:精灵碰撞,c#,sprite,C#,Sprite,我有一段关于C#游戏编程中精灵碰撞的C#代码片段,希望你们能帮我澄清一下 我不理解所收集的方法,尤其是计算d1和d2以确定精灵是否碰撞,在这种情况下矩阵反转()和多重hy的含义和使用,以及使用颜色alpha组件来确定两个精灵的碰撞 多谢各位 public struct Vector { public double X; public double Y; public Vector(double x, double y) { X = x; Y =

我有一段关于C#游戏编程中精灵碰撞的C#代码片段,希望你们能帮我澄清一下

我不理解所收集的方法,尤其是计算d1和d2以确定精灵是否碰撞,在这种情况下矩阵反转()和多重hy的含义和使用,以及使用颜色alpha组件来确定两个精灵的碰撞

多谢各位

public struct Vector
{
   public double X;
   public double Y;

   public Vector(double x, double y)
   {
      X = x;
      Y = y;
   }

   public static Vector operator -(Vector v, Vector v2)
   {
      return new Vector(v.X-v2.X, v.Y-v2.Y);
   }

   public double Length
   {
      get
      {
         return Math.Sqrt(X * X + Y * Y);
      }
   }
}

public class Sprite
{
    public Vector Position;
    protected Image _Image; 
    protected Bitmap _Bitmap;
    protected string _ImageFileName = "";
    public string ImageFileName
    {
       get { return _ImageFileName; }
       set
       {
          _ImageFileName = value;
          _Image = Image.FromFile(value);
          _Bitmap = new Bitmap(value);
        }
     }

    public Matrix Transform
    {
      get
      {
            Vector v = Position;
            if (null != _Image)
               v -= new Vector(_Image.Size) / 2;

            Matrix m = new Matrix();
            m.RotateAt(50.0F, new PointF(10.0F, 100.0F));
            m.Translate((float)v.X, (float)v.Y);
            return m; 
       }
    }

    public bool IsCollided(Sprite s2)
    {
        Vector v = this.Position - s2.Position;
        double d1 = Math.Sqrt(_Image.Width * _Image.Width + _Image.Height * _Image.Height)/2;
       double d2 = Math.Sqrt(s2._Image.Width * s2._Image.Width + s2._Image.Height * s2._Image.Height)/2;
       if (v.Length > d1 + d2)
           return false;

        Bitmap b = new Bitmap(_Image.Width, _Image.Height);
        Graphics g = Graphics.FromImage(b);
        Matrix m = s2.Transform;

        Matrix m2 = Transform;
        m2.Invert();

        Matrix m3 = m2;
        m3.Multiply(m);

        g.Transform = m3;

        Vector2F v2 = new Vector2F(0,0);
        g.DrawImage(s2._Image, v2);

        for (int x = 0; x < b.Width; ++x)
           for (int y = 0; y < b.Height; ++y)
           {
              Color c1 = _Bitmap.GetPixel(x, y);
              Color c2 = b.GetPixel(x, y);

              if (c1.A > 0.5 && c2.A > 0.5)
                  return true;
            }

       return false;
    }
}
公共结构向量
{
公共双X;
公共双Y;
公共向量(双x,双y)
{
X=X;
Y=Y;
}
公共静态向量运算符-(向量v,向量v2)
{
返回新向量(v.X-v2.X,v.Y-v2.Y);
}
公共双倍长度
{
得到
{
返回Math.Sqrt(X*X+Y*Y);
}
}
}
公共级雪碧
{
公共媒介立场;
受保护的图像\u图像;
受保护位图\u位图;
受保护字符串_ImageFileName=“”;
公共字符串ImageFileName
{
获取{return\u ImageFileName;}
设置
{
_ImageFileName=值;
_Image=Image.FromFile(值);
_位图=新位图(值);
}
}
公共矩阵变换
{
得到
{
向量v=位置;
如果(空!=\u图像)
v-=新向量(_Image.Size)/2;
矩阵m=新矩阵();
m、 旋转(50.0F,新点F(10.0F,100.0F));
m、 平移((浮动)v.X,(浮动)v.Y);
返回m;
}
}
公共图书馆(Sprite s2)
{
向量v=该位置-s2位置;
双d1=数学.Sqrt(_Image.Width*_Image.Width+_Image.Height*_Image.Height)/2;
double d2=数学Sqrt(s2.\u Image.Width*s2.\u Image.Width+s2.\u Image.Height*s2.\u Image.Height)/2;
如果(v.长度>d1+d2)
返回false;
位图b=新位图(_Image.Width,_Image.Height);
图形g=图形。来自图像(b);
矩阵m=s2.变换;
矩阵m2=变换;
m2.倒置();
矩阵m3=m2;
m3.乘以(m);
g、 转换=m3;
向量2f v2=新向量2f(0,0);
g、 DrawImage(s2._图像,v2);
对于(int x=0;x0.5和c2.A>0.5)
返回true;
}
返回false;
}
}

有点复杂。两部分:

第一部分(简单快速)

第一部分(涉及v,d1+d2)可能令人困惑,因为图像的尺寸不是使用方框进行碰撞测试,而是用于构造边界圆。然后使用这些边界圆进行简单的碰撞测试。这是一个“快速n脏”测试,可以消除明显没有碰撞的精灵

“如果两个圆的半径之和大于其中心之间的距离,则两个圆重叠。因此,毕达哥拉斯认为,如果:

(cx1-cx2)2+(cy1-cy2)2<(r1+r2)2“

请参阅此答案底部的和第二个链接

注释代码:

// Get the vector between the two sprite centres
Vector v = this.Position - s2.Position;

// get the radius of a circle that will fit the first sprite
double d1 = Math.Sqrt(_Image.Width * _Image.Width + _Image.Height * _Image.Height)/2;

// get the radius of a circle that will fit the second sprite
double d2 = Math.Sqrt(s2._Image.Width * s2._Image.Width + s2._Image.Height * s2._Image.Height)/2;

// if the distance between the sprites is larger than the radiuses(radii?) of the circles, they do not collide
if (v.Length > d1 + d2)
       return false;
注意:您可能需要考虑使用轴向对齐的边界框测试,而不是此处的圆。如果你有宽度和长度不同的矩形,这将是一个更有效/准确的第一次测试

第二部分(较慢)

我没有时间100%检查代码,但第二部分——在第一步中确定两个精灵可能发生碰撞——正在执行更复杂的碰撞测试。它正在使用精灵的图像源(特别是其alpha通道)执行每像素碰撞测试。在游戏中,alpha通道通常用于存储透明度的表示。值越大,图像越不透明(因此0将是100%透明,1.0f将是100%不透明)

在显示的代码中,如果两个精灵中的像素重叠,并且两个精灵的alpha值均大于0.5f,则像素共享相同的空间并表示实心几何体,因此发生碰撞。通过执行此测试,这意味着在测试碰撞时不会考虑精灵的透明(读取:不可见)部分,因此您可以拥有在拐角处不碰撞的圆形精灵等


以下是。

除非精灵图像的大小发生变化,否则如果不在每次调用边界圆时计算边界圆的大小,快速肮脏测试会快得多。您也可以像这样比较平方空间中的球体:(cx1-cx2)+(cy1-cy2)<(r1+r2);节省了每次计算平方根的开销。贾斯珀:是的,肯定是:)我有时间的时候会把它加到答案上。非常感谢你们。你给了我很多启发,但我仍然不明白为什么他们在这里使用逆矩阵,逆矩阵在这种情况下以及在精灵动画中的作用是什么,因为我看到他们使用父精灵的逆矩阵,然后在整个程序中用它乘以子精灵的矩阵。歌舞伎:对不起,我真的没什么意思。