我一直在XNA上制作一个自上而下的射击游戏,需要矩形碰撞地图。自动合并相邻的矩形
用于地图的碰撞壁被存储在文本文件中的格式:rect[0,0,1024,8]
的值对应于限定的矩形(X,Y,宽度,高度)。
我一直在想,我可以编写一个单独的应用程序,可以通过地图图像的数据文盲,找出黑色(或任何颜色的墙)的像素,并在那里做矩形。基本上,该程序将生成碰撞所需的矩形。理想情况下,这将是像素完美的,这将需要像一千个矩形,每个1像素宽,涵盖所有的墙壁。
有没有可能的方法来检测这些矩形(或应该说是正方形)中的哪一个彼此相邻,然后将它们连接到更大(但仍覆盖相同区域)矩形?
EG。假设我有一个10乘以2的墙。该程序将生成20个不同的矩形,每个矩形高1个像素。我将如何有效地检测到这些矩形是相邻的,并自动制作一个覆盖整个墙的10乘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值和相同宽度值(y + 1)的矩形。这将继续增加,直到没有,将创建一个大的矩形,并从列表中删除使用的矩形。最终的结果列表包含了构成图像上所有黑色像素的所有矩形(我认为效率很高)。
感谢您的帮助,我浏览了部分论文(并且很害怕),但是我已经写了一些基本的通用代码,可以帮助我。我不需要它是超级有效的。我用我的代码和解释编辑了我的原始问题。希望它能帮助未来的人们。 –