加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

利用观察者模式实现Cocos2DX-lua游戏中的消息管理系统

发布时间:2020-12-14 16:34:19 所属栏目:百科 来源:网络整理
导读:http://blog.csdn.net/operhero1990/article/details/48575487 游戏中某些对象往往需要及时获知其他特定对象状体的改变。为降低类之间的耦合度,可以建立消息管理系统,实现消息的集中与分发。观察者(也叫发布-订阅)模式很容易实现这套系统。观察者模式是

http://blog.csdn.net/operhero1990/article/details/48575487

游戏中某些对象往往需要及时获知其他特定对象状体的改变。为降低类之间的耦合度,可以建立消息管理系统,实现消息的集中与分发。观察者(也叫发布-订阅)模式很容易实现这套系统。观察者模式是一种比较成熟的设计模式,基本概念可以通过百度获得,这里不再赘述。

消息管理系统实际分为:管理中心,观察者,订阅者三部分。

一、管理中心

这里先上实现代码:

--
-- file: msgCenter.lua
-- desc: 消息管理中心
--================================================


hp.msgCenter = {}


-- 消息定义
hp.MSG =
{
	CHANGEDTYPE_1 = 1,--变化1
	CHANGEDTYPE_2 = 2,--变化2
}


-- 消息处理者
local msgMgr = {}

-- addMsgMgr
-- 添加消息处理
-----------------------------------------
function hp.msgCenter.addMsgMgr(msg_,mgr_)
	if msgMgr[msg_]==nil then
		msgMgr[msg_] = {}
	else
		for i,v in ipairs(msgMgr[msg_]) do
			if v==mgr_ then
			-- 已添加
				return false
			end
		end
	end
	table.insert(msgMgr[msg_],mgr_)

	return true
end

-- removeMsgMgr
-- 移除消息处理
-----------------------------------------
function hp.msgCenter.removeMsgMgr(msg_,mgr_)
	if msgMgr[msg_]~=nil then
		for i,v in ipairs(msgMgr[msg_]) do
			if v==mgr_ then
				table.remove(msgMgr[msg_],i)
				break
			end
		end
	end

	return true
end

-- sendMsg
-- 发送消息
-----------------------------------------
function hp.msgCenter.sendMsg(msg_,param_)
	if msgMgr[msg_]~=nil then
		for i,v in ipairs(msgMgr[msg_]) do
			v:onMsg(msg_,param_)
		end
	end
end


hp.msgCenter:外部调用接口

消息定义:消息系统需要处理不同类型的消息,这里相当于消息类型的宏定义

消息处理者msgMgr:存储订阅者的表

添加消息处理hp.msgCenter.addMsgMgr(msg_,mgr_):将订阅者以及订阅的消息类型存储于消息处理者msgMgr表中。msg_为消息定义宏中的一种,mgr_为订阅者

移除消息处理hp.msgCenter.removeMsgMgr(msg_,mgr_):与添加消息对应

发送消息hp.msgCenter.sendMsg(msg_,param_):由观察者调用此方法,向所有订阅者发送参数param_。订阅者通过自身onMsg方法接收并处理订阅消息。


二、观察者

观察者部分较为简单,只需调用发送消息方法即可:hp.msgCenter.sendMsg(hp.MSG.CHANGEDTYPE_1,“消息类型1”)


三、订阅者

订阅者主要分为两步:注册消息和响应消息处理

这里我们构建一个订阅者基类,提供消息订阅方法,并建立消息订阅表,方便对象析构时及时移除消息订阅

--
-- Listener.lua
-- 订阅者基类
--================================================

Listener = Listener or class("Listener")

--
-- ctor
-------------------------------
function Listener:ctor(...)	
	self.super.init(self)
	self:init(...)
end

--
-- init
----------------------------
function Listener:init()
	self.manageMsg = {}
end

--
-- preExit
----------------------------
function Listener:preExit()
	self:unregistAllMsg()
end

--
-- onExit
----------------------------
function Listener:onExit()
	self:unregistAllMsg()
end

--
-- 消息处理
--=============================================
-- registMsg
function Listener:registMsg(msg_)
	if hp.msgCenter.addMsgMgr(msg_,self) then
		table.insert(self.manageMsg,msg_)
	end
end

-- unregistMsg
function Listener:unregistMsg(msg_)
	if hp.msgCenter.removeMsgMgr(msg_,self) then
		for i,v in ipairs(self.manageMsg) do
			if v==msg_ then
				table.remove(self.manageMsg,i)
			end
		end
	end
end

-- unregistMsg
function Listener:unregistAllMsg()
	for i,v in ipairs(self.manageMsg) do
		hp.msgCenter.removeMsgMgr(v,self)
	end

	self.manageMsg = {}
end

-- onMsg
function Listener:onMsg(msg_,parm_)
end

其他类继承订阅者基类即可实现消息订阅功能:
-- file:MyListener.lua
-- desc:订阅者
-- =====================================

MyListener = class("MyListener",Listener)

-- 初始化
function MyListener<span style="font-family: Arial,Helvetica,sans-serif;">:init()</span>
	local function bindGuide(parm_)
		print(parm_)
	end
	self.bindGuide = bindGuide
	self:registMsg(hp.MSG.CHANGEDTYPE_1)
end

-- onMsg
function MyListener:onMsg(msg_,parm_)
	if msg_==hp.MSG.CHANGEDTYPE_1 then
		self.bindGuide(parm_)
	end
end
MyListener首先订阅hp.MSG.CHANGEDTYPE_1,onMsg接受消息时,判断发过来的消息是否为订阅的类型,并调用相应的处理函数self.bindGuide处理消息

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读