我只是试图将球弹回原来的高度。但是一旦我引入时间而不是框架,我就会失去某种势头。
将代码降到最低限度,我有以下内容:
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)。
我显然有一些非常严重的错误,但我看不到它。
感谢任何帮助。
答案 0 :(得分: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(...)
答案 1 :(得分:0)
float timeDelta = System.currentTimeMillis() - startTime;
startTime = System.currentTimeMillis();
我的猜测是这是原因。调用currentTimeMillis可以给你两个不同的数字。我会做什么:
float currentTime = System.currentTimeMillis();
float delta = currentTime - startTime;
startTime = currentTime;