如何防止新的碰撞绕过旧的碰撞? (二维)

How to prevent newer Collisions bypassing old collisions? (2D)

我想用 C++ 中的多边形制作我自己的碰撞系统。有静态碰撞器(永远不会移动,不能被推动)和动态碰撞器(可以移动,永远不会 可以在静态碰撞器内。)。 我目前的做法是:

for (auto &dyn : dynamicColliders) {
    for (auto &stat : staticColliders) {
        // "how deep" is any vertex of dyn inside of stat? Store that in t.
        //    Is dyn inside stat (0 <= t <= 1)? -> push dyn outside by t
        // not inside? -> next 2 lines
        // "how deep" is any vertex of stat inside of dyn? Store that in r.
        //    Is stat inside dyn (0 <= r <= 1)? -> push dyn outside by r.
    }
}

这是一个发生的例子:

https://youtu.be/XeGga98ZtUY

基本上,方块是静态对象。六边形是动态的。 现在,当六边形碰撞到底部正方形时,它被推入顶部正方形。然而,顶部正方形将六边形推回底部正方形。 (现在,物理步骤结束了。不再考虑假底部碰撞。这个顺序发生是因为顶部方块是 "newest" 碰撞对象)

我尝试了什么:

  1. 对所有 "Push" 个向量求和并在末尾相加
  2. 如果在被推到正方形外后发生碰撞,则完全取消当前物理步骤中的移动。
  3. (以上方法)

结果:

  1. 没用:Hexagon 被推到正方形下方,它之前没有与之发生碰撞。
  2. 确实有效,但非常有问题。我不能沿着正方形滑行,因为它被取消了。
  3. (见上面的视频)

如何避免绕过这种类型的碰撞?非常感谢!

这种单点碰撞检测方法(遗憾地)行不通。由于它在碰撞发生的单个点对每个对象进行建模,因此它没有考虑到对象可能也在其他地方发生碰撞,因此无法在它试图推动它的方向上移动或反弹。

您需要使用您正在使用的任何检测系统检查它碰撞的所有点,然后让您的碰撞处理逻辑根据它可以进入的有效方向做出反应。

如果您也在构建检测系统(从您的问题来看这听起来很像),那么您将需要一个有效的算法来映射 2d space 中可能的碰撞点,您可能需要 最近邻搜索kd-tree。您可以找到 许多 C++ 库来为您完成这项工作。

(请注意,kd-tree 在每次插入和删除时都会失去平衡,因此您应该为移动点准备一个动态树,定期重新平衡,为静态点准备一个静态树,可以单独放置)