我正在使用delta时间,所以我可以使我的程序帧速率独立。 但是我无法获得相同的跳跃高度,角色总是在较低的帧速率下跳得更高。
变量:
const float gravity = 0.0000000014f;
const float jumpVel = 0.00000046f;
const float terminalVel = 0.05f;
bool readyToJump = false;
float verticalVel = 0.00f;
逻辑代码:
if(input.isKeyDown(sf::Keyboard::Space)){
if(readyToJump){
verticalVel = -jumpVel * delta;
readyToJump = false;
}
}
verticalVel += gravity * delta;
y += verticalVel * delta;
我确定增量时间是正确的,因为角色水平移动很好。
无论帧速率如何,我如何让我的角色跳跃?
答案 0 :(得分:6)
计算新职位的公式为:
position = initial_position + velocity * time
考虑到根据功能降低速度的重力:
velocity = initial_velocity + (gravity^2 * time)
注意:在这种情况下,重力与重力不同。 最终的公式变为:
position = initial_position + (initial_velocity + (gravity^2 * time) * time
从上面的等式可以看出,initial_position和initial_velocity不受时间的影响。但在您的情况下,您实际上将初始速度设置为-jumpVelocity * delta
。
帧速率越低,delta
的值越大,因此角色会跳得越高。解决方案是改变
if(readyToJump){
verticalVel = -jumpVel * delta;
readyToJump = false;
}
到
if(readyToJump){
verticalVel = -jumpVel;
readyToJump = false;
}
编辑:
以上应该给出一个很好的估计,但这并不完全正确。假设p(t)
是时间t
之后的位置(在本例中为高度),那么v(t) = p'(t)', and the acceleration is given by
给出的速度a(t)= v'(t)= p''(t )`。因为我们知道加速度是恒定的;即重力,我们得到以下结果:
a(t) = g
v(t) = v0 + g*t
p(t) = p0 + v0*t + 1/2*g*t^2
如果我们现在计算p(t+delta)-p(t)
,即从一个实例到另一个实例的位置变化,我们得到以下结果:
p(t+delta)-p(t) = p0 + v0*(t+delta) + 1/2*g*(t+delta)^2 - (p0 + v0*t + 1/2*g*t^2)
= v0*delta + 1/2*g*delta^2 + g*delta*t
原始代码未考虑delta
或额外字词g*delta*t*
的平方。更准确的方法是存储增量增量,然后使用上面给出的p(t)
公式。
示例代码:
const float gravity = 0.0000000014f;
const float jumpVel = 0.00000046f;
const float limit = ...; // limit for when to stop jumping
bool isJumping = false;
float jumpTime;
if(input.isKeyDown(sf::Keyboard::Space)){
if(!isJumping){
jumpTime = 0;
isJumping = true;
}
else {
jumpTime += delta;
y = -jumpVel*jumpTime + gravity*sqr(jumpTime);
// stop jump
if(y<=0.0f) {
y = 0.0f;
isJumping = false;
}
}
}
注意:我没有编译或测试上面的代码。
答案 1 :(得分:0)
&#34; delta time&#34;你的意思是可变时间步骤吗?在每一帧中,您计算的时间步长可能与之前的步骤完全不同?
如果是, DON&#39; T 。
阅读本文:http://gafferongames.com/game-physics/fix-your-timestep/
TL; DR:对内部状态使用固定时间步长;如果需要,插入帧。