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、前のタイム スライスの最後の位置を示すために、厳密にラベル付けを簡単にするために を使用します。これにより、コードの 3 行目が次のようになります。

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'、最後まで待ってください。)

ここで、以前の which を無視したケースをすばやくプルします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 に答える