我用 Java 创建了一个简单的 2d 物理引擎,它使用圆形射弹和直墙。目前,每一帧,每个射弹的位置都会提前velocity * (1/fps)
. 速度随后更新,每帧一次。碰撞检测使用先前和当前位置以点斜率形式定义一条线,检查该线是否与墙壁相交,如果该交叉点位于先前位置和当前位置之间,则记录碰撞并且射弹的当前位置和速度会相应更新。目前,没有预期的旋转。
现在,除了非弹性碰撞之外,这一切都有效。目前,非弹性碰撞将弹丸速度的垂直于其碰撞表面的分量乘以某个小于 1 的系数。
假设有一个弹丸在水平面上上下弹跳。应该发生的是,弹丸速度的 y 分量随着每次弹跳而减小,导致弹丸的最大高度随着每次弹跳而减小,最终达到可以忽略不计的点。取而代之的是,球的最大高度降低到某个点,然后开始增加几次反弹,再次开始降低,进入一个恒定的循环。结果是球从未真正停止,而是似乎“抖动”。
发生这种情况是因为弹丸每帧都沿直线段移动,而且速度不是连续变化的。如果球落下的帧数多于球上升的帧数,则球会为这些额外的帧加速,最终会飞得比应有的更高。正在发生的事情是,球到达一个点,由于上述原因,一次反弹将其发送到比它应该具有的更高的位置。当最大高度由于非弹性碰撞再次下降时,它再次做同样的事情。
我尝试通过让球移动 来消除这种情况(v*t + 0.5*a*t^2)
,其中v
是速度,a
是重力加速度,并且t
是1/fps
。这是可行的,除了当反弹变得足够小时,它会导致使用直线的碰撞检测失败。我也尝试过使用参数定义的抛物线进行碰撞检测,但在检测射弹之间的碰撞时,它变得令人难以置信的烦人和低效。如果您好奇,我可以更深入地解释我尝试的解决方案。
您还想提出其他简单的解决方案吗?
在此先感谢您,尤其是如果您真正阅读了这五个段落。