0

请查看下面的代码... 球像普通球一样弹跳,但随后球停止,然后从 GUI 下沉。关于这段代码可能有什么问题的任何想法?

public void verticalBounce(Container container) {
        deltaY = deltaY - gravity;
        y = y + deltaY;

        if (y >= getHeight()) {
            deltaY = -deltaY;
            deltaY = (int) (deltaY * 0.9);
            y -= -deltaY;
        }
    }
4

1 回答 1

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());

由于我们没有混合yy'并且y''在任何计算的右侧,我们可以通过y给我们最后的if子句来简单地替换所有它们(仅更改了最后一行):

    if (y >= getHeight()) {
        deltaY = -deltaY;
        deltaY = (int) (deltaY * 0.9);
        y = getHeight() - 0.9*(y - getHeight());
    }

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

于 2013-09-26T18:18:38.257 回答