C++ 基于时间而非FPS的速度

C++ 基于时间而非FPS的速度,c++,c,math,physics,C++,C,Math,Physics,我正在用一个物体做一个简单的应用,我在上面施加重力 当fps速率改变时,我不希望对象走得太快/太慢,所以我四处寻找一种方法来实现这一点,我发现我需要将运动速度乘以增量时间 所以我决定去做,但我遇到的问题比我想象的要多 在游戏循环中,我有: gravityRate = 0.02; velocity.y += gravityRate; objectPosition.y -= velocity.y; 这当然会受到游戏fps的影响 我希望对象每16毫秒移动0.02个单位 所以我试着这么做: velo

我正在用一个物体做一个简单的应用,我在上面施加重力

当fps速率改变时,我不希望对象走得太快/太慢,所以我四处寻找一种方法来实现这一点,我发现我需要将运动速度乘以增量时间

所以我决定去做,但我遇到的问题比我想象的要多

在游戏循环中,我有:

gravityRate = 0.02;
velocity.y +=  gravityRate;
objectPosition.y -= velocity.y;
这当然会受到游戏fps的影响

我希望对象每16毫秒移动0.02个单位

所以我试着这么做:

velocity.y += (gravityRate * (delta * 1000.0) ) / (1000 / 60);
而delta*1000给出了经过的毫秒数

到目前为止还不错,它似乎工作正常,物体以相同的速度移动,即使在较低的FPS下,它跳过较大的间隙,但这很好

问题是,我希望对象在某些情况下向上跳。比如碰撞等等,, 我过去常常通过这样做来实现这一点: 速度y=-0.05

但现在这不起作用了,它确实起作用了,但它再次依赖于fps。 它在较高的FPS速率下跳得更高,在较低的FPS速率下跳得更低。 (我认为这可能是因为多个调用的聚集和降低速度超过预期,但事实并非如此,它只运行一次。)

我试图解决这个问题已经有一段时间了,但随着时间的推移,我不断遇到更多的问题。。所以我非常感谢你的帮助


谢谢你

根据时间计算你的速度和位置,如下所示:

deltaTime = currentTime - timeLastFrame    // time sins last frame
velocityDelta = deltaTime * gravityRate    // velocity change 

// calculate new position with only half of the velocity change this frame
objectPosition.y -= (velocity.y + (velocityDelta / 2)) * deltaTime   
velocity.y += velocityDelta 
天平需要根据您的游戏设置进行调整


编辑:

因此,在细节方面——首先,我们需要知道自上次以来发生了多少时间:

deltaTime = currentTime - timeLastFrame    // time sins last frame

由于速度随时间不断增加,我们需要计算自上一帧以来它增加了多少。距离上一帧越长,速度变化越大,我们将其与增量时间相乘

velocityDelta = deltaTime * gravityRate    // velocity change 

为了计算对象在帧中移动的程度,将计算该帧中的平均速度。这等于初始速度:
velocity.y
加上终点速度:
velocity.y+velocityDelta
,除以
2
。简而言之,这可以写成
(velocity.y+(velocityDelta/2))
。使用平均速度,我们可以通过乘以帧的增量时间来移动对象:

objectPosition.y -= (velocity.y + (velocityDelta / 2)) * deltaTime   

为了准备下一帧,我们还需要更新速度:

velocity.y += velocityDelta 

这还取决于用作3d/2d显示的内容以及用于渲染的内容。也就是说,你不能预先计算位置/速度/加速度的值,然后根据这些值绘制一个时间轴吗?@Nomad101我有一种感觉,无论我走到哪里,我都会遇到同样的问题。我有一种感觉,为了让它跳跃,我需要改变我的方式,但是我想不出一个办法,你能详细介绍一下预计算吗?我不确定我看到了你要做的事情,所以从我收集的资料来看,你正在尝试制作一个物体的动画来模拟重力。也就是说,设置对象动画的方式在很大程度上取决于渲染对象的方式。至于预计算,我的意思是你可以根据你的重力和你想要实现的任何碰撞来创建一张物体所在位置的地图。一旦生成了地图,您就可以基于此进行渲染,并且您将准确地返回地图应该位于的位置。@Nomad101例如在游戏中,这种方法会起作用吗?一个球员的动作?关于渲染,在这个循环之后,我所做的就是从我的渲染器对象中渲染它,它只是在我从循环中得到的最终位置上绘制对象。我试过了,但是我仍然有跳转本身的问题,同样的机会,我可以问一下,你期望delta保持什么吗?因为我编码的地方没有现成的,所以每次循环运行时我基本上都会节省时间,以毫秒为单位。我希望delta是从上一帧开始的时间。如果你想跳回,你也应该在
objectPosition.y
上这样做。这样,它将始终提供与帧速率无关的相同数量。如果我在objectPosition上执行此操作。y以及obejct不会直接向上跳,而不是平稳地向上跳吗?我已更新了答案,以考虑到您不断提高速度。这将允许您在撞到某物时降低速度。