2

我正在开发一款游戏(使用 Game Maker:Studio Professional v1.99.355),它需要同时具有用户可修改的关卡几何和基于平台物理的 AI 寻路。因此,我需要一种方法来动态确定可以从哪些其他平台访问哪些平台,以便构建可以提供给 A* 的节点图。

我目前的方法或多或少是这样的:

  1. 对于每个平台,请考虑关卡中的其他平台。

  2. 对于这些平台中的每一个,如果它明显无法到达(例如,由于高于最大跳跃高度),则不要形成链接并移动到下一个平台。

  3. 如果链接似乎可行,则在起始平台上放置一个 ai_character 实例并(在当前步骤事件中)模拟跳跃尝试。

3.a 对起始平台上每个可能的起始位置重复此跳跃尝试。

  1. 如果此尝试成功,请记录实时复制所需的数据并转移到下一个平台。

  2. 如果没有,请不要形成链接。

  3. 对所有平台重复。

这种方法或多或少有效,并产生了一个链接结构,当可视化时看起来像这样:

链接平台(超链接,因为没有代表。)

在此示例中,右下角大部分隐藏的粉红色幽灵正试图到达黑白框。浅蓝色矩形只是用来突出识别平台所在的位置,实际平台是灰色框的行。链接线在起点处为绿色,在目的地处为红色。

这种方法的一个巨大而明显的问题是,对于只有 17 个平台的级别(如上所示),生成节点图需要一秒钟的时间。原因很明显,屏幕中心的黄色文本向我们展示了构建图形需要多长时间:超过 24,000(!)个模拟帧,每个帧都伴随着对每个块的碰撞检查 - 我实际上只是运行角色的 step 事件在一个 while 循环中,因此它通常会在一个框架中处理平台游戏移动的所有操作现在执行 24,000 次。

这显然是不可接受的。如果它仅在 17 个平台上扩展得如此糟糕,那么我需要支持的数百个平台将是一个笑话。哎呀,以这个几何时间成本可能需要数年时间。

为了加快速度,我专注于另一个重要的调试数字,测试计数器:239。如果我只是尝试了起始平台和目标平台的所有可能组合,我将需要运行 17 * 16 = 272 次测试。通过找出各种方法来预测跳跃是否不可能,我设法将运行的昂贵测试的数量减少了高达 33 次(12%!)。然而,我添加到代码中的异常和特殊情况越多,我就越确信实际问题出在跳跃模拟代码中,这让我终于想到了我的问题:

你如何确定一个角色是否有可能从一个平台跳到另一个平台,并且最好不需要模拟整个跳跃?

我的特定平台物理:

跳跃的高度是固定的,除非你碰到天花板。

水平运动没有加速度或惯性。

允许水平空气控制。

更多信息:我找到了这个视频,它描述了一个类似的问题,但没有提供一个好的解决方案。这实际上是我找到的唯一资源。

4

2 回答 2

1

您可以通过仅比较附近的平台来限制比较的数量。我可能只会检查平台之间的水平距离,如果它比可能的最长跳跃更宽,那么不要费心检查这两者之间的链接。但是您可能已经这样做了,因为您检查了跳跃的最大高度。

我看了看视频,它给了我一个想法。与其查看所有平台来找出哪些跳跃是不可能的,不如反其道而行之呢?尝试在所有平台上放置一个 AI 角色,看看他们可以到达哪些其他平台。如果你的敌人不能在半空中改变方向,那当然更容易实现。哦,头脑风暴是找到一些东西的关键。

于 2015-03-11T18:11:07.870 回答
0

Several ideas you could try out:

  1. Limit the amount of comparisons you need to make by using a spatial data structure, like a quad tree. This would allow you to severely limit how many platforms you're even trying to check. This is mostly the same as what you're currently doing, but a bit more generic.

  2. Try to pre-compute some jump trajectories ahead of time. This will not catch all use cases that you have - as you allow for full horizontal control - but might allow you to catch some common cases more quickly

  3. Consider some kind of walkability grid instead of a link generation scheme. When geometry is modified, compute which parts of the level are walkable and which are not, with some resolution (something similar to the dimensions of your agent might be good starting point). You could also filter them with a height, so that grid tiles that are higher than your jump height, and you can't drop from a higher place on to them, are marked as unwalkable. Then, when you compute your pathfinding, as part of your pathfinding step you can compute when you start a jump, if a path is actually executable ('start a jump, I can go vertically no more than 5 tiles, and after the peak of the jump, i always fall down vertically with some speed).

于 2019-04-04T10:28:47.473 回答