周笔记(21/52) - 过一下《游戏编程模式》

0 0 开始写游戏才发现架构这件事确实很重要哎~ 以及这本书确实是既通俗易懂又干货满满!我这种小白都能愉悦的读完~

几个重要的问题

  1. 相同数据的共享
  2. 相同代码的共享
  3. 性能
  4. 扩展性
  5. 令人犯错概率

典型的设计

  1. 命令模式
    • 封装命令(类似闭包)
    • 可以在命令生效的时候再传入需要操作的对象
  2. 享元模式
    • 数据共享
    • 缓存命中的问题与数据的存放方式有关
  3. 观察者模式
    • Event/EventHandler
    • 可以考虑将链表挂在观察者or被观察者身上
  4. 原型模式
    • 使用类模板/函数传参/类方法 等方式来实现
    • 对数据使用原型模式
  5. 单例模式
    • 使用编译时或者运行时单例
    • 全局的并不一定都是好的,会有多线程、访问无限制等问题
    • 注意延迟初始化会造成卡顿的问题
    • 可以以传参/挪到基类的方式替代
  6. 状态模式(FSM)
    • 功能
      • 进入、退出时切换状态
      • 状态有各自的接收消息、转换规则
      • 状态有各自的运行中的逻辑
    • 扩展
      • 并发状态机:两个状态机,处理两组关联较小的状态,对于其之间的耦合可以用if简单应付
      • 层次状态机:对状态机进行继承
      • 状态栈:为状态机增加历史记录
  7. 双缓冲
    • 如果交换数据的时间比写入数据的时间小得多,那么可以用这个
    • 在需要统一变换的过程中很好用,例如显示图片、帧之间的大量对象的状态切换
  8. 游戏循环
    • 使用sleep来减少发热
    • 对优先级比较高的进行固定循环,其他的视时间循环,例如分离physics和rendering
  9. 解释器模式
    • 内部操作:将数据和函数编码为简单的字符,方便使用
    • 外部数据:压栈,在编译到函数编码部分的时候出栈使用
    • 控制流:实现if、while等
    • 制作一个图形界面来方便使用和减少出错
  10. 子类沙盒
    • 在父类上放上子类可能需要的所有函数
    • 子类只能在父类的范围内调用函数,不能调用任何外部函数
    • 可以获得封装性
    • 继承会造成“脆弱的基类”的问题,可以将所需要的数据传递给基类而后获取其上的功能
  11. 类型对象
    • 将类型封装为对象,其不同表现作为数据
  12. 组件模式
    • 组件之间通信的问题,可以直接引用其他组件来处理,或者建立一个小型的事件系统
  13. 事件队列
    • 将事件按照顺序进入队列然后依次处理
    • 注意事项:
      • 会剥夺发送者对事件的控制
      • 全局的总是有些糟糕
      • 避免死循环
      • 对象的所有权(释放对象的问题)
    • 可以使用环状缓冲区
    • 可以汇总事件进行处理
  14. 服务定位
    • 在使用的时候查找所需要的服务然后使用
    • 依然有全局的问题
    • 服务不能使用的时候,可以考虑返回空服务,或者各方处理异常
  15. 数据局部性
    • 缓存命中率会很大程度的提高速度
    • 方法
      • 将需要循环处理的数据放在相近的内存块,例如组件模式中的同组件(如果是按照组件类型进行循环的话)
      • 减少if-else的可能性,例如试图将需要判断的if-else移到循环外
      • 热/冷分解,将用的比较多的数据放在一起
      • 避免继承和指针集合
  16. 脏标记模式
    • 如果修改的次数比使用的次数多,或者更新数据的计算过程比较长
    • 注意脏标记的粒度,比如为每个物体都设置脏标记,还是所有物体一块设置一个
  17. 对象池
    • 可以考虑扩容、清理现存对象、不创建对象的方法来处理对象池不够了的问题
  18. 空闲分区
    • 将数据按照他的位置组织数据结构,来高效定位
    • 将战场划分为网格,网格内可以采用链表循环等
    • 考虑分区更多的依赖是战场面积还是对象数量
    • 四叉树/二叉空间分割/k-dimensional树/层次包围盒

你可能感兴趣的:(设计模式,每周笔记)