#帧率 #逻辑 #变量 #游戏开发 #固定 #渲染 #输入

不依赖 std ftvf

在 Rust 中编写固定帧率、可变帧率游戏的时序逻辑

2 个不稳定版本

0.6.0 2023 年 9 月 21 日
0.5.0 2019 年 9 月 25 日

#352 in 游戏开发

Zlib 许可证

44KB
712

ftvf

ftvf 是一个用于以固定帧率、可变帧率执行游戏逻辑的包。通过将您的游戏逻辑放在严格可互换的滴答声中,而不是根据帧率变化,您将获得许多优势

  • 可重复性:相同的输入将产生相同的输出,仅此而已。
  • 帧率无关性:没有像 Quake 那样的问题,您的精确跳跃高度取决于您的计算机有多快。
  • 满意度:知道您做出了道德上正确的选择。 :)

额外奖励:如果您知道您的刷新率,ftvf 可以帮助您以恰好该速率渲染帧,无抖动。

要开始,将 ftvf 添加到 Cargo.toml 中的依赖项

ftvf = "0.6"

然后初始化一个 Metronome

let mut metronome = Metronome::new(
  RealtimeNowSource::new(),
  // want 30 ticks per 1 second
  Rate::per_second(30, 1),
  // accept being up to 5 ticks behind
  5,
);

然后您的游戏循环看起来像这样

while !world.should_quit() {
  world.handle_input();
  for reading in metronome.sample(Mode::UnlimitedFrames) {
    match reading {
      Reading::Tick => world.perform_tick(),
      Reading::Frame{phase} => world.render(phase),
      Reading::TimeWentBackwards
        => eprintln!("Warning: time flowed backwards!"),
      Reading::TicksLost
        => eprintln!("Warning: we're too slow, lost some ticks!"),
      // Mode::UnlimitedFrames never returns Idle, but other modes can, and
      // this is one way to handle it.
      Reading::Idle{duration} => std::thread::sleep(duration),
    }
  }
}

您的逻辑滴答在离散的固定时间间隔中运行。然后,当是渲染的时候,您渲染一帧,该帧代表两个滴答之间的一段时间,由其 phase 表示。您的渲染过程应根据 phase 的值渲染之前滴答和当前滴答之间的插值状态。简单示例

self.render_at(self.previous_position
               + (self.current_position - self.previous_position) * phase);

更改

自 0.5.0 以来

  • ftvf 不再依赖于 std。您可以使用 no_std 功能标志来去除 std 依赖项,但代价是无法使用内置的 RealtimeNowSource
  • Mode::MaxOneFramePerTick 已重命名为 Mode::OneFramePerTick
  • metronome.sample() 现在直接返回一个迭代器,而不是让您以纪律性的方式反复调用 metronome.status()
  • 现在使用新的Rate结构传递利率,而不是作为元组。
  • 现在的时间精度是完美的,而不仅仅是“只有”纳秒精度。(帧相位计算仍然使用纳秒精度,在运行时更改滴答/帧率也会丢弃亚纳秒部分。)
  • Status已被重命名为Reading
  • Reading::Idle现在直接以Duration的形式给出等待时间,而不是让您间接通过metronome
  • 添加了Mode::TargetFramesPerSecond
  • 现在可以在任何时候更改滴答率,没有任何时间异常——除了每次更改可能有一纳秒的一次性时间误差。
  • 已删除NowSource::sleep
  • NowSource不再隐含Copy
  • 现在为所有Deref<Target=RefCell<NowSource>>类型,包括&RefCell<NowSource>Box<RefCell<NowSource>>类型提供了一个通用的NowSource实现。这使得伪造的NowSources更加方便。
  • 现在有一个FakeNowSource,可带或不带no_std,您可以在任何实时不是关键因素的情况下使用它,例如单元测试或将渲染重放保存到磁盘。

许可

ftvf在zlib许可证下分发。完整的文本如下

版权(c)2019,2023 Solra Bizna

本软件按“原样”提供,不提供任何明示或暗示的保证。在任何情况下,作者都不会因使用本软件而承担任何损害赔偿责任。

任何人都可以出于任何目的使用本软件,包括商业应用,并自由修改和重新分发它,但须遵守以下限制

  1. 本软件的来源不得被误传;您不得声称您编写了原始软件。如果您将本软件用于产品中,产品文档中的致谢将被赞赏,但不是必需的。
  2. 更改的源代码版本必须清楚地标记为这样的版本,并且不得被误传为原始软件。
  3. 本通知不得从任何源分发中删除或更改。

无运行时依赖

功能