如何处理碰撞检测,以便不允许快速的物体穿过墙壁?


14

我正在创建一个2D横摇射击游戏,但在子弹的碰撞检测方面遇到了一些麻烦。包括项目符号在内的所有事物都是具有自己的多边形/更新方法的对象。

问题在于子弹速度很快,并且以每秒60帧(游戏运行时)的速度,子弹通常会直接跳过一堵墙-因为它在更新间隔内移动的速度超过了墙的宽度-并且继续愉快地前进,因为多边形实际上不会重叠。

我该怎么办?我唯一能想到的就是从旧位置到新位置绘制一条线,并在该位置上进行碰撞检测,但是slick2d文档建议针对碰撞检测使用线图。我该如何解决?


没有完整的答案,所以发表评论。我从不建议以图形方式画一条线,但是从数学上讲您可以做到这一点,它只是一个简单的射线平面相交以查看是否发生了碰撞。然后,您可以执行较小的固定步长检测,以获取发生碰撞时的准确时刻(以及随之而来的所有信息),而不必按照答案中的建议始终以更高的速度运行。进行成本更低的检查,然后花时间获取所需的精确答案。
詹姆斯

Answers:


9

标准方法是(选择一种):

  1. 增加边界宽度和/或降低子弹的最大速度,以使子弹在一次更新中永远不会跳过墙(需要一些毕达哥拉斯来找出最大距离/最小边界宽度);
  2. 进行连续碰撞检测(CCD),通常是通过射线投射来检测与运动对象之前的线性(2)或平面(3D)表面的碰撞。这比较昂贵,但是是更完善的解决方案。对2D线进行射线投射是非常基本的,但是在这种情况下,您确实需要将所有边界定义为直边多边形。

为此,您可以将子弹建模为射线-如果适合游戏的外观,例如left4kdead。这样,您不需要将子弹近似为射线,因为它们已经是射线。从外观的角度来看,如果您在子弹头上画一个带有较亮点的线,或者只是以从亮(子弹头)到暗(尾部)的渐变画线,这看起来就不错了。运动。

我会同意,在大多数情况下,使用图形进行碰撞检测会有些误导,但是像素完美的碰撞检测恰恰是这样,并且是一种可以接受的技术。我猜这一切都取决于您想要实现什么,以及达到多少速度。如果您不需要具有很多身体和动作的快速游戏,那就去吧。否则,最好使用我上面概述的方法之一。


感谢您的出色回答-理想情况下,我希望它能与许多移动的身体快速配合。我将子弹视为物理对象的原因是,它们会像其他所有东西一样受到重力的影响(因此,根据子弹的速度等,略微向下弯曲)。这不是一个好方法吗?这是我的第一场比赛,所以我仍在寻找最佳实践。我也可以使用抛物线方程,但是我不确定如何设置与子弹的速度/目标角度有关的系数
Mala

3
听起来子弹的细节太多了。在现实生活中,当您发射子弹时,由于弹跳的力,richochet角的不可预测性等原因,您不可能发现该弹头。否则,它只是进入人体并停留在那里(树,人)。我只是让它们消失或弹跳,然后此后不久消失。专注于您的核心游戏玩法,不必担心这些小细节。现实主义最好集中在重要的事情上。
工程师

是的,我想我可以只将直线用作子弹,也许会找到一种方法,使子弹稍稍向下弯曲(如果看起来很重要)。
马拉

2
如果子弹的速度不是太快(即不快到无法看到它们在屏幕上移动的速度),那么您就可以对它们的速度施加重力,同时仍然使用简单的射线对它们的碰撞检测进行建模。用户将不会注意到子弹以一系列直线移动,而不会注意到您所有其他对象也都一样。对于子弹轨迹,计算和绘制弯曲轨迹(样条曲线)并不困难,并且会增加对子弹轨迹的平滑曲线的错觉。
肖恩·米德迪奇

3

如果您希望子弹的行为像真实的物理对象(例如,子弹更像是弹射器中的箭头或石头,而不是枪声),那么您也可以尝试增加物理更新的频率。

因此,虽然您的游戏可能以每秒60帧的速度运行,但是您的物理模拟可以每秒120个更新的速度运行(这是您的时间步文章无处不在的修复,它解释了一种良好的物理设置,其运行速度与渲染循环的速度不同)。

当然,增加物理引擎的更新间隔会给CPU带来更大的负担。因此,这种方法仅在弹丸不是非常快速移动的情况下才有意义(我之所以这样假设是因为您能够分辨出弹丸正在弧形移动)。


谢谢!我正在有效地做到这一点(以及使用线形射弹),并希望随着游戏变得越来越复杂而保持可行性
Mala
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.