2

ボールを元の高さと同じ高さにバウンドさせようとしています。しかし、フレームではなく時間を導入するとすぐに、どこかで勢いを失います。

コードを最小限に抑えると、次のようになります。

public void onDrawFrame(GL10 gl) {

float timeDelta = System.currentTimeMillis() - startTime;
startTime = System.currentTimeMillis();

update(timeDelta);
}

float gravity = -1.0f;
float PosY = 2400;
float VelocityY = 0;

public void update(float timeDelta){

PosY+=VelocityY;
if(PosY<=0){
    VelocityY=Math.abs(VelocityY);
} else{
    VelocityY+=gravity*timeDelta;
}       
Log.d(SystemSingleton.sLogDebug,String.format("Pos: y%f. y%f, timeDelta: %f",PosY, VelocityY, timeDelta));

}

キャストや丸めによって何も失われないようにするために、時間のデルタをミリ秒のままにしました(1000で割って秒を期待するのではなく)。

timeDeltaを無視し、フレームごとに重力全体を適用すると、これは正常に機能し、バウンスのピークは正確に2400(開始位置)になります。しかし、timedeltaを考慮に入れると、それは常に2400未満であり、ゆっくりと劣化します。その後、再び劣化し始める前に、時々かなりの量(2400をはるかに超える場合もあります)に跳ね上がります。

私は明らかにかなり劇的に間違った何かを持っていますが、私はそれを見ることができません。

どんな助けでも大歓迎です。

4

2 に答える 2

4

timeDelta新しい位置を計算するときは、タイム ステップ ( ) を考慮する必要があります。これを行う代わりに:

PosY += VelocityY;  // no!!

これを行う:

PosY += VelocityY * timeDelta;

さらに良いことに、次のようにします。

PosY += VelocityY * timeDelta + 0.5 * gravity * timeDelta * timeDelta;

また、バウンス検出を少し変更します。試してみる新しいコードを次に示します。

// Perform the integration
PosY      += VelocityY * timeDelta + 0.5 * gravity * timeDelta * timeDelta;
VelocityY += gravity * timeDelta;

// Check whether it's time to bounce
if (PosY<=0 && VelocityY<0){
    VelocityY = Math.abs(VelocityY);
}       
Log.d(...)
于 2011-06-21T00:47:10.643 に答える
0
float timeDelta = System.currentTimeMillis() - startTime;
startTime = System.currentTimeMillis();

私の推測では、これが原因です。currentTimeMillis を呼び出すと、2 つの異なる数値が得られる可能性があります。私がすること:

float currentTime = System.currentTimeMillis();
float delta = currentTime - startTime;
startTime = currentTime;
于 2011-06-20T20:12:33.397 に答える