1

我一直在 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)的矩形。这将不断增加,直到没有,其中将创建一个大矩形,并从列表中删除使用的矩形。

4

1 回答 1

1

礼仪可能会建议我应该对此发表评论而不是将其添加为答案,但我还没有这种能力,所以请耐心等待。

恐怕我无法为您将其翻译成代码,但我可以向您发送一些学术论文,这些论文讨论可以完成您所要求的某些事情的算法。

其他时间出现了这个问题:

这些问题中链接的论文:

希望这些问题和论文可以帮助您找到您正在寻找的答案,或者至少吓跑您寻找另一个解决方案。

于 2012-12-09T05:26:15.540 回答