两轴的二维平台碰撞问题

时间:2010-04-17 02:11:13

标签: c++ 2d sdl collision-detection

我正在使用C ++和SDL制作一个小型平台游戏/格斗游戏,我在碰撞检测方面遇到了很多麻烦。

关卡由一系列图块组成,我使用for循环遍历每一个(我知道它可能不是最好的方法,我也可能需要帮助)。对于角色的每一面,我在那个方向移动一个像素并检查碰撞(我还检查角色是否朝那个方向移动)。如果发生碰撞,我将速度设置为0并将玩家移动到图块的边缘。

我的问题是,如果我首先检查水平碰撞,并且玩家每帧以多个像素垂直移动,它会处理水平碰撞并将角色移动到图块的侧面,即使图块位于下方(或以上)角色。如果我首先处理垂直碰撞,它会做同样的事情,除了它是横向轴。

如何在没有这些问题的情况下处理两个轴上的碰撞?有没有更好的方法来处理碰撞而不是我的做法?

2 个答案:

答案 0 :(得分:3)

XNA's 2D platformer example也使用基于图块的碰撞。他们处理它的方式很简单,可能对你有用。这里有一个简单的解释,其中包含了什么(删除特定于他们的演示内容):

  1. 应用移动后,会检查是否有碰撞。
  2. 根据玩家的边界框确定玩家重叠的图块。
  3. 它遍历所有这些瓷砖......
    1. 如果要检查的图块不可通过:
    2. 它确定玩家与不可通行的瓷砖重叠的X和Y轴的距离
    3. 仅在浅轴上解决碰撞
      1. 如果Y是浅轴(abs(overlap.y)< abs(overlap.x)),则position.y + = overlap.y;同样,如果X是浅轴。
      2. 根据位置更改
      3. 更新边界框
    4. 转到下一个瓷砖......
  4. 如果你抓住代码并想看看他们在那里做了什么,那就是在HandleCollisions()函数的player.cs中。

答案 1 :(得分:0)

是。基于矢量的碰撞将比基于图块的碰撞好得多。将图块的每个边缘定义为线条(有快捷方式,但现在忽略它们。)现在要查看是否发生了碰撞,找到最近的水平和垂直线条。如果你采用lastPos.x * LineVector.y的标志 - lastPos.y * LineVector.x并将其与thisTurnsPos.x * LineVector.y - ThisTurnsPos.y * LinePos.x进行比较。如果这两个值的符号不同,那么你就越过这条线。这不会检查您是否已经越过了线段的末尾。您可以在相同的lineVector和curPosition之间形成一个点积(这里有一点误差,但可能足够好)并且它是负数或大于线的幅度平方,您不在该线段内并且没有发生碰撞

现在这非常复杂,您可以通过简单的网格检查来确定您是否已经进入另一个方格区域。但!使用矢量执行此操作的优点是它解决了比碰撞盒问题的大小更快的移动速度(更重要的是),您可以使用非轴对齐线来进行碰撞。这个系统适用于任何2D矢量(并且还有一些按摩,3D也是如此。)它还允许您轻松地沿着碰撞盒的边缘滑动角色,因为您已经完成了所需的99%的数学运算。找到碰撞后你应该去的地方。

我已经掩盖了几个实现细节,但我可以说,我已经在无数的商业视频游戏中使用了上述方法,它的工作就像一个魅力。祝你好运!