帧率独立加速

发布于 2024-10-21 09:22:26 字数 529 浏览 10 评论 0原文

所以我明白,为了获得与帧速率无关的运动,我必须将基本速度乘以(1000/delta)。它适用于代表速度的值,但是当我尝试使用加速度变量(例如重力)时,它不起作用,它甚至与帧速率无关。

加速度变量是否有不同的公式,或者我忘记了什么?

示例:

var Multiplier:Number = (GetDeltaTime()) / (1000 / 30);
jumpVelocity = -21 * Multiplier //works
gravity = 1.5 * Multiplier //dosn't work

这在每帧开始时调用

编辑:找到解决方案,我必须对增量时间进行平方。不能 100% 确定它为什么有效,但它确实有效。

所以:

jumpVelocity = -21 * Multiplier //unchanged
gravity = 1.5 * Math.pow(Multiplier,2) //works now

So I understand that, to get frame rate independent movement I have to multiply the base speed by (1000/delta). It works on values that represent speed, but when I try this with an acceleration variable, e.g. gravity, it won't work, it isn't even frame rate independent.

Is there a different formula for acceleration variables, or am I forgetting something else?

Example:

var Multiplier:Number = (GetDeltaTime()) / (1000 / 30);
jumpVelocity = -21 * Multiplier //works
gravity = 1.5 * Multiplier //dosn't work

This is called at the start of every frame

Edit: Found a solution, I had to square delta time. Not 100% sure why it works, but it does.

So:

jumpVelocity = -21 * Multiplier //unchanged
gravity = 1.5 * Math.pow(Multiplier,2) //works now

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

染墨丶若流云 2024-10-28 09:22:26

基本上,您想要做的是测量自上一帧以来经过的时间(“帧时间”),并将其添加到累加器中。

然后,您可以按“固定时间步长”(例如 1/30 秒)转发游戏状态,并从累加器中减去模拟时间,直到它小于一个时间步长。

举个例子:

  • 累加器从 0 开始
  • 固定时间步长设置为 33ms

  • 1 帧以 20fps 的速度通过,帧时间为 1000ms/20 = 50ms

  • 50ms 添加到累加器
  • 游戏状态按 1 个固定时间步长(33ms)转发,从累加器中减去该时间
  • 现在累加器为 17ms,小于 1 个固定时间步骤->游戏状态完成更新
  • 继续到下一帧

  • 1 帧以 10fps 的速度传递,帧时间为 1000ms/10 = 100ms

  • 100ms 添加到累加器
  • 累加器现在
  • 为 117ms 游戏状态转发 1 个固定时间步长(33ms),从累加器减去
  • 累加器的时间现在为 84ms,这超过了一个固定时间步长 ->游戏状态未完成更新
  • 游戏状态被转发 1 个固定时间步长(33ms),从累加器中减去该时间累加器
  • 现在为 51ms,这超过了一个固定时间步长 -> 1游戏状态未完成更新
  • 游戏状态被转发1个固定时间步长(33ms),从累加器中减去该时间
  • 累加器现在是18ms,这小于1个固定时间步长->1游戏状态已完成更新,
  • 继续下一帧

Glenn Fiedler 有一篇关于这个问题的优秀文章。您可以在此处找到它。

Basically what you want to do is measure the time that has passed since the last frame (the "frame time"), and add that to an accumulator.

You then forward your game's state by "fixed time steps" (e.g. 1/30th of a second) and subtract that simulated time from the accumulator until it is less than one time step.

So as an example:

  • accumulator starts at 0
  • fixed time step set to 33ms

  • 1 frame passes at 20fps, the frame time was 1000ms/20 = 50ms

  • 50ms added to accumulator
  • game state is forwarded by 1 fixed time step (33ms), that time is subtracted from accumulator
  • accumulator is now 17ms, which is less than one fixed time step -> game state is done updating
  • continue to next frame

  • 1 frame passes at 10fps, the frame time was 1000ms/10 = 100ms

  • 100ms added to accumulator
  • accumulator is now 117ms
  • game state is forwarded by 1 fixed time step (33ms), that time is subtracted from accumulator
  • accumulator is now 84ms, which is more than one fixed time step -> game state is not done updating
  • game state is forwarded by 1 fixed time step (33ms), that time is subtracted from accumulator
  • accumulator is now 51ms, which is more than one fixed time step -> game state is not done updating
  • game state is forwarded by 1 fixed time step (33ms), that time is subtracted from accumulator
  • accumulator is now 18ms, which is less than one fixed time step -> game state is done updating
  • continue to next frame

There is an excellent article by Glenn Fiedler about just this issue. You can find it here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文