C# - 每像素碰撞检测
C# - Per Pixel Collision Detection
这是我正在制作 2D 迷宫游戏 (XNA 4.0) 的情况。我发现进行碰撞检测的最佳方法是使用逐像素检测。在互联网上搜索时,我发现有人在解释或展示两种碰撞的代码(即鼠标和播放器、播放器和播放器、两种形状)。我想做的是让这个碰撞检测玩家是否与墙壁碰撞(背景是黑色的,但迷宫的墙壁是白色的)。有人可以解释如何执行此操作或提供代码的某种起点。非常感谢。
P.S。 link 到网站或任何与我的问题相关的内容也会有帮助
创建一个代表您的精灵的布尔矩阵和一个代表您的迷宫的布尔矩阵(代表您的精灵的矩阵需要与您的迷宫具有相同的尺寸)。
然后你可以做一些简单的事情,比如遍历所有 x-y 坐标并检查它们是否都为真
// as an optimization, store a bounding box to minimize the
// coordinates of what you need to check
for(int i = 0; i < width, i++) {
for(int j = 0; j < height, j++) {
if(sprite[i][j] && maze[i][j]) {
collision = true
//you might want to store the coordinates
}
}
}
如果你想要非常花哨,你可以展平你的迷宫矩阵并使用位运算
完成此 CPU 密集型操作的最佳方法是先检查碰撞盒碰撞,然后再检查每像素碰撞。
大部分代码都可以在这个有用的 video 中找到。
static bool IntersectsPixel(Rectangle hitbox1, Texture2D texture1, Rectangle hitbox2, Texture2D texture2)
{
Color[] colorData1 = new Color[texture1.Width * texture1.Height];
texture1.GetData(colorData1);
Color[] colorData2 = new Color[texture2.Width * texture2.Height];
texture2.GetData(colorData2);
int top = Math.Max(hitbox1.Top, hitbox2.Top);
int bottom = Math.Min(hitbox1.Bottom, hitbox2.Bottom);
int right = Math.Max(hitbox1.Right, hitbox2.Right);
int left = Math.Min(hitbox1.Left, hitbox2.Left);
for(y = top; y< bottom; y++)
{
for(x = left; x < right; x++)
{
Color color1 = colorData1[(x - hitbox1.Left) + (y - hitbox1.Top) * hitbox1.Width]
Color color2 = colorData2[(x - hitbox2.Left) + (y - hitbox2.Top) * hitbox2.Width]
if (color1.A != 0 && color2.A != 0)
return true;
}
}
return false;
}
你可以这样调用这个方法:
if (IntersectsPixel(player.hitbox, player.texture, obstacle.hitbox, obstacle.texture))
{
// Action that happens upon collision goes here
}
希望能帮到你,
- GHC
这是我正在制作 2D 迷宫游戏 (XNA 4.0) 的情况。我发现进行碰撞检测的最佳方法是使用逐像素检测。在互联网上搜索时,我发现有人在解释或展示两种碰撞的代码(即鼠标和播放器、播放器和播放器、两种形状)。我想做的是让这个碰撞检测玩家是否与墙壁碰撞(背景是黑色的,但迷宫的墙壁是白色的)。有人可以解释如何执行此操作或提供代码的某种起点。非常感谢。
P.S。 link 到网站或任何与我的问题相关的内容也会有帮助
创建一个代表您的精灵的布尔矩阵和一个代表您的迷宫的布尔矩阵(代表您的精灵的矩阵需要与您的迷宫具有相同的尺寸)。
然后你可以做一些简单的事情,比如遍历所有 x-y 坐标并检查它们是否都为真
// as an optimization, store a bounding box to minimize the
// coordinates of what you need to check
for(int i = 0; i < width, i++) {
for(int j = 0; j < height, j++) {
if(sprite[i][j] && maze[i][j]) {
collision = true
//you might want to store the coordinates
}
}
}
如果你想要非常花哨,你可以展平你的迷宫矩阵并使用位运算
完成此 CPU 密集型操作的最佳方法是先检查碰撞盒碰撞,然后再检查每像素碰撞。
大部分代码都可以在这个有用的 video 中找到。
static bool IntersectsPixel(Rectangle hitbox1, Texture2D texture1, Rectangle hitbox2, Texture2D texture2)
{
Color[] colorData1 = new Color[texture1.Width * texture1.Height];
texture1.GetData(colorData1);
Color[] colorData2 = new Color[texture2.Width * texture2.Height];
texture2.GetData(colorData2);
int top = Math.Max(hitbox1.Top, hitbox2.Top);
int bottom = Math.Min(hitbox1.Bottom, hitbox2.Bottom);
int right = Math.Max(hitbox1.Right, hitbox2.Right);
int left = Math.Min(hitbox1.Left, hitbox2.Left);
for(y = top; y< bottom; y++)
{
for(x = left; x < right; x++)
{
Color color1 = colorData1[(x - hitbox1.Left) + (y - hitbox1.Top) * hitbox1.Width]
Color color2 = colorData2[(x - hitbox2.Left) + (y - hitbox2.Top) * hitbox2.Width]
if (color1.A != 0 && color2.A != 0)
return true;
}
}
return false;
}
你可以这样调用这个方法:
if (IntersectsPixel(player.hitbox, player.texture, obstacle.hitbox, obstacle.texture))
{
// Action that happens upon collision goes here
}
希望能帮到你,
- GHC