用Lua实现基于观察者模型的游戏成就系统

博主进入游戏开发行业一年多,希望在有空之余能多理解几种开发模型,并运用到实际项目中,为了督促自己,会时不时写下博客。这是开发模型系列的第一篇博客,也是博主本人的第一篇博客,有误之处还望指出。

简单说明

具体定义可以查看其他资料。简单的来说,观察者模型可以实现:事件的发生与相应功能的执行解耦。具体咱们通过下面的例子理解这句话到底是啥意思。

适用的地方

当初我同事是如此实现游戏的成就系统的:例如玩家在成功升级仙友时,我需要在相应的代码处调用他给我的接口,以此来告诉他仙友升级了。其实从逻辑上来讲是很通顺的,但是这样有个问题。同事还开发了每日任务系统,也就是说我必须也在仙友升级那里调用他给我的每日任务接口。这种方式是事件的发生主动去关联那些对这个事件感兴趣的操作。这样不大好,应该是对这个事件感兴趣的操作主动去关联这个事件。因为前者是一对多,后者是一对一。后者对开发人员更加友好。这就是开头说的事件的发生和功能的执行耦合度过高了。实现各个模块的解耦一直是我们开发追究的,所以在这里我们可以尝试用观察者模型来重构这成就系统。

开始愉快的撸代码啦

大致从观察者和被观察者(主题)两个方面讲

被观察者

首先我们需要定义先撸出我们的游戏的事件系统,我们让这个事件系统来管理被观察者。

--这个是我们的事件的枚举,我们就以三种事件为例
ENUM_GameEvent = {--仙友模块举例Xianyou_Lvl_Up = 1, --仙友升级事件Xianyou_Skill_Up = 2,--仙友技能升级事件Xianyou_Star_Up = 3,--仙友升星
}--这是上个table的反表
ENUM_GameEventInverse = {--仙友模块举例[1] = "Xianyou_Lvl_Up",[2] = "Xianyou_Skill_Up",[3] = "Xianyou_Star_Up",
}--初始化事件系统
function IGameEventSystem:Init(  )CC.Print("init IGameEventSystem")self.gameEvents = {}
end--注册一个观察者
--enumGameEvent:事件名字, theKey:标记此观察者,为了更好的管理,theObserver:注册的观察者
function IGameEventSystem:RegisterObserver(enumGameEvent, theKey,theObserver) local subject = self:RegisterEvent(enumGameEvent)if subject thensubject:Attach({key = theKey,observer = theObserver})end
end--注册一个事件
function IGameEventSystem:RegisterEvent(enumGameEvent)if self.gameEvents[enumGameEvent] thenreturn self.gameEvents[enumGameEvent] --如果已经存在改事件就返回end local gameEventSubject = require "IGameEventSubject".IGameEventSubject:New()gameEventSubject:Init() --没有该事件,所以就为改事件生成一个主题if CC.ENUM.ENUM_GameEventInverse[enumGameEvent] thenself.gameEvents[enumGameEvent] = gameEventSubjectCC.Print("注册事件 " .. enumGameEvent)return gameEventSubjectelseCC.Print("还没有该事件的ENUM")end
end--事件发生,提醒注册改事件的observer更新
function IGameEventSystem:NotifySubject(enumGameEvent)if self.gameEvents[enumGameEvent] thenself.gameEvents[enumGameEvent]:Update()elseCC.Print("该事件没有注册")end
end

然后我们定义一个主题的类

--初始化事件主题
function IGameEventSubject:Init(  )self.gameEventObservers = {}
end--在主题中加入一个观察者
function IGameEventSubject:Attach(tVal)if self.gameEventObservers[tVal.key] == nil thenself.gameEventObservers[tVal.key] = tVal.observerCC.Print("注册观察者 " .. tVal.key)end
end--移除一个观察者
function IGameEventSubject:Detach(key)self.gameEventObservers[key] = nil
end--通知主题下面的所有观察者更新
function IGameEventSubject:Update(  )for k,v in CC.pairs(self.gameEventObservers) dov:Update()end
end

观察者

--初始化一个观察者
function IGameEventObserver:Init(tVal)self.key = tVal.key --改观察者的标记self.enumEvent = tVal.enumEvent --事件名称self.funcUpdate = tVal.funcUpdate --当被通知时所需要执行的函数igameEventSystem:RegisterObserver(tVal.enumEvent, tVal.key, self) -- 告诉事件系统,观察者的名字,对什么主题感兴趣
end--更新所需要执行的函数
function IGameEventObserver:Update(  )if self.funcUpdate thenself.funcUpdate()end
end

成就系统(为了方便测试,把一些测试函数也写在了这里,并且和monoBehaviour绑定)

function AchievementSystem:Start(  )CC.Print("observer begin")igameEventSystem:Init()self:C("Button"):Click("InitObserver")self:C("Button2"):Click("XianyouLvlup")self:C("Button3"):Click("SkillUp")
end--测试创建了三个个观察者,主分别是仙友升级和仙友技能升级
function AchievementSystem:InitObserver(  )local xianyouLvlUpObserver = iGameEventObserver:New()xianyouLvlUpObserver:Init({enumEvent = CC.ENUM.ENUM_GameEvent.Xianyou_Lvl_Up,key = "achievementSystem_ob1",funcUpdate = function (  )--当这个func执行的时候,说明该主题已经更新(仙友已经升级),然后更新之后需要做的相关操作写在这里CC.Print("成就系统观察者捕捉到:仙友升级" )end})local xianyouSkillUpObserver1 = iGameEventObserver:New()xianyouSkillUpObserver1:Init({enumEvent = CC.ENUM.ENUM_GameEvent.Xianyou_Skill_Up,key = "achievementSystem_ob1",funcUpdate = function (  )--当这个func执行的时候,说明该主题已经更新(仙友技能已经升级),然后更新之后需要做的相关操作写在这里CC.Print("成就系统观察者1捕捉到:仙友技能升级" )end})local xianyouSkillUpObserver2 = iGameEventObserver:New()xianyouSkillUpObserver2:Init({enumEvent = CC.ENUM.ENUM_GameEvent.Xianyou_Skill_Up,key = "achievementSystem_ob2",funcUpdate = function (  )--当这个func执行的时候,说明该主题已经更新(仙友技能已经升级),然后更新之后需要做的相关操作写在这里CC.Print("成就系统观察者2捕捉到:仙友技能升级" )end})
end--模拟仙友升级了
function AchievementSystem:XianyouLvlup(  )igameEventSystem:NotifySubject(CC.ENUM.ENUM_GameEvent.Xianyou_Lvl_Up)
end--模拟仙友技能升级了
function AchievementSystem:SkillUp(  )igameEventSystem:NotifySubject(CC.ENUM.ENUM_GameEvent.Xianyou_Skill_Up)
end

现在让我们来测试

unity中创建3个按钮:注册观察者(一共有三个观察者), 仙友升级, 仙友技能升级

点击注册观察者:

点击仙友升级:

点击仙友技能升级:

总结一下

观察者模型在开发用到地方还是挺多的,具体是否用,用哪里,怎么用,我觉得需要程序猿自己把握了。在下认为开发模型固然重要,但是不能过分奉为圭臬。如果用了开发模型后,代码反而僵硬,这还不如不用。

用Lua实现基于观察者模型的游戏成就系统相关推荐

  1. 基于文法模型的中文纠错系统

    基于文法模型的中文纠错系统 徐明 编译 论文地址:http://www.anthology.aclweb.org/W/W14/W14-6827.pdf 相关开源项目:https://github.co ...

  2. 毕设项目:基于BS模型的在线OJ系统

    系列文章目录 文章目录 系列文章目录 前言 一.在线OJ系统描述 二.在线编译模块 1.搭建一个HTTP服务器完成在线编译 2.收到HTTP请求,进行数据格式转化(HTTP中body的内容转换为JSO ...

  3. Google Play游戏成就系统,7招搞定用户留存!

    最近,谷歌Stadia平台的成就系统已经正式上线,用户使用电脑.电视和笔记本电脑进行Stadia游戏时可以得到实时成就获得通知,还可使用浏览器查看自己的成就解锁情况,完成度等信息. 对于这个新上线的& ...

  4. Google Play对游戏成就系统的要求和建议

    Google Play对游戏提供成就系统的支持,开发者可以使用谷歌提供的成就系统,这样可以节省很多时间.在使用谷歌提供的成就系统中,具有一些要求和建议,想要使用谷歌成就系统的开发者可以详细了解下面的内 ...

  5. PHP怎么写游戏成就系统,游戏成就系统成就了什么

    现年 25 岁的 Steven Rollins 是一家游戏网站的编辑.作为一名资深玩家,自打记事起,他就开启了自己的电子游戏生涯.小时候,他玩自己感兴趣的游戏,还和口味相投的小伙伴们彼此交换游戏,渐渐 ...

  6. 基于cocos2d-x引擎的游戏框架设计【转载】

    http://www.cnblogs.com/lancidie/archive/2013/03/18/2965564.html 基于cocos2d-x引擎的游戏框架设计 移动互联网浪潮正在彻底改变人们 ...

  7. 学影视模型还是游戏模型更有前景?

    选择影视模型还是游戏模型,同学们经常很纠结 到底学哪个课程更好呢?二者有没有互补? 回答这个问题之前,我们不妨先恶补些相关知识~ 游戏与影视模型有什么区别? 很多人都认为,模型无非就是模型,用不同的软 ...

  8. Pomelo:网易开源基于 Node.js 的游戏服务端框架

    Pomelo 是基于 Node.js 的高性能.分布式游戏服务器框架.它包括基础的开发框架和相关的扩展组件(库和工具包),可以帮助你省去游戏开发枯燥中的重复劳动和底层逻辑的开发.Pomelo 不但适用 ...

  9. 基于java的俄罗斯方块游戏系统设计与实现(项目报告+答辩PPT+源代码+数据库+截图+部署视频)

    基于Java的俄罗斯方块游戏的设计与实现 俄罗斯方块是一款风靡全球,从一开始到现在都一直经久不衰的电脑.手机.掌上游戏机产品,是一款游戏规则简单,但又不缺乏乐趣的简单经典小游戏,上手容易,适用范围广泛 ...

最新文章

  1. windows7 64位机上CUDA7.0配置及在VS2010中的简单使用举例
  2. 201406114331-黄智涛-OS 实验报告
  3. Wireshark如何选择多行
  4. 简单点儿、简单点儿、再简单点儿,其实世界可以不是我们想象的那么复杂
  5. 【webservice】Java JAX-WS和JAX-RS webservice
  6. Spring Boot 入门与实战笔记
  7. WPS for MacOS如何设置自动拼写检查
  8. C++自定义迭代器模板,实现ArrayList基本操作,自定义迭代器遍历
  9. 自定义的Spinner文字居中
  10. 微型计算机原理DL,微型计算机原理练习附解答.doc
  11. (转)移动互联加速金融科技的渗透 中国将成为全球最大智能投顾市场
  12. 湖南省对口升学c语言试题,湖南省对口升学计算机专业综合试卷试题.doc
  13. 车辆管理系统 c++
  14. Python基本数据类型字符串操作总结
  15. gogo protobuf
  16. STM IIC库函数
  17. 计算机算法的概念教案,高中信息技术 1.2 算法和算法的描述教案
  18. Python与人工神经网络(2)——使用神经网络识别手写图像
  19. 云计算介绍PPT2011-03版
  20. BSD是什么系统 BSD简介

热门文章

  1. matlab自学笔记一(台大郭彦甫)
  2. 脑电分析系列[MNE-Python-20]| 脑电图处理和事件相关电位(ERP)
  3. 【Java案例】用户登录注册
  4. 什么是传递函数模型?
  5. 全志XR829 WIFI和BT模块在T7 Android8.1上调试
  6. 国产实时操作系统+intel x86/龙芯平台超边缘计算机方案
  7. PR CC2019启动出现crash桌面文件
  8. C语言:memcpy的用法
  9. 3D空间堆叠PCB设计 ——PCB线路优化项目总结
  10. fcm的java实现_支持FCM的Java APNs库