cocos2d-x的消息和数据传递

原创作品,转载请标明http://blog.csdn.net/jackystudio/article/details/17088979


如何在层间或者场景间进行消息传递,大概是每个初学者都要面对的问题吧。这里介绍cocos2d-x的一种消息/数据传递方式,内置的观察者模式,也称消息通知中心,CCNotificationCenter。


1.CCNotificationCenter

CCNotificationCenter是cocos2d-x提供的一个消息中心,类似于观察者模式,是一个单例类,用于辅助控制消息传递。大概工作原理如下图。



这里以A,B通讯为例,A,B可以是层间或者场景间。假如A要向B发送带数据的消息。那么

(1)B向小心中心注册一个bMsg的消息,告知消息中心,如果消息中心接收到bMsg,必须通知B,以便B采取相应的措施。

(2)A向消息中心发送bMsg消息。

(3)消息中心接收到bMsg,查询有谁在它这里注册了这个消息,发现是B,就通知B有人发送了bMsg。

(4)当然这个消息带有A要传递的数据,而B也不知道到底是谁给它发了bMsg这条消息,除非在传递的数据中指出。


2.相关API

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. //获得消息通知中心的一个单例对象  
  2. static CCNotificationCenter *sharedNotificationCenter(void);  
  3.   
  4. //销毁通知中心的单例对象  
  5. static void purgeNotificationCenter(void);  
  6.   
  7. //添加观察者  
  8. void addObserver(CCObject *target,   
  9.                  SEL_CallFuncO selector,  
  10.                  const char *name,  
  11.                  CCObject *obj);  
  12.   
  13. //移除观察者  
  14. void removeObserver(CCObject *target,const char *name);  
  15.   
  16. //移除所有观察者  
  17. int removeAllObservers(CCObject *target);  
  18.   
  19. //发送消息  
  20. void postNotification(const char *name);  
  21.   
  22. //发送带数据的消息  
  23. void postNotification(const char *name, CCObject *object);  

观察者的意思即是等待获取消息的对象,比如上图的B。


3.原理

CCNotificationCenter的实现比较简单,它的内部维护了一个CCArray数组,数组的元素是CCNotificationObserver类型的对象,CCNotificationObserver封装了回调的执行者,回调函数,消息名称以及传递的数据。每次注册,也就是添加观察者,其实就是把这个CCNotificationObserver对象加入通知中心的CCArray数组,而每次的消息发送就是将消息传递给通知中心,由通知中心遍历这个数组,找到一致的消息,调用这些回调函数。其实这样看起来,就像是A在调用B的函数。具体的就自己看下源码吧。


4.示例

这里做了一个场景,包含了2个层,目的是层A向层B发送带数据的消息,层B收到后打印出这条数据。

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. //ALayer  
  2. bool ALayer::init()  
  3. {  
  4.     bool bRet=false;  
  5.     do   
  6.     {  
  7.         CC_BREAK_IF(!CCLayer::init());  
  8.         CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();  
  9.         CCMenuItemImage *pCloseItem = CCMenuItemImage::create(  
  10.             "CloseNormal.png",  
  11.             "CloseSelected.png",  
  12.             this,  
  13.             menu_selector(ALayer::PostMessage));//按钮用于点击发送消息  
  14.   
  15.         pCloseItem->setAnchorPoint(ccp(0.5,0.5));  
  16.         pCloseItem->setPosition(ccp(visibleSize.width/2,visibleSize.height/2));  
  17.         CCMenu* pMenu = CCMenu::create(pCloseItem, NULL);  
  18.         pMenu->setPosition(CCPointZero);  
  19.         this->addChild(pMenu, 1);  
  20.   
  21.         bRet=true;  
  22.     } while (0);  
  23.     return bRet;  
  24. }  
  25.   
  26. void ALayer::PostMessage(CCObject* pSender)  
  27. {  
  28.     CCString* str=CCString::create("Hello BLayer!");  
  29.     CCNotificationCenter::sharedNotificationCenter()->postNotification("BMessage",str);//发送带str的消息BMessage  
  30. }  
  31.   
  32. //BLayer  
  33. bool BLayer::init()  
  34. {  
  35.     bool bRet=false;  
  36.     do   
  37.     {  
  38.         CC_BREAK_IF(!CCLayer::init());  
  39.           
  40.         CCNotificationCenter::sharedNotificationCenter()->addObserver(this,callfuncO_selector(BLayer::getMessage),"BMessage",NULL);//注册BMessage,如果接收到了,执行getMessage  
  41.   
  42.         bRet=true;  
  43.     } while (0);  
  44.     return bRet;  
  45. }  
  46.   
  47. void BLayer::getMessage(CCObject* obj)  
  48. {  
  49.     CCString* str=static_cast<CCString*>(obj);//打印出传递的数据  
  50.     CCLog(str->getCString());  
  51. }  
  52.   
  53. BLayer::~BLayer(void)  
  54. {  
  55.     CCNotificationCenter::sharedNotificationCenter()->purgeNotificationCenter();//释放通知中心单例对象  
  56. }  

5.注意

使用CCNotificationCenter需要注意以下几点:

(1)一个对象可以注册多个消息,一个消息也可以由多个消息注册。

(2)传递参数,A可以向B传递参数,而B在注册的时候也可以带一个参数,如果这两个数据不是指向同一对象的话,消息不会传递。也就是说要么A传递NULL对象,要么B注册时带NULL对象,要么都不是NULL但必须是同一对象,消息传递才会成功。以下是发送消息执行的判断:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. if (!strcmp(name,observer->getName()) && (observer->getObject() == object || observer->getObject() == NULL || object == NULL))  
(3)局部变量的传递,注意到上例,传递的是CCString的一个局部变量(但还是要autorelease),从CCNotificationCenter的实现上来看,这是没有问题的,因为数据是在postNotification被调用的,也就是整个函数体并没结束,数据不会被销毁。


6.效果图




7.源码下载

http://download.csdn.net/detail/jackyvincefu/6647453

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值