4

円形の発射体と直線の壁を使用する単純な 2D 物理エンジンを Java で作成しました。現在、各フレームで、すべての発射体の位置が だけ進みvelocity * (1/fps)ます。その後、速度はフレームごとに 1 回更新されます。衝突検出は、前の位置と現在の位置を使用してポイントスロープ形式で線を定義し、その線が壁と交差するかどうかを確認し、その交点が前の位置と現在の位置の間にある場合、衝突が登録され、発射体の現在の位置とそれに応じて速度が更新されます。現時点では、ローテーションは意図されていません。

さて、これは非弾性衝突を除いてすべて機能します。現在、非弾性衝突は、衝突した表面に垂直な発射体の速度の成分に 1 未満の係数を乗算します。

水平面上で上下に跳ね返る発射体があるとします。発射体の速度の y 成分がバウンスごとに減少し、バウンドごとに発射体の最大高さが減少し、最終的には無視できるポイントに到達します代わりに、ボールの最大高さが特定のポイントまで減少し、その後増加し始めて数回バウンドし、再び減少し始め、一定のサイクルに入ります。その結果、ボールが実際に止まることはなく、「ジッター」しているように見えます。

これは、発射物がフレームごとに直線セグメントで移動し、速度が連続的に変化しないために発生します。ボールが上昇しているフレームよりもボールが落下しているフレームの方が多い場合、ボールはそれらの余分なフレームで加速され、必要以上に高くなってしまいます。何が起きているかというと、上記の理由により、ボールが 1 回のバウンドで本来よりも高い位置に到達するということです。非弾性衝突により最大高さが再び下がると、再び同じことが行われます。

私は、ボールを(v*t + 0.5*a*t^2)v動かすaことによってこれを排除しようtとしまし1/fpsた。これは機能しますが、バウンスが十分に小さくなると、直線を使用した衝突検出が失敗するという事実を除きます。また、パラメトリックに定義された放物線で衝突検出を試みましたが、発射体間の衝突の検出に関しては、信じられないほど面倒で非効率的になります。興味があれば、私が試みた解決策をさらに詳しく説明できます。

他に提案したい簡単な解決策はありますか?

特に、これらの 5 つの段落を実際に読んだ場合は、事前に感謝します。

4

1 に答える 1

0

私がお勧めするのは、バウンスの高さが高さとして定義した特定の定数以上の場合にのみバウンスするコード ブロックを用意することです。ボールが跳ねるたびに予測される跳ね返りの高さを計算するには、ある種のループ構造 (または以下で行った「ヘルパー」メソッド) が必要です。次に、次のようなことができるかもしれません:

private static final int MINIMUM_BOUNCE = 100 //arbitrary value

. . .

if(calculateNewBounceHeight() >= MINIMUM_BOUNCE) {
    bounce();
} else {
    // terminate program?
    // notify user?
    // etc.
}

この方法の唯一の問題は、ある時点で終了しない場合、プログラムが無限にバウンドできるかどうか (ボールがベースライン上で「転がっている」かどうか) をチェックすることです。これはある程度の無限ループであるため、メモリの問題が発生する可能性があります。

明確にするために: calculateNewBounceHeight()andbounce()は、作成できると思われるメソッドです。これはまったく役に立ちますか?何かを見逃したり、質問を間違って解釈したりした場合はお知らせください (すべてを読んでいない可能性があります)。

于 2015-05-12T11:59:11.630 に答える