您的位置:首页 > 移动开发 > Cocos引擎

cocos2dx中的观察者模式

2016-08-02 19:56 190 查看
**

一、什么是观察者模式

当我们对感兴趣的消息进行订阅,一旦有新的动态,就可以收到这些消息。更重要的是,我们不需要时刻关注,消息会自动到达,这就是观察者模式。
在游戏中,观察者模式有很大的作用。比如游戏中的战斗,角色的死亡信息可以被订阅,当角色死亡时,订阅该消息的主体就能做出一些处理(比如怪物停止攻击,弹出死亡界面等等)


**

二、cocos中提供的观察者模式工具类

1.addObserver(订阅消息)

1)Ref* target:要订阅的消息主体

2)SEL_CallFunco selector:消息的回调函数

3)const std::string& name:消息名称

4)Ref* sender: 要传递的数据

2.removeObserver(取消订阅消息)

1)Ref* target:取消订阅消息的主体

2)const std::string& name:消息名称

3.postNotification(发布消息)

1)const std::string& name:消息名称

4.postNotification(发布消息)

1)const std::string& name:消息名称

2)Ref* sender:传递的数据

在发布消息的时候带上一个数据,订阅者在接收消息的时候就能获得所需要的数据

下面通过程序创建两个层,分别是HelloWorld与otherLayer,HelloWorld作为主体订阅otherLayer发布的消息。

查看下面例子方便理解

#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__

#include "cocos2d.h"

class HelloWorld : public cocos2d::Layer
{
public:
static cocos2d::Scene* createScene();
virtual bool init();
CREATE_FUNC(HelloWorld);

/* 发布test消息 */
void sendMsg(float dt);

/* 接收test消息的回调函数 */
//void testMsg(Ref* pSender);
};

#endif // __HELLOWORLD_SCENE_H__


头文件在下面的cpp文件实现

#include "HelloWorldScene.h"
#include "OtherLayer.h"

USING_NS_CC;

Scene* HelloWorld::createScene()
{
auto scene = Scene::create();
auto layer = HelloWorld::create();
scene->addChild(layer);

/* 再添加一个layer */
auto otherLayer = OtherLayer::create();
scene->addChild(otherLayer);

return scene;
}

// on "init" you need to initialize your instance
bool HelloWorld::init()
{
if (!Layer::init())
{
return false;
}
/* 订阅消息类型为test的消息,不传递数据 */
//     NotificationCenter::getInstance()->addObserver(
//         this,
//         callfuncO_selector(HelloWorld::testMsg),
//         "test",
//         NULL);

/* 3秒后发布test消息 */
this->schedule(schedule_selector(HelloWorld::sendMsg), 3.0f);
return true;
}

void HelloWorld::sendMsg(float dt) {
/* 发布test消息,不传递数据 */
NotificationCenter::getInstance()->postNotification("test", NULL);
}

//void HelloWorld::testMsg(Ref* pSender) {
//    log("testMsg");
//}


这里新建了一个OtherLayer,在该类里面订阅test消息,将原来HelloWorldScene里面的testMsg函数删除,订阅消息的代码也删除。

我们把OtherLayer添加到HelloWorldScene的场景中,并把HelloWorldScene订阅消息的代码删除,则HelloWorldScene现在只负责3秒后的发送消息,运行最后可以看到日志输出

testMsg in OtherLayer

#ifndef _OtherLayer_H_
#define _OtherLayer_H_

#include "cocos2d.h"
USING_NS_CC;

class OtherLayer : public Layer {
public:
CREATE_FUNC(OtherLayer);
virtual bool init();

private:
/* 接收test消息的回调函数 */
void testMsg(Ref* pData);
};

#endif


#include "OtherLayer.h"

bool OtherLayer::init() {
if (!Layer::init())
{
return false;
}

/* 订阅消息类型为test的消息,传递数据 */
NotificationCenter::getInstance()->addObserver(
this,
callfuncO_selector(OtherLayer::testMsg),
"test",
NULL);

return true;
}

void OtherLayer::testMsg( Ref* pData ) {
//log("testMsg in OtherLayer");
log("testMsg in OtherLayer");
}


总结:我们在HelloWorldScene里面发布消息,在OtherLayer里面接收消息。

HelloWorldScene是订阅的主体,接受了OtherLayer传递过来的数据。

/* 3秒后发布test消息 */
this->schedule(schedule_selector(HelloWorld::sendMsg), 3.0f);
return true;
}

void HelloWorld::sendMsg(float dt) {
/* 发布test消息,不传递数据 */
NotificationCenter::getInstance()->postNotification("test", NULL);
}


而OtherLayer在向HelloWorldScene这个层传递消息时,需要建立消息的订阅

NotificationCenter::getInstance()->addObserver(
this,
callfuncO_selector(OtherLayer::testMsg),
"test",
NULL);

void OtherLayer::testMsg( Ref* pData ) {
//log("testMsg in OtherLayer");
log("testMsg in OtherLayer");


三、关于addObserver与postNotification函数中最后个参数传递数据的区别

1.如果addObserver与postNotification同时发布了数据,并且不是同一个数据,则无法发布消息

2.要发布消息的条件是,要么两个数据相同,要么两者其中之一为空值,才能发布消息
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: