cocos2d-x有個問題,即使暫停CCScene運行,觸摸仍然有效,有些菜單和按鈕仍然會被觸發。
所以有的時候我們要手動屏蔽觸摸,尤其是在彈出計費畫面的,或者使用一些本平台自帶控件的時候。
做法有幾種:
第一種方案是:每一個繼承自CCLayer的類都可以關閉觸摸,使用這個函數
- setIsTouchEnabled(false);
在暫停sence時,我們只需要關閉那些主要的CCLayer即可,也就是當前CCScene的主CCLayer和相關的CCMenu等。
但這種方法,有時候會造成莫名其妙的crash。調試發現,如果在同一個frame的同一個函數中,先關閉再恢復觸摸,就可能造成crash。crash的原因是引擎在派發觸摸事件時,發現響應對象的列表為空,直接觸發斷言。
第二種方案是:寫一個CCLayer,把所有優先級調至最高,並直接覆蓋到當前CCSence主CCLayer上。
經過試驗,這種方式非常簡單有效,重用性也很高。
- class NoTouchLayer : public cocos2d::CCLayer{
- public:
- // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
- virtual bool init();
- // implement the "static node()" method manually
- LAYER_NODE_FUNC(NoTouchLayer);
- virtualvoid registerWithTouchDispatcher();
- virtualbool ccTouchBegan (cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent);
- virtualvoid ccTouchMoved (cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent);
- virtualvoid ccTouchEnded (cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent);
- };
- bool NoTouchLayer::init(){
- if (!CCLayer::init() )
- {
- return false;
- }
- setIsTouchEnabled(true);
- return true;
- }
- void NoTouchLayer::registerWithTouchDispatcher(){
- CCTouchDispatcher::sharedDispatcher()->addTargetedDelegate(this, numeric_limits <int> ::min() , true);//使用int最小值做最高優先級,並且吞掉事件true
- CCLayer::registerWithTouchDispatcher();
- }
- bool NoTouchLayer::ccTouchBegan (CCTouch *pTouch, CCEvent *pEvent){
- return true;
- }
- void NoTouchLayer::ccTouchMoved (CCTouch *pTouch, CCEvent *pEvent){
- }
- void NoTouchLayer::ccTouchEnded (CCTouch *pTouch, CCEvent *pEvent){
- }
這個類的使用也很簡單,直接addChild,removeChild即可。注意清理,注意addChild的時候要給一個足夠大的z軸深度值。
本文出自 “老G的小屋” 博客,請務必保留此出處http://4137613.blog.51cto.com/4127613/845269