请看下面的代码... 球像普通球一样弹跳,但随后球停止并从 GUI 上下沉。关于这段代码可能有什么问题有什么想法吗?
public void verticalBounce(Container container) {
deltaY = deltaY - gravity;
y = y + deltaY;
if (y >= getHeight()) {
deltaY = -deltaY;
deltaY = (int) (deltaY * 0.9);
y -= -deltaY;
}
}
最佳答案
我将使用y'
表示该时间片末尾的 y 位置,y
用于前一个时间片末尾的位置,严格来说是为了便于标记。这使得代码的第三行:
y' = y + deltaY;
让我们考虑 y'
的情况严格大于getHeight()
。 (它们相等的情况最终将被自动考虑,如下所示。)快速绘制这种情况如下:
_ o - y
| o
| o
----------|--------------------- getHeight()
| O
deltaY - | O
| O
|_ O - y'
在当前时间片内的某个时刻,球落地(在 getHeight() 处)。对于当前时间片的剩余时间,我们超出下限的量为:
y' - getHeight()
我们需要这个余数作为球在当前时间片内向上弹起的量。当前时间片结束时的实际 y 位置(暂时忽略弹性常数)如下所示:
_ O - y''
_ o - y | O
| o | O
| o | O
-------------------------------- getHeight()
现在,y''
是 getHeight()
减去我们上面计算的超出下限的量:
y'' = getHeight() - (y' - getHeight());
(您可能想将其更改为 2*getHeight() - y'
,但请坚持到我们结束为止。)
我们现在将快速引入我们之前忽略的案例,其中 y' == getHeight()
。如您所见,y' - getHeight()
归零,留下y'' == getHeight()
,正如我们所需要的,因此对于这种情况不需要做额外的工作。
很好,所以我们现在需要做的就是处理弹性常数(我假设这就是 0.9 因子的用途,以便弹力随着时间的推移而衰减)。我们想将其应用到 deltaY
正如您所做的那样,但我们还需要将其应用于当前时间片中自其落地以来的反弹:
y'' = getHeight() - 0.9*(y' - getHeight());
因为我们还没有混合y
, y'
和y''
在任何计算的右侧,我们可以简单地将它们全部替换为 y
给我们最后的if
子句(仅更改了最后一行):
if (y >= getHeight()) {
deltaY = -deltaY;
deltaY = (int) (deltaY * 0.9);
y = getHeight() - 0.9*(y - getHeight());
}
我确信,如果您拿出以前的解决方案,您就会发现它们错在哪里。另外,在我看来,使用 int 表示 deltaY 似乎是在自找麻烦。我宁愿使用 float 进行所有计算,然后仅在绘图时进行舍入。您会注意到我没有对 y
的结果进行任何转换上面,这可能是必要的,具体取决于 y
的类型.
关于java - 弹跳球重力,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19017910/