成就系统,基本上是每个游戏里都会涉及到的系统,但如果直接使用其它系统的函数接口,你将会发现整个项目中,每个系统都要和成就系统耦合在一起。

这是一件极其糟糕的事情。

观察者模式可以解决这件事情。


首先,我们先定义两个类,分别是观察者和被观察者。

观察者:

class Observer
{friend class Subject;public:Observer():next(nullptr), previous(nullptr) {}void OnNotify(const Unit unit, Event event) {}private:std::shared_ptr<Observer> next;std::shared_ptr<Observer> previous;
};

被观察者:

class Subject
{
public:Subject():head(nullptr) {}void AddObserver(std::shared_ptr<Observer> observer){observer->next = head;head = observer;}void RemoveObserver(std::shared_ptr<Observer> observer){if (observer->previous == nullptr)head = observer->next;elseobserver->previous = observer->next;}void Notify(const Unit unit,Event event){//相应事件//...auto observer = head;while (observer != nullptr){observer->OnNotify(unit, event);observer = observer->next;}}private:std::shared_ptr<Observer> head;
};

如何去使用它:

假如游戏中存在着一个邮件系统,当玩家发送第一封邮件时,解锁一个成就:

发信人:成功发送一封邮件给其他玩家

那我们只需要在邮件系统中定义:

class MailMgr
{
public:void OnRoleSendMail(Unit& unit){subject.Notify(unit, Event::EVENT_SENDMAIL);//...}private:Subject subject;
};

观察者模式本身只是发送了一个通知,它的逻辑是遍历一个观察者列表,然后调用函数,相对于一开始的直接函数调用,它并没有速度上的劣势,反而让两个游戏系统解耦,邮件系统开发者并不需要关注成就系统开发者做了什么事情。

如果非要说它的缺点:那就是多了一些内存的开销


进阶:

链表节点池:

我们可以对被观察者进行改造,在上面的代码中,被观察者存储的是一个观察者列表,现在改为存储一个指针列表,列表中的指针指向真正的观察者。

这样,多个指针可以指向同一个观察者,节省空间。

(当然,上面的代码使用的是智能指针,变向地支持了这个功能)

对象池:

由于所有的结点都是一样的大小和类型,可以预分配一个内存对象池子,根据需要去重用而不是不断地进行内存分配

 注册函数,而不是注册类:

在上面的代码中,我们是使用类来实现观察者(列表中存储的是对象指针),其实也可以改造成函数指针。

游戏设计模式-观察者模式相关推荐

  1. Unity游戏设计模式(二)观察者模式(Observer Pattern)

    最近看游戏设计模式,当看到观察者模式时被搞得云里雾里的,什么观察者,被观察者,抽象观察者,抽象被观察者.听着这些词就觉得可怕,其实理解以后还是比较简单的. 当我们玩游戏时,经常会出现一些事件,而这个事 ...

  2. 多人网络游戏服务器开发基础学习笔记 I:基本知识 | 游戏设计模式 | 网游服务器层次结构 | 游戏对象序列化 | 游戏 RPC 框架 | 帧同步和状态同步

    今天继续开新坑,尽管过了很多 Unix 套接字编程的坑,但是实际还是有很多不同场景和性能的需求,以及最服务器架构的内容也就接触过 preforking 和 master 带 worker 而已. 所以 ...

  3. 《游戏设计模式》学习笔记

    ** <游戏设计模式>学习笔记 ** 原作中文版传送门:<游戏设计模式> 原书作者:Bob Nystrom 阅读背景:最近担任了主程(惭愧,整个项目组就我一个人,2333),在 ...

  4. 设计模式-观察者模式(Observer)-Java

    设计模式-观察者模式(Observer)-Java 目录 文章目录 1.前言 2.示例案例-多人联机对战游戏的设计 3.观察者模式概述 3.1.观察者模式定义 3.2.观察者模式结构 3.3.观察者模 ...

  5. 设计模式-观察者模式(Observer Pattern)

    设计模式-观察者模式 观察者模式是使用频率最高的设计模式之一,它用于建立一种对象与对象之间的依赖关系,一个对象发生改变时将自动通知其他对象,其他对象将相应作出反应.在观察者模式中,发生改变的对象称为观 ...

  6. Python设计模式-观察者模式

    Python设计模式-观察者模式 代码基于3.5.2,代码如下; #coding:utf-8 # 观察者设计模式class observerInterface():def update(self,va ...

  7. [Head First设计模式]山西面馆中的设计模式——观察者模式

    原文:[Head First设计模式]山西面馆中的设计模式--观察者模式 系列文章 [Head First设计模式]山西面馆中的设计模式--装饰者模式 引言 不知不自觉又将设计模式融入生活了,吃个饭也 ...

  8. 游戏设计模式——C++单例类

    前言: 本文将探讨单例类设计模式,单例类的懒汉模式/饿汉模式,单例类的多线程安全性,最后将利用C++模板减少单例类代码量. 本文假设有一个Manager管理类,并以此为探究单例类的设计模式. 懒汉模式 ...

  9. java设计模式--观察者模式(Observer)

    java设计模式--观察者模式(Observer) java设计模式--观察者模式(Observer) 观察者模式的定义: 定义对象间的一种一对多的依赖关系.当一个对象的状态发生改变时,所有依赖于它的 ...

最新文章

  1. 批量mergeinto
  2. 因为一个跨域请求,我差点丢了饭碗!
  3. [react] react的函数式组件有没有生命周期?
  4. 电脑电池修复_笔记本电脑充不进去电如何修复
  5. 矩阵连乘 动态规划_利用动态规划解LeetCode第62题:不同路径
  6. 再学点分治——动态点分治
  7. truffle version/usr/local/lib/node_modules/truffle/build/385.bundled.js:65232 catch cli.bundled.js:6
  8. JanusGraph组件对应版本
  9. mysql如何查看使用的配置_mysql 配置文件如何查询?
  10. C语言——判断一个数字是否为质数(素数)!
  11. 计算机桌面 文字大小,敬业签电脑桌面便签软件怎么设置字体字号大小?
  12. QT-功能-实现主页面和子页面之间的跳转(最简单)
  13. CF1290F Making Shapes——数位背包DP
  14. matlab的雷劈数算法,寻找雷劈数
  15. HFSS初探日志(六)被动毫米波成像系统馈源天线
  16. 网盘加速器PanDownload+网盘倍速播放
  17. 杭电计算机复试面试题库,杭电电子分院历年复试题(整理版).doc
  18. Vs Code配置前端环境及运行
  19. c语言花卉销售与管理系统,花卉销售与管理系统
  20. 【转载】C++的就业状况与方案。

热门文章

  1. Aggressive cows-疯牛POJ(2456)-详解
  2. Ant Design 中覆盖组件样式
  3. 分布式 | 如何通过 dble 的 split 功能,快速地将数据导入到 dble 中
  4. 微信小程序在智能家居物联网中的应用
  5. 0. DRF之软件开发模式CBV源码解析
  6. PHP将word文件转为图片预览
  7. 电脑蓝屏错误代码0x0000007e的解决方法
  8. 解决C#调用Excel接口时报错,提示:Microsoft.Office.Interop.Excel.ApplicationClass”的 COM 对象强制转换为接口类型“Microsoft.Offi
  9. 暗影骑士vn7安装linux,宏碁暗影骑士一代(VN7-591G)拆机清灰教程
  10. 通用计算机的发展历程,中国计算机发展史