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

8 篇文章 0 订阅
1 篇文章 0 订阅

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处理消息


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值