Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm RTS游戏中视线计算的快速算法_Algorithm_Optimization_Big O_Math - Fatal编程技术网

Algorithm RTS游戏中视线计算的快速算法

Algorithm RTS游戏中视线计算的快速算法,algorithm,optimization,big-o,math,Algorithm,Optimization,Big O,Math,我正在做一个简单的RTS游戏。我希望它运行得非常快,因为它应该与数千个单位和8名球员 一切似乎都完美无瑕,但视线计算似乎是一个瓶颈。很简单:如果一个敌方单位比我的任何一个单位的视距都近,它就会被看见 目前,我使用了一种非常简单的算法:对于每一个敌人单位,我都会检查我的任何单位是否看到了他。是O(n^2) 因此,如果有8个玩家,每个玩家有3000个单位,这意味着在最坏的情况下,每个玩家有3000*21000=63000000个测试。这相当慢 更多细节:这是一个愚蠢的简单2D空间RTS:没有网格,每

我正在做一个简单的RTS游戏。我希望它运行得非常快,因为它应该与数千个单位和8名球员

一切似乎都完美无瑕,但视线计算似乎是一个瓶颈。很简单:如果一个敌方单位比我的任何一个单位的视距都近,它就会被看见

目前,我使用了一种非常简单的算法:对于每一个敌人单位,我都会检查我的任何单位是否看到了他。是O(n^2)

因此,如果有8个玩家,每个玩家有3000个单位,这意味着在最坏的情况下,每个玩家有3000*21000=63000000个测试。这相当慢

更多细节:这是一个愚蠢的简单2D空间RTS:没有网格,每个单元都沿着直线移动,并且没有碰撞,所以它们可以相互移动。因此,即使在同一地点也可能有数百个单位

我想以某种方式加速这个服务水平算法。有什么想法吗

编辑:

因此,其他细节:

  • 我的意思是一个玩家甚至可以拥有3000个单位
  • 我的部队有雷达,所以他们向各个方向都是一样的
使用a按位置高效查找单元

此外,如果您只关心某个单元是否可见,而不关心哪个单元发现了它,那么您可以这样做

for each unit
    mark the regions this unit sees in your spatial data structure
并已:

isVisible(unit) = isVisible(region(unit))
一个非常简单的空间数据结构是网格:在运动场上覆盖一个粗糙的网格。区域是该栅格的单元。您分配一个区域数组,并为每个区域保留该区域当前的单元列表


你可能也会发现这很有用。

gamedev中最基本的规则之一是利用游戏性定义的所有可能约束来优化算法中的bejeebers-这是你看不到在任何给定公司游戏引擎上构建的完全不同的游戏的主要原因,他们已经如此有效地利用了他们的约束,以至于他们无法处理任何不在这些约束范围内的事情

也就是说,你说单位是直线移动的——你说玩家可以移动3000个单位——即使我假设8名玩家可以移动3000个单位,也就是每个玩家375个单位,所以我认为我可以安全地假设在游戏的每一步(我假设每一步都涉及到你上面描述的计算)不改变方向的单位比改变方向的单位多

所以,如果这是真的,那么你想把你所有的作品分成两组——在最后一步改变方向的作品和没有改变方向的作品

对于那些这样做的,你需要做一点计算——对于任何两个相反的力的单位,你想问‘当单位a和单位B都不改变方向或速度时,单位a什么时候会看到单位B’(你可以处理加速/减速,但它会变得更复杂)-要计算此值,您首先需要确定单元A和单元B所行驶的向量是否会相交(简单的二维直线相交计算,结合告诉您每个单元何时到达此相交点的计算)-如果它们不相交,并且现在无法看到彼此,那么,除非他们中至少有一个人改变方向,否则他们永远不会见面。如果它们确实相交,那么你需要计算第一辆和第二辆车通过交叉点时的时间差-如果该距离大于服务水平范围,那么这些车将永远不会看到对方,除非一辆车改变方向-如果该差小于服务水平范围,则再多几个(使劲挥手)计算会告诉你这一幸运事件何时发生

现在,你所拥有的是一个信息集合,分为永远不会看到彼此的元素和在未来某个时间t会看到彼此的元素-每一步,你只需处理改变方向的单元,并计算它们与其余单元的交互。(哦,处理那些之前的计算告诉你们会出现在彼此眼前的单元——记住将它们保存在一个可插入的有序结构中)您有效地利用了系统的线性行为,将您的问题从“A单元是否参见B单元”更改为“当A单元是否参见B单元时”


现在,所有这些都说,这不是折扣空间数据结构答案-这是一个很好的答案-但是,它也能够处理单位的随机运动,所以你想考虑如何进一步优化这个过程-你还需要小心处理跨区域可见性,即单位在边界的两个不同ent区域可能可以相互看到-如果你有容易聚集的片段,那么使用具有可变维度的空间数据结构可能是答案,不在同一区域的片段保证不能相互看到。

我会使用网格。我认为商业RTS游戏就是这样解决问题的

  • 为可见性跟踪器将游戏世界离散化。(方形网格最简单。尝试粗糙度,看看哪个值最有效。)
  • 记录每个区域的当前单位。(单位移动时更新。)
  • 记录每个玩家看到的区域。(这必须随着单位的移动而更新。单位可以轮询以确定其可见的分幅。或者你可以在游戏开始前分析地图。)
  • 为每个玩家看到的敌人单位制作一个列表(或任何合适的结构)
现在,每当装置从一个可视区域移动到另一个可视区域时,执行检查:

  • 从一个看不见的区域到一个看得见的区域-将该单位添加到玩家的可见性跟踪器中
  • 从看得见的区域转到看不见的区域-从玩家的可见性跟踪器中移除该单位
  • 在另外两个案例中,没有发生可见性变化
这很快,但是