类似于“马里奥”的2D侧卷轴游戏中的碰撞反应

时间:2011-07-13 03:42:00

标签: 2d collision-detection game-engine

在过去的几周里,这一直困扰着我。在这段时间里,我一直在网上进行研究,甚至在Borders的计算机部分读书,试图找到答案,但我没有太多运气。

我为侧卷轴视频游戏编写了2D级编辑器。现在我想把它变成一个游戏,我有一个可以跑步和跳跃探索关卡的玩家,类似于“马里奥”。

真正给我带来麻烦的是碰撞响应(没有检测:我已经知道如何判断两个块是否发生碰撞)。以下是我要说明的一些场景,以便您可以看到我的问题(阴影块是地面,箭头是玩家的速度矢量,虚线是玩家的投射路径)。

请参阅此碰撞响应方案图像:

example http://dl.dropbox.com/u/12556943/collision_detection.jpg

假设情景(1)和(2)中的速度矢量相等(相同的方向和幅度)。然而,在场景(1)中,玩家正在击中该区块的一侧,并且在场景(2)中,该玩家正在该区块的顶部着陆。这使我得出结论,确定碰撞响应不仅取决于玩家的速度矢量,还取决于玩家相对于碰撞块的相对位置。这引出了我的第一个问题:知道速度矢量和玩家的相对位置,我如何确定玩家与该块碰撞的方向(左侧,右侧,顶部或底部)?

我遇到的另一个问题是如果玩家与同一帧中的多个块发生碰撞,如何确定碰撞响应。例如,假设在场景(3)中,玩家同时与这两个块碰撞。我假设我将不得不遍历玩家正在碰撞的每个区块并相应地调整每个区块的反应。总而言之,这是我的第二个问题:如果玩家与多个区块发生碰撞,我该如何处理碰撞响应?

请注意,我从未透露过我正在编程的语言;这是因为我更喜欢你不知道(不过是个人的,但是:)。我对伪代码比对特定语言代码更感兴趣。

谢谢!

3 个答案:

答案 0 :(得分:10)

我认为XNA's example platform game处理碰撞的方式可能对您有用。我将此答案发布到一个非常相似的问题elsewhere on Stack Overflow,但也将在此处转发。

  1. 应用移动后,检查并解决冲突。
  2. 根据玩家的边界框确定玩家重叠的图块。
  3. 迭代所有这些瓷砖执行以下操作:(除非您的播放器与世界瓷砖相比很大,否则通常不会很多)
    1. 如果要检查的磁贴不可通过:
      1. 确定玩家与不可通过的图块重叠的X轴和Y轴的距离
      2. 通过仅在浅轴上移动播放器来解决碰撞(无论哪个轴穿透最少)
        • 例如,如果Y是浅轴并且碰撞位于下方,则将玩家向上移动到不再与该图块重叠。
        • 像这样:if(abs(overlap.y) < abs(overlap.x)) { position.y += overlap.y; } else { position.x += overlap.x; }
      3. 根据玩家的新位置
      4. 更新边界框的位置
      5. 转到下一个瓷砖......
    2. 如果正在检查的图块 可以通过,则不执行任何操作
  4. 如果解决碰撞可能会将玩家移动到另一个碰撞中,您可能希望再次运行上述算法。或者重新设计你的等级。
  5. 如果您有兴趣获取他们的代码以了解他们在那里做了什么,那么此逻辑的XNA版本位于player.cs函数的HandleCollisions()中。

答案 1 :(得分:3)

所以让这更加棘手的是恒定的重力调整你的球员位置。如果你的球员在一个区块顶部跳跃,他们不应该反弹,他们应该落在街区顶部并留在那里。但是,如果玩家在左侧或右侧击中一个区块,他们不应该只停留在那里,重力必须将它们拉下来。我认为这大致是你的问题。

我认为你会想要将两种重力和球员速度与碰撞检测/响应算法分开。使用播放器的速度,如果它们与一个块碰撞,无论方向如何,只需将玩家的位置移动到碰撞的边缘,并从玩家的速度中减去相等和相反的矢量,因为不这样做会导致它们再次与玩家的碰撞宾语。您需要计算交叉点并将玩家的位置放在块上。

在旁注中你可以通过玩家碰撞的阻挡类型来改变那么大的力量,从而允许有趣的反应,如果玩家跑得足够快(即玩家的速度>比块的力量)

然后继续将恒力引力应用于玩家的位置并继续进行正常计算,以确定玩家是否已到达场地。

我认为通过分离这两个概念,你有一个非常简单的直接碰撞响应算法,并且你有一个相当简单的重力平台算法。这样,您可以改变重力,而无需重做碰撞响应算法。比如水位,空间等等,碰撞检测响应都是一样的。

答案 2 :(得分:2)

我最近想了很久。

我正在使用分离轴定理,因此如果我检测到碰撞,我会将对象投影到标准化的速度矢量上,并将物体沿负速度矢量的方向移动该距离。假设物体来自安全的地方,该解决方案将物体放置在碰撞后的安全位置。

可能不是你想要得到的答案,但希望它会指出你正确的方向?