我正在制作一个太空射击游戏,它发生在一个大型地牢中,该地牢由大型矩形组成,用于定义墙壁。使用Farseer Physics对游戏中的所有内容进行物理模拟。但是有一个问题:我希望地牢看起来足够大,但这需要我的网格中至少有80x80个矩形,这意味着在最坏的情况下,我有6400个物理模拟的物体,这不完全是性能友好,你可以猜到。
我的临时解决方案是在垂直切片中划分网格,这样,对于每一列,使用布尔添加操作添加所有矩形,然后使用生成的凹多边形创建一个主体。它会稍微提高性能,但是多边形容易陷入混乱,变得不存在,阻塞通常应该遍历的方式甚至变得无效并导致Farseer崩溃。
我一直在考虑制作某种算法,以某种方式找到最大的墙壁区域,并将它们合并为一个大矩形,并继续为较小的矩形做这个,直到所有的孔都被填满,但我不知道如何实现这一点。它似乎是完美的解决方案,因为它解决了性能问题以及我现在所拥有的凹形多边形混乱。有没有人知道如何实现这样的东西?
完全停止使用物理引擎并不是一个解决方案,因为我游戏中的很多东西都依赖它。
编辑:这是一个关于身体现在如何看起来的一个小例子:(每个数字都是一个身体)
这就是我希望他们成为的样子:
答案 0 :(得分:1)
我可能没有正确理解这个问题,但是让我提出一个算法,我认为这有点暗示解决你的问题。
您的问题始于矩形贪婪,其中正方形免费和非免费。从一开始, free 正方形是我们要用它们构建墙的方格,非自由正方形是空心空间。
完成后,您应该将最大可能的墙块组合在一起。
通过围绕 free 方块的扩展来澄清,我的意思是在所有可用方向上从给定方块开始构建假设的最大矩形。
矩阵n*m
矩阵的此算法的复杂性直观地围绕O(n*n*m*m)
。在实践中,我认为你的数据会很快。请注意,此算法不提供最少数量的对象,而是最大化所有区域的总和(根据您的问题)。我认为,就复杂性而言,最小化身体总数的问题要困难得多。
答案 1 :(得分:1)
这是我在我的一个游戏中使用的(不是在C#中):
首先创建一个包含实心墙的数组,创建一个类似Wall
的结构,其中包含x
,y
,width
和height
,很多,每个街区一个。
然后循环遍历它们并合并具有相同y
和height
的那些,并且是邻居(x₁ + width₁ = x₂
)。
然后再次循环,这次使用x
代替y
(反之亦然),并使用width
代替height
(反之亦然)。
这未经过优化,但您可以对其进行修改以加快速度。这是我在游戏中使用的实现,对你来说可能太慢了。
运行它会生成38个实体(与您发布的示例中的实体数量相同):
在最后两个步骤中颠倒顺序会生成36个实体:
答案 2 :(得分:0)
使用Farseer时,应使用 EDGES ,而不是使用如此多的实体构建地图/世界/等级,这可能会导致性能问题。
如果您能找到将地图转换为连续顶点坐标列表的方法,可能是跟踪墙并生成列表的算法,那么您可以这样做......
创建1个主体并添加FIRST边缘:
Body dungeon = BodyFactory.CreateEdge(world, start, end);
然后按顺序循环遍历所有其他顶点坐标,然后将每个新边连接到前一个边端坐标。 (按顺序将边缘链接在一起直到完成)
FixtureFactory.AttachEdge(start, end, dungeon);
这导致1个身体而不是35 +。