《游戏编程模式》--序列模式--学习

在线阅读:

序列模式 · 游戏设计模式 (tkchu.me)

参考文章:

GameDesignPattern_U3D_Version/Assets/007SequencingPatterns at master · TYJia/GameDesignPattern_U3D_Version · GitHub

目录

序列模式

双缓冲模式

何时使用

提醒:

缓冲区是如何被交换的

在缓冲区之间拷贝数据

缓冲的粒度如何

如果缓存是一整块

 如果很多对象都持有一块数据

游戏循环

 模式:

更新方法

更新方法适应以下情况:


序列模式

 游戏循环是时钟的中心轴。 对象通过更新方法来聆听时钟的滴答声。 我们可以用双缓冲模式存储快照来隐藏计算机的顺序执行,这样看起来世界可以进行同步更新。

双缓冲模式

用序列的操作模拟瞬间或者同时发生的事情。

定义缓冲类封装了缓冲:一段可改变的状态。 这个缓冲被增量地修改,但我们想要外部的代码将修改视为单一的原子操作。 为了实现这点,类保存了两个缓冲的实例:下一缓冲当前缓冲

当信息缓冲区中读取,它总是读取当前的缓冲区。 当信息需要写缓存,它总是在下一缓冲区上操作。 当改变完成后,一个交换操作会立刻将当前缓冲区和下一缓冲区交换, 这样新缓冲区就是公共可见的了。旧的缓冲区成为下一个重用的缓冲区。

何时使用

  • 我们需要维护一些被增量修改的状态。
  • 在修改到一半的时候,状态可能会被外部请求。
  • 我们想要防止请求状态的外部代码知道内部的工作方式。
  • 我们想要读取状态,而且不想等着修改完成。

提醒:

交换本身需要时间

我们得保存两个缓冲区 

class Scene
{
public:
  Scene()
  : current_(&buffers_[0]),
    next_(&buffers_[1])
  {}

  void draw()
  {
    next_->clear();

    next_->draw(1, 1);
    // ...
    next_->draw(4, 3);

    swap();
  }

  Framebuffer& getBuffer() { return *current_; }

private:
  void swap()
  {
    // 只需交换指针
    Framebuffer* temp = current_;
    current_ = next_;
    next_ = temp;
  }

  Framebuffer  buffers_[2];
  Framebuffer* current_;
  Framebuffer* next_;
};

缓冲区是如何被交换的

在执行交换操作的时候,我们必须锁住两个缓冲区上的读取和修改,为了让性能最优,我们需要它进行的越快越好

交换缓冲区的指针或引用:

  • 速度快。 不管缓冲区有多大,交换都只需赋值一对指针。很难在速度和简易性上超越它。

  • 外部代码不能存储对缓存的永久指针。 这是主要限制。 由于我们没有真正地移动数据,本质上做的是周期性地通知代码库的其他部分到别处去寻找缓存, 就像前面的舞台类比一样。这就意味着代码库的其他部分不能存储指向缓冲区中数据的指针—— 它一段时间后可能就指向了错误的部分。

    这会严重误导那些期待缓冲帧永远在内存中的固定地址的显卡驱动。在这种情况下,我们不能这么做。

  • 缓冲区中的数据是两帧之前的数据,而不是上一帧的数据。

在缓冲区之间拷贝数据

  • 下一帧的数据和之前的数据相差一帧。 拷贝数据与在两块缓冲区间跳来跳去正相反。 如果我们需要前一帧的数据,这样我们可以处理更新的数据。

  • 交换也许更花时间。 这个当然是最大的缺点。交换操作现在意味着在内存中拷贝整个缓冲区。 如果缓冲区很大,比如一整个缓冲帧,这需要花费可观的时间。 由于交换时没有东西可以读取或者写入任何一个缓冲区,这是一个巨大的限制。

缓冲的粒度如何

如果缓存是一整块

  • 交换操作更简单 由于只有一对缓存,一个简单的交换就完成了。 如果可以改变指针来交换,那么不必在意缓冲区大小,只需几部操作就可以交换整个缓冲区。

 如果很多对象都持有一块数据

交换操作更慢。 为了交换,需要遍历整个对象集合,通知每个对象交换。

游戏循环

将游戏的进行和玩家的输入解耦,和处理器速度解耦。

游戏循环的第一个关键部分:它处理用户输入,但是不等待它

 模式:

一个游戏循环在游玩中不断运行。 每一次循环,它无阻塞地处理玩家输入更新游戏状态渲染游戏。 它追踪时间的消耗并控制游戏的速度。

更新方法

通过每次处理一帧的行为模拟一系列独立对象。

​​​​​​​游戏世界管理对象集合。 每个对象实现一个更新方法模拟对象在一帧内的行为。每一帧,游戏循环更新集合中的每一个对象。

更新方法适应以下情况:

  • 你的游戏有很多对象或系统需要同时运行。

  • 每个对象的行为都与其他的大部分独立。

  • 对象需要跟着时间进行模拟。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值