我一直在 XNA 中制作一个需要矩形碰撞地图的自上而下的射击游戏。
地图的碰撞墙以以下格式存储在文本文件中:rect[0,0,1024,8]
这些值对应于定义一个矩形(x、y、宽度、高度)。
我一直在想我可以编写一个单独的应用程序,它可以对地图图像的数据进行文盲,找出黑色(或墙壁的任何颜色)的像素并在那里制作矩形。基本上,该程序将生成碰撞所需的矩形。理想情况下,它应该是像素完美的,这将需要大约一千个矩形,每个 1 像素宽,覆盖所有墙壁。
有没有一种可能的方法来检测这些矩形(或我应该说的正方形)中的哪些彼此相邻,然后将它们连接到更大(但仍覆盖相同区域)的矩形中?
例如。假设我有一堵 10 x 2 的墙。该程序将生成 20 个不同的矩形,每个矩形高 1 个像素。我如何有效地检测这些矩形是相邻的并自动制作一个 10 x 2 的矩形覆盖整个墙壁,而不是拥有 20 个不同的小像素矩形?
编辑:我已经制定了一个适合我的目的的解决方案,以供将来参考,我的代码如下:
//map is a bitmap, horizontalCollisions and collisions are List<Rectangle>s
for (int y = 0; y < map.Height; y++) //loop through pixels
{
for (int x = 0; x < map.Width; x++)
{
if (map.GetPixel(x, y).Name == "ff000000") //wall color
{
int i = 1;
while (map.GetPixel(x + i, y).Name == "ff000000")
{
if (i != map.Width - x)
{
i++;
}
if (i == map.Width - x)
{
break;
}
}
Rectangle r = new Rectangle(x, y, i, 1);//create and add
x += i - 1;
horizontalCollisions.Add(r);
}
}
}
for (int j = 0; j < horizontalCollisions.Count; j++)
{
int i = 1;
Rectangle current = horizontalCollisions[j];
Rectangle r = new Rectangle(current.X, current.Y + 1, current.Width, 1);
while(horizontalCollisions.Contains(r))
{
i++;
horizontalCollisions.Remove(r);
r = new Rectangle(current.X, current.Y + i, current.Width, 1);
}
Rectangle add = new Rectangle(current.X, current.Y, current.Width, i);
collisions.Add(add);
}
//collisions now has all the rectangles
基本上,它将水平循环遍历像素数据。当它遇到一个墙壁像素时,它会停止计数器并(使用一个while循环)将计数器向右移动,一个接一个,直到它碰到一个非墙壁像素。然后,它将创建一个该宽度的矩形,然后继续。在这个过程之后,将会有一个大的矩形列表,每个 1px 高。基本上,一堆水平线。下一个循环将遍历水平线,并使用与上面相同的过程,它将找出其下是否存在具有相同X值和相同Width值(y + 1)的矩形。这将不断增加,直到没有,其中将创建一个大矩形,并从列表中删除使用的矩形。