【问题标题】:Framerate independent acceleration帧率独立加速
【发布时间】:2011-03-11 12:45:34
【问题描述】:

所以我明白,要获得与帧速率无关的运动,我必须将基本速度乘以 (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

【问题讨论】:

  • 我对动作脚本一无所知,但我知道物理学,这对我来说毫无意义。你知道单位吗?你能给我们一些数字,告诉我们出了什么问题(不仅仅是“它不起作用”)吗?
  • 单位是像素/30 秒。基本上,除了加速度、重力和摩擦之外,一切都有效。所有这些都会改变速度,而不是坐标。在更高的帧速率下,这些值似乎会增加(例如更快的加速度、更高的重力)。

标签: actionscript-3 physics formula


【解决方案1】:

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

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

举个例子:

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

  • 1 帧以 20fps 传递,帧时间为 1000ms/20 = 50ms

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

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

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

Glenn Fiedler 有一篇关于这个问题的优秀文章。你可以找到它here

【讨论】:

  • 感谢您的帮助,但我之前确实读过那篇文章。我决定不使用它,因为如文章最后一节所述,每帧可能会采取不同数量的步骤,从而使其不稳定。这篇文章为此提供了一个解决方案,但我正在使用闪存,它会太慢。
  • @simon 澄清一下:固定时间步长物理的整个想法是它确实看起来不稳定。事实上,如果您更进一步并插入状态(在文章末尾提到),您将在任何游戏、任何模拟、任何地方获得最平滑、最美观的结果。也许this link 会有所帮助。看看两个示例 swf,分别是“基于帧的案例研究”和“基于计时器的案例研究”,并告诉我哪个看起来不连贯:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-03
  • 2011-10-17
  • 2017-04-24
相关资源
最近更新 更多