用序列的操作模拟瞬间或者同时发生的事情
- 我们需要维护一些被增量修改的状态。
- 在修改到一半的时候,状态可能会被外部请求。
- 我们想要防止请求状态的外部代码知道内部的工作方式。
- 我们想要读取状态,而且不想等着修改完成。
定义缓冲类封装了缓冲:一段可改变的状态。 这个缓冲被增量地修改,但我们想要外部的代码将修改视为单一的原子操作。 为了实现这点,类保存了两个缓冲的实例:下一缓冲和当前缓冲。
当信息从缓冲区中读取,它总是读取当前的缓冲区。 当信息需要写到缓存,它总是在下一缓冲区上操作。 当改变完成后,一个交换操作会立刻将当前缓冲区和下一缓冲区交换, 这样新缓冲区就是公共可见的了。旧的缓冲区成为下一个重用的缓冲区。
优点
- 双缓冲模式位于底层,它对代码库的其他部分影响较小
缺点
- 交换本身需要时间
- 保存两个缓冲区,增加了内存的使用
独立的设计模式,需要它时自然会想起的模式
在游玩中不断运行。 每一次循环,它无阻塞地处理玩家输入,更新游戏状态,渲染游戏。 它追踪时间的消耗并控制游戏的速度
如果你使用游戏引擎,你不需要自己编写,但是它还在那里。
- 使用平台的事件循环:
- 简单。你不必担心编写和优化自己的游戏核心循环。
- 平台友好。 你不必明确地给平台一段时间让它处理它自己的事件,不必缓存事件,不必管理任何平台输入模型和你的不匹配之处。
- 你失去了对时间的控制。 平台会在它方便时调用代码。 如果这不如你想要的那样平滑或者频繁,太糟了。 更糟的是,大多数应用的事件循环并未为游戏设计,通常是又慢又卡顿。
- 使用游戏引擎的循环:
- 不必自己编写。 编写游戏循环非常需要技巧。 由于是每帧都要执行的核心代码,小小的漏洞或者性能问题就对游戏有巨大的影响。 稳固的游戏循环是使用现有引擎的原因之一。
- 不必自己编写。 当然,硬币的另一面是,如果引擎无法满足你真正的需求,你也没法获得控制权。
- 自己写:
- 完全的控制。 你可以做任何想做的事情。你可以为游戏的需求订制开发。
- 你需要与平台交互。 应用框架和操作系统通常需要时间片去处理自己的事件和其他工作。 如果你拥有应用的核心循环,平台就没有这些时间片了。 你得显式定期检查,保证框架没有挂起或者混乱。
独立的设计模式,需要它时自然会想起的模式