[英]Frame rate independent gravity
我遇到一个问题,重力随帧频变化而变化很大。 当我以160 fps的速度运行时,我的播放器在空中跳了几米然后摔倒了,但是以10 fps的速度,我的播放器跳了半米然后摔倒了。 我的重力代码如下:
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的增加,玩家跳得更高,更高。 有任何想法吗?
您的问题在这一行:
player.y += velocity;
这没有考虑到速度是“距离除以时间”。
您正在正确地建模加速:
v = u + a * t // v = current velocity, a = acceleration, t = time
但不是距离,对于足够小的delta
,它是:
delta_s = v * delta_t
在将velocity
添加到位置之前,需要将velocity
乘以delta
。
您没有正确地建立物理模型。 假设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
,一次是在计算新的垂直位置时。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.