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 可以给你两个不同的数字。我会做什么:

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