【cocos2d-x】 之 模态对话框

作者 小滕的世界原文链接 http://blog.csdn.net/teng_ontheway/article/details/8349253

需求:用cocos2d-x开发游戏时 可能需要模态对话框 拦截下层消息 

比如:购买等待模态对话框  我们点击购买按钮后不希望玩家再次点击购买 这时候我们最幸福的就是拥有一个模态对话框了

不知道咋在MAC上截图截的灰蒙蒙的...

实现原理

模态对话框 能够拦截对话框所有下层的消息

cocos2d-x 消息处理优先级【-128,128】越小优先级越高

而菜单CCMenu kCCMenuHandlerPriority优先级 为-128 

要想拦截模态对话框下层所有消息(包括菜单

我们必须将的模态对话框优先级设置小于-128 这样就可以成功的拦截按钮的消息了

但是这样也意味着当前模态对话框的菜单消息(-128)也被拦截了

我们需要手动将消息传给模态对话框上的按钮进行处理

实现过程

1.模态对话框派生自CCColorLayer 这样有个好处能处理触摸事件 还可以设置不透明度和背景颜色 比如半透明的灰色

[cpp]  view plain copy
  1. setColor(ccc3(255,0,0));  
  2. setOpacity(128);  

2.赋予当前模态对话框 一个接受触摸事件的最高优先级 意味着优先级数值要<-128 这样才能拦截包括按钮在内的所有消息

[cpp]  view plain copy
  1. // 屏蔽所有priority比自己大的消息  
  2. CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, kCCMenuHandlerPriority - 1, true);  

3.处理触摸消息 手动将消息传送给当前模态对话框的按钮 看他们是否处理

[cpp]  view plain copy
  1. bool DialogLayer::ccTouchBegan(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent)  
  2. {  
  3.     // 因为拦截了所有消息(包括按钮) 所以需要将消息手动传给模态对话框上的按钮  
  4.     if (mMenu) {  
  5.         mTouchedMenu = mMenu->ccTouchBegan(pTouch, pEvent);  
  6.     }  
  7.       
  8.     return true;  
  9. }  


简单的封装了一个类 还有待于改进 但目前已经能够满足使用了

[cpp]  view plain copy
  1. #ifndef _DIALOGLAYER_H_  
  2. #define _DIALOGLAYER_H_  
  3.   
  4. #include "cocos2d.h"  
  5.   
  6. class DialogLayer: public cocos2d::CCLayerColor  
  7. {  
  8. public:  
  9.     DialogLayer();  
  10.     virtual ~DialogLayer();  
  11.   
  12. public:  
  13.     /** 初始化对话框 */  
  14.     virtual bool onInitDialog() = 0;  
  15.   
  16.     /** 所有的菜单按钮压入到容器中 */  
  17.     void pushMenu(cocos2d::CCMenuItem *pMenu);  
  18.   
  19.     virtual bool init();  
  20.   
  21.     virtual void onEnter();  
  22.     virtual void onExit();  
  23.   
  24.     virtual bool ccTouchBegan(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent);  
  25.     virtual void ccTouchMoved(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent);  
  26.     virtual void ccTouchEnded(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent);  
  27.     virtual void ccTouchCancelled(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent);  
  28.   
  29. private:  
  30.     /** 初始化菜单 将菜单添加到模态对话框上*/  
  31.     bool initMenu();  
  32.   
  33. private:  
  34.     cocos2d::CCMenu *mMenu;             // 模态对话框菜单  
  35.     cocos2d::CCArray *mMenuItemArray;   // 所有菜单  
  36.     bool mTouchedMenu;                  // 记录菜单点击  
  37. };  

使用很简单:

1.派生一个对话框,重载实现OnInitDialog将需要的控件添加到模态对话框上

2.派生类中需要响应事件的按钮使用pushMenu添加 

3.派生类实现CREATE_FUNC(class_name)宏

[cpp]  view plain copy
  1. class ExitDlg : public DialogLayer  
  2. {  
  3. public:  
  4.     virtual bool onInitDialog();  
  5.   
  6.     CREATE_FUNC(ExitDlg);  
  7.   
  8. public:  
  9.     /** 确认和退出按钮 */  
  10.     void okMenuItemCallback(CCObject *obj);  
  11.     void cancelMenuItemCallback(CCObject *obj);  
  12. };  
  13.   
  14. bool ExitDlg::onInitDialog()  
  15. {  
  16.     CCSize winSize = CCDirector::sharedDirector()->getWinSize();  
  17.   
  18.     CCLabelTTF *label = CCLabelTTF::create("Are you sure exit?""", 64);  
  19.     label->setPosition(ccp(winSize.width / 2, winSize.height / 2 + 50));  
  20.     this->addChild(label);  
  21.   
  22.     CCMenuItemFont *okMenuItem = CCMenuItemFont::create("OK"this, menu_selector(ExitDlg::okMenuItemCallback));  
  23.     okMenuItem->setPosition(ccp(winSize.width / 2 - 100, winSize.height / 2 - 50));  
  24.   
  25.     CCMenuItemFont *cancelMenuItem = CCMenuItemFont::create("Cancel"this, menu_selector(ExitDlg::cancelMenuItemCallback));  
  26.     cancelMenuItem->setPosition(ccp(winSize.width / 2 + 100, winSize.height / 2 - 50));  
  27.   
  28.     pushMenu(okMenuItem);  
  29.     pushMenu(cancelMenuItem);  
  30.   
  31.     setColor(ccc3(255,0,0));  
  32.     setOpacity(128);  
  33.     return true;  
  34. }  
  35.   
  36. void ExitDlg::okMenuItemCallback(CCObject *obj)  
  37. {  
  38.     CCDirector::sharedDirector()->end();  
  39. }  
  40.   
  41. void ExitDlg::cancelMenuItemCallback(CCObject *obj)  
  42. {  
  43.     removeFromParentAndCleanup(true);  
  44. }  


使用也相当easy

[cpp]  view plain copy
  1. void HelloWorld::menuCloseCallback(CCObject* pSender)  
  2. {  
  3.     ExitDlg* dlg = ExitDlg::create();  
  4.     addChild(dlg);  
  5. }  


剩下的就是不断的重复重复再重复的利用了 哈哈

代码如下:查看代码


原理文章可以参考oneRain 的 文章 感谢作者的亲情奉献 哈哈

http://blog.csdn.net/onerain88/article/details/7608496# 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值