我将使用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());
}
我敢肯定,如果您抽出以前的解决方案,您会发现它们哪里出错了。此外,在我看来,对 deltaY 使用 int 似乎是在自找麻烦。我宁愿使用浮点数进行所有计算,然后仅在绘图时进行舍入。你会注意到我没有对y
上面的结果进行任何转换,这可能是必要的,具体取决于y
.