[翻译]XNA外文博客文章精选之four
PS:自己翻译的,转载请著明出处
2D精灵的碰撞检测
2D碰撞检测使用alpha通道很容易实现。
让我们看下下面一对图的alpha象素:
当两个非alpha象素重叠时出现一个碰撞:
让我们定义一个功能去检查两个矩形之间的碰撞:
1 public class Collision
1 public static bool Intersects(Rectangle a, Rectangle b)
2 {
3 // check if two Rectangles intersect
4 return (a.Right > b.Left && a.Left < b.Right && a.Bottom > b.Top && a.Top < b.Bottom);
5 }
现在棘手的部分是检查在两个alpha覆盖的纹理的碰撞:
2 {
3 // check if two Rectangles intersect
4 return (a.Right > b.Left && a.Left < b.Right && a.Bottom > b.Top && a.Top < b.Bottom);
5 }
1 public static bool Intersects(Sprite a,Sprite b)
让我们首先检查它们的矩形边框,看看是否互相相交:
1 if (Collision.Intersects(a.bounds, b.bounds))
并且从这个纹理中获取象素数据
1 uint[] bitsA = new uint[a.texture.Width * a.texture.Height];
2 a.texture.GetData<uint>(bitsA);
3 uint[] bitsB = new uint[b.texture.Width * b.texture.Height];
4 b.texture.GetData<uint>(bitsB);
现在让我们得到每个矩形重叠的部分:
2 a.texture.GetData<uint>(bitsA);
3 uint[] bitsB = new uint[b.texture.Width * b.texture.Height];
4 b.texture.GetData<uint>(bitsB);
1 int x1 = Math.Max(a.bounds.X, b.bounds.X);
2 int x2 = Math.Min(a.bounds.X + a.bounds.Width, b.bounds.X + b.bounds.Width);
3 int y1 = Math.Max(a.bounds.Y, b.bounds.Y);
4 int y2 = Math.Min(a.bounds.Y + a.bounds.Height, b.bounds.Y + b.bounds.Height);
现在我们知道每个纹理重叠的象素,我们简单通过这些象素来循环,并且测试出共同的象素,它们是不透明的。
2 int x2 = Math.Min(a.bounds.X + a.bounds.Width, b.bounds.X + b.bounds.Width);
3 int y1 = Math.Max(a.bounds.Y, b.bounds.Y);
4 int y2 = Math.Min(a.bounds.Y + a.bounds.Height, b.bounds.Y + b.bounds.Height);
1 for (int y = y1; y < y2; ++y)
2 {
3 for (int x = x1; x < x2; ++x)
4 {
检查alpha字节去看看它们是否超过20(这只是捏造的因素,确保任何的在纹理的杂质不会影响碰撞的检测)
2 {
3 for (int x = x1; x < x2; ++x)
4 {
1 if (((bitsA[(x - a.bounds.X) + (y - a.bounds.Y) * a.texture.Width] & 0xFF000000)>>24) > 20 &&((bitsB[(x - b.bounds.X) + (y - b.bounds.Y) * b.texture.Width] & 0xFF000000)>>24) > 20)
2 {
3 return true;
4 }
这里没有碰撞,让我们返回false
2 {
3 return true;
4 }
1 return false;
没有碰撞被发现:碰撞被检测到:
源代码:http://www.ziggyware.com/readarticle.php?article_id=48
(完)