有许多游戏通常可以被视为通过空间展开的一堆对象,而一个非常常见的操作是选择子区域中的所有对象。典型的例子是在大型地图上有大量单位的游戏,以及影响某个半径内单位的爆炸。这需要拾取半径中的每个单位以应用爆炸效果。
现在,有几种方法可以存储允许有效选择子区域的对象。最简单的方法可能是将地图划分为网格;在一个区域中拣选单位将涉及仅选择受影响的网格部分,并在该区域内进行不是100%的细粒度坐标检查网格图块。
我不喜欢这种方法回答“网格瓷砖应该有多大?”太大,效率可能成为一个真正的问题。太小了,如果游戏世界足够大,网格占用大量内存(如果游戏是3d则可能变得荒谬)。甚至可能没有合适的中庸之道。
上面显而易见的解决方案是制作一个具有某种智能细分的大网格,如伪树结构。在这一点上,我确信我已经远远没有过早优化。 (然后有适当的动态quad / octree,但这对代码来说更复杂,我甚至不相信它会表现得更好。)
所以我的问题是:上述问题是否有标准解决方案?在STL容器的行中,可以只使用坐标存储任何对象,并在某个区域内检索对象列表的东西?它不必与我上面描述的不同,只要它是经过深思熟虑并被认为是“足够好”的东西。
如果在Python中有算法的实现,那么奖励点,但C也会这样做。
答案 0 :(得分:1)
编写实用程序的第一步是接受某些常量的选择来自现实世界的考虑,而不是超越性的数学真理。这尤其适用于游戏设计/世界模拟类型编码,如果您坚持尝试以最佳方式模拟现实世界,那么您将永远无法获得任何地方。 : - )
如果您的对象大小都相当均匀,我只需选择与平均对象大小成比例的网格大小,然后继续使用。这是最简单的 - 记住简单性会给你带来一些速度,即使你最终搜索的物体超过绝对必要的数量!
如果你的物体尺寸变化很大,事情变得更加困难 - 例如,如果你试图使用相同的引擎来处理子弹,老鼠,人类,巨型怪物,车辆,小行星,行星等等。如果这是在这种情况下,一种常见的(但丑陋)方法是根据您所处的情况类型而设置不同的“模式”。简而言之,一个想法可能是使用具有二叉树细分的大网格网格细胞累积了太多小物体之后。
一方面:如果你使用浮点坐标,你需要注意网格尺寸的精度和圆角问题,因为靠近原点的点比远处的点更精确,这可能导致网格单元遗漏某些对象的错误。
答案 1 :(得分:0)
Here is a free book available online将回答您的问题。 具体来看第18章关于碰撞检测和交叉。
答案 2 :(得分:0)
我对游戏编程一无所知,但我想(基于直觉和我过去读过的内容),对于大空间来说,完整的网格效率会非常低;你会在存储和时间上都失败,因为你会融化缓存。
STL容器基本上是一维的。是的,set
和map
之类的内容允许您定义任意排序关系,但它仍然只在一个维度中排序。如果你想做得更好,你可能需要使用四叉树,kd树或类似的东西。