我一直专注于寻找从一个地方到另一个地方的路径的任务。然而,一个同样重要的问题是:一旦我有了一条路径,我该如何沿着它前进?最明显的答案是从一个位置直线移动到另一个位置。但是,您可能还想在曲线中移动,或进行多个级别的移动。您可能希望将这些位置视为您偏离的低优先级目标。更高层次的问题是:你想去哪里?除非您首先回答更高级别的问题,否则寻路不是很有用。当然,目标设置的一种形式是要求用户点击目的地。但是,您可能也有自动化任务——探索、监视、攻击和构建是常见的任务。 单位移动#我专注于寻路,这减少了从一个位置移动到另一个位置的问题,以及从一个空间移动到相邻空间的许多较小问题。 您可以从一个位置直线移动到下一个位置,但也有其他选择。考虑此图中的四个运动路径: 红色路径是标准方法:从一个正方形的中心移动到下一个正方形的中心。绿色路径更好一些:在瓷砖之间的边缘之间以直线移动,而不是在瓷砖的中心。您也可以尝试在瓷砖的角之间沿直线移动。蓝色路径使用样条,深蓝色是低阶样条,浅蓝色是高阶样条。 瓷砖角和边缘之间的线将是最短的解决方案。然而,样条可以让你的单位看起来不那么机械,更“有活力”。这是一个便宜的技巧,但不是一个很好的技巧。有更好的方法来处理运动。 如果您的单位无法轻松转动,您可能需要在绘制移动路径时考虑到这一点。Craig Reynolds 有一个关于转向的很棒的页面,其中有一篇关于转向和演示各种行为的 Java 小程序的论文。如果你有不止一个单位沿着一条路径移动,你可能还想调查成群结队。克雷格建议,不要将路径视为您的单位必须访问的地方列表,而是将路径视为“指导方针,您可以根据情况做出反应偏离”。 如果您使用网格进行寻路,您的单位不受网格限制,并且移动成本是统一的,则您可能希望通过从一个节点直线移动到远处一个节点,并且在两者之间没有障碍的情况下拉直路径他们俩。如果您使用导航网格,请查看漏斗算法。 行为标志或堆栈#您的单位可能有多个目标。例如,您可能有一个像“间谍”这样的总体目标,但也有一个更直接的目标,比如“去敌军总部”。此外,可能还有“避开那个巡逻守卫”之类的临时目标。以下是一些关于目标的想法:
对于每个单元,您可以有一个标志,指示它要执行的行为。要具有多个级别,请保留一个行为堆栈。堆栈顶部将是最直接的目标,堆栈底部将是总体目标。当你需要做一些新的事情但后来又想回到你正在做的事情上时,把一个新的行为推到堆栈上。如果您不是需要做一些新的东西,但不希望回到老问题,清除栈。完成某个目标后,将其从堆栈中弹出并开始在堆栈上执行下一个行为。 等待运动#运动算法不可避免地会遇到寻路过程中不存在的障碍。一种易于实施的技术基于其他障碍物将首先移动的假设。当障碍物是友方单位时,这特别有用。当障碍物挡在路上时,等待一段时间让它移动。如果在那段时间之后它仍然没有移动,请重新计算围绕它或到达目的地的路径。如果提前检测到障碍物,您的单位可以简单地走得更慢,让另一个单位有更多时间让开。 两个单位可能会相互碰撞,每个单位都会等待对方继续前进。在这种情况下,可以使用优先级方案:为每个单元分配一个唯一编号,然后让编号较低的单元等待编号较高的单元。如果两个单元都在等待,这将强制其中一个单元继续。当提前检测到障碍物时,编号较低的单元应在到达预期碰撞点之前减速。 协调运动#当单位试图通过狭窄的走廊时,上述技术不起作用。如果一个单位站着不动而另一个单位试图绕过,则两个单位都不能使用走廊。一个单位会阻止它,而另一个单位会绕很长一段路。 第二个单元应该可以与第一个单元通信,并要求它备份。一旦走廊畅通,第二个单元可以通过,然后第一个单元可以通过。除非您能事先确定走廊,否则实施起来可能很复杂。对于随机生成的地图,可能很难确定走廊的位置以及第一个单位需要后退多远。 |
|