请参阅下面的代码...... 球像普通球一样反弹,然后球停止然后从GUI下沉。有关此代码可能出错的任何想法吗?
public void verticalBounce(Container container) {
deltaY = deltaY - gravity;
y = y + deltaY;
if (y >= getHeight()) {
deltaY = -deltaY;
deltaY = (int) (deltaY * 0.9);
y -= -deltaY;
}
}
答案 0 :(得分:1)
我将使用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''
,我们可以简单地用{{1}替换所有这些给我们最后的y
子句(只改变了最后一行):
if
我敢肯定,如果您提取出以前的解决方案,您会看到他们出错的地方。另外,在deltaY中使用int似乎是在寻找麻烦。我宁愿使用浮点数进行所有计算,然后只在绘图时进行舍入。您会注意到我没有对上面 if (y >= getHeight()) {
deltaY = -deltaY;
deltaY = (int) (deltaY * 0.9);
y = getHeight() - 0.9*(y - getHeight());
}
的结果进行任何投射,这可能是必要的,具体取决于y
的类型。