我用 Java 创建了一个简单的 2d 物理引擎,它使用圆形射弹和直墙。目前,对于每一帧,每个射弹的位置都会提前velocity * (1/fps)
。之后速度每帧更新一次。碰撞检测使用先前位置和当前位置以点斜率形式定义一条线,检查该线是否与墙壁相交,如果该交点位于先前位置和当前位置之间,则会记录碰撞,并且射弹的当前位置和速度相应更新。目前,还没有预期的轮换。
现在,除了非弹性碰撞之外,这一切都有效。目前,非弹性碰撞会将垂直于其碰撞表面的射弹速度分量乘以某个小于 1 的系数。
假设有一个弹丸在水平面上上下弹跳。什么should发生的情况是,弹丸速度的 y 分量随着每次弹跳而减小,导致弹丸的最大高度随着每次弹跳而减小,最终达到可以忽略不计的点。相反,发生的情况是球的最大高度减小到某个点,然后开始增加几次弹跳,然后再次开始减小,进入一个恒定的循环。结果是球永远不会真正停止,而是看起来“抖动”。
发生这种情况是因为射弹每帧都以直线段移动,并且速度不是连续变化的。如果球下落的帧数多于球上升的帧数,则球会在这些额外的帧中加速,最终会比应有的高度更高。所发生的情况是,球到达一个点,由于上述原因,一次弹跳将其发送到比应有的高度更高的位置。当最大高度由于非弹性碰撞再次下降时,它会再次做同样的事情。
我尝试通过让球移动来消除这个问题(v*t + 0.5*a*t^2)
, where v
是速度,a
是重力加速度,并且t
is 1/fps
。这是可行的,除了当弹跳足够小时它会导致使用直线的碰撞检测失败。我还尝试过使用参数定义的抛物线进行碰撞检测,但在检测射弹之间的碰撞时,它变得令人难以置信的烦人和低效。如果您好奇,我可以更深入地解释我尝试的解决方案。
您还想建议其他任何简单的解决方案吗?
提前致谢,特别是如果您确实阅读了这五个段落。
我建议的是有一个会反弹的代码块only如果弹跳高度等于或高于您定义为高度的某个常数。您将需要某种循环结构(或“辅助”方法,如下所示)来计算球每次弹跳后的预计弹跳高度。那么你也许可以做这样的事情:(假设你已经输入了“现在是时候弹跳方法了”)
private static final int MINIMUM_BOUNCE = 100 //arbitrary value
. . .
if(calculateNewBounceHeight() >= MINIMUM_BOUNCE) {
bounce();
} else {
// terminate program?
// notify user?
// etc.
}
这种方式的唯一问题是,如果您没有在某个时刻终止,程序将检查它是否可以无限弹跳(如果球在基线上“滚动”)。这可能会导致一些内存问题,因为它在某种程度上是无限循环。
只是为了澄清:calculateNewBounceHeight()
and bounce()
我认为您能够创建这些方法。这有帮助吗?如果我错过了某些内容或错误地解释了问题,请告诉我(我可能没有阅读整篇文章)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)