游戏里的时钟
正如上篇文章《游戏里的调度器》提到的,游戏里的时钟是非常重要的一个环节。但想把时钟做好,却可能更加困难,因为我们没有更多的手段来对付这个难题。
大部分的游戏都采取 Main Game Loop 机制,只要游戏在运行,循环就在持续,每帧一次,永不停息。来让我们看看,每帧都需要做些什么:
- Accept User Input :接受用户的键盘/鼠标输入
- 更新游戏场景里的一切
- 渲染所有可见对象
- 网络游戏中要处理数据包
- 运行游戏对象的业务逻辑
上面的各个步骤依照不同的顺序执行, 但也未必需要都在同一帧内执行,有的任务也可以隔若干帧执行一次,记得上篇文章里讲过延迟执行的任务吗?调度器的执行也是建立在这样一个循环上面的。但令我们头疼的是:随着游戏的进行,每一帧的长度实际上在不断变化的,而且很有可能这个变化的幅度是如此之大,这个变化是游戏呈现出莫名其妙的样子。
我们希望有一个可靠的时钟系统来支持游戏:
- 获取当前时间
- 获取帧的长度
- 暂停
- 缩放
- 归零
- 独立于游戏部分
- 帧长度固定
- 足够的精度
全局时钟 和 局部时钟:GlobalClock LocalClock
GlobalClock:这是一个总的时间源。
LocalClock:为游戏中的不同用途而创建的,可以暂停,归零,缩放,变帧长度...
现在我们提到一个重要的问题,如何让帧长度是固定的,这么说或许是理想化的说法,那么换一种,如果让帧长度的差值不会太大。读过两种做法:取平均帧长度和设置帧长度上限。
下面向大家展示一张图,是以5帧的帧长度的平均值为过滤的。
看上去很酷,是吗?可实际上要实现这样的效果,恐怕不是一件容易的事情,时钟是一个需要长期探讨下去的课题。
大家如果感兴趣,可以时常来看看,接下来要写点代码来尝试验证验证了。在实践中有所心得后,和大家分享。还是那句话:纸上得来终觉浅,须知此事要躬行。