2D平台游戏AABB碰撞问题

6

http://dl.dropbox.com/u/3724424/Programming/Gifs/game6.gif

我在AABB碰撞解决方案上遇到了问题。


我先解决X轴,然后解决Y轴以解决AABB相交。这样做是为了防止出现以下错误:http://i.stack.imgur.com/NLg4j.png


当物体向玩家移动且需要水平推动玩家时,当前方法运行良好。正如你在gif中所看到的,水平钉子正确地推动了玩家。


然而,当垂直钉子移动到玩家时,仍然首先解决X轴。这使得“使用钉子作为升降机”变得不可能。

当玩家移动到垂直钉子(受重力影响,掉落到它们里面)时,因为一开始没有重叠的X轴,所以会在Y轴上被推开。


我尝试过的一些方法是第一个答案所描述的链接中的方法。然而,钉子和移动物体是通过改变它们的位置而不是速度来移动的,而且我直到调用它们的Update()方法之前才计算它们的下一个预测位置。不用说这个解决方案也没有起作用 :(


我需要以一种方式解决AABB碰撞,使得上述两种情况都按预期工作。

这是我的当前碰撞源代码:http://pastebin.com/MiCi3nA1

如果有人能够帮忙解决这个问题,我将不胜感激,因为这个错误从一开始就存在于引擎中,我一直在努力寻找一个好的解决方案,但一直没有成功。这让我花费了很多时间看碰撞代码,阻止我进入“有趣的部分”并编写游戏逻辑 :(


我尝试实现与XNA AppHub平台游戏演示相同的碰撞系统(通过复制大部分内容)。然而,在我的游戏中出现了“跳跃”错误,而在AppHub演示中没有出现。[跳跃错误: http://i.stack.imgur.com/NLg4j.png]

要跳跃,我检查玩家是否“在地面上”,然后将-5添加到Velocity.Y中。

由于玩家的Velocity.X大于Velocity.Y(参见图示中的第四个面板),所以当它不应该时,onGround被设置为true,从而让玩家在空中跳跃。

我认为这在AppHub演示中不会发生,因为玩家的Velocity.X永远不会高于Velocity.Y,但我可能错了。

我之前通过先在X轴上解决问题,然后在Y轴上解决问题来解决这个问题。但这会破坏与尖刺的碰撞,就像我上面所说的那样。


这是有关游戏开发的编程内容,请将以下文本从英语翻译成中文。仅返回翻译后的文本:FYI,这个问题在gamedev.stackexchange.com上也有,那里有更多的答案:http://gamedev.stackexchange.com/questions/14486/2d-platformer-aabb-collision-problems?lq=1 - CodeSmile
3个回答

0

为什么不先在Y轴上解决垂直尖峰,然后再在X轴上解决水平尖峰呢?

顺便说一句,图形很漂亮。


据我所理解,您处理运动和碰撞的方式大概是这样的:
  1. 移动所有对象。
  2. 对于每个对象 O,测试玩家和 O 之间的交集,如有必要,将玩家水平或垂直抛出,以使其不再与 O 相交。
  3. 如果玩家仍然与某个对象相交,则 (某些操作)
这意味着当您进行第二步时,您已经忘记了对象 O 移动的方向,因此无法确定它是否试图将玩家向上或向侧面推。
解决方法:在第一步中,为每个对象存储其移动方向。当您发现玩家与对象相交时,可以查看对象是向上、向下、向左还是向右移动,并告诉您执行哪种弹出方式。

那是“最后的手段”解决方案。我更喜欢找到一个“自动”适用于每种情况的通用解决方案。 - Vittorio Romeo
你不是打算继续进行“有趣的部分”吗?;) 这个解决方案听起来还不错,也许这是唯一/最好的解决方案。试一下并继续前进,你随时可以稍后回来。 - CodeSmile
想一想,你需要以不同的方式处理移动的“平台”和静态碰撞瓷砖。当玩家站在移动平台上时,您需要将其与平台一起移动,这意味着在评估碰撞之前,每帧都要将平台的移动增量位置添加到玩家位置中。这需要在玩家移动之前移动平台。请参见此处的平台部分:http://higherorderfun.com/blog/2012/05/20/the-guide-to-implementing-2d-platformers/ - CodeSmile

0
我找到的一个可能的解决方案是根据玩家速度对对象进行排序,然后再进行解析。

0

正如Gareth Rees所说,问题在于在检测到碰撞后,您需要更多信息(当前位置以及来自哪个方向或上一个位置),以执行碰撞响应。

如果两个对象都在移动,则会变得非常复杂。相反,选择一个对象作为参考框架,并从其他所有对象中减去其速度。

一个简单的解决方案可能是为非参考框架对象的运动/增量创建线段。然后将这些线段与4个AABB边相交。这给出了交点的时间和交点处的法线。然后您可以应用与现在相同的响应。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接