由于重力问题,使用时间来增加速度(无法获得完美的弹性)



我只是想把球弹到原来的高度。但一旦我引入时间,而不是框架,我就会在某个地方失去动力。

把代码降到最低限度,我有以下内容:

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

我把时间delta留作毫秒(而不是像你所期望的那样除以1000得到秒),以确保我不会因为强制转换或舍入而丢失任何东西。

如果我忽略timeDelta,只在每帧应用整个重力,这很好,它的反弹峰值将正好是2400(它的起始位置)。但考虑到时间增量,它总是小于2400,并缓慢降解,然后在再次开始降解之前,不时地大幅上升(有时远高于2400)。

很明显我出了很大的问题,但我看不出来。

感谢您的帮助。

在计算新位置时,需要考虑时间步长(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(...)
float timeDelta = System.currentTimeMillis() - startTime;
startTime = System.currentTimeMillis();

我猜这就是原因。打currentTimeMillis可以给你两个不同的号码。我会做什么:

float currentTime = System.currentTimeMillis();
float delta = currentTime - startTime;
startTime = currentTime;

最新更新