我遇到了一个问题,重力会随着帧速率的变化而严重变化。当我以每秒160帧的速度跑步时,我的球员在空中跳了几米然后倒下,但在大约10帧的时候,我的球员跳了半米然后倒下。我的重力代码如下:
public void fall(long delta) {
float increase = acceleration * ((delta) / 1000000000); //changes delta time (nanoseconds) to seconds
if(player.y + velocity + increase < -1.15f) {
if(velocity + inc < terminal_velocity) {
velocity += inc;
}
player.y += velocity;
}else{
player.y = -1.15f;
velocity = 0;
}
}
我把它叫做:
while(!close_request) {
now = getTime();
int delta = getDelta(now);
player.fall(delta);
........other functions.........
}
我认为实现增量可以防止玩家改变速度太快或太慢,但它实际上让情况变得更糟。我认为这是由于这样一个事实:随着两帧之间时间的增加,速度的增加也会导致球员异常快速地倒下。这来自于这样一个事实:随着FPS的增加,玩家会跳得更高。有什么想法吗?
发布于 2012-12-24 18:45:23
你的问题出在这一行:
player.y += velocity;
这没有考虑到速度是“距离除以时间”。
你正确地模拟了加速度:
v = u + a * t // v = current velocity, a = acceleration, t = time
但不包括距离,对于足够小的delta
,它是:
delta_s = v * delta_t
您需要将velocity
乘以delta
,然后才能将其添加到位置。
发布于 2012-12-24 18:37:41
你没有正确地建立物理模型。假设dt足够小,这将提供一个“足够好”的近似值。
curV // current velocity
accel // global acceleration constant
terminal // terminal velocity for object
dt // delta time in seconds
fall(dt):
deltaV = accel * dt // Change in velocity in a vacuum
newV = curV + deltaV // New velocity
if (newV < terminal) newV = terminal // Don't exceed downwards terminal velocity
y = y + dt * (curV+newV)/2 // New position
curV = newV // Save new velocity as current
它忽略了一些复杂的事情,比如当你接近终端速度时,加速度降低。这与您的最大区别在于dt
出现了两次,一次是在计算deltaV
时,另一次是在计算新的垂直位置时。
https://stackoverflow.com/questions/14024057
复制