cocos2d-x如何快速屏蔽触摸
2013-09-04 10:44
211 查看
转自:http://4137613.blog.51cto.com/4127613/845269
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轴深度值。
PS:
1.addTargetedDelegate默认的优先级是-128,值越小优先级越高,而menu的优先级是-128。
2.触摸的优先级和addChild的zOrder没有关系!!!只和addTargetedDelegate的优先级有关系。
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轴深度值。
PS:
1.addTargetedDelegate默认的优先级是-128,值越小优先级越高,而menu的优先级是-128。
2.触摸的优先级和addChild的zOrder没有关系!!!只和addTargetedDelegate的优先级有关系。
相关文章推荐
- cocos2d-x:如何快速屏蔽触摸
- cocos2d-x:如何快速屏蔽触摸
- cocos2d-x如何快速屏蔽触摸
- cocos2d-x学习笔记番外篇05:如何快速屏蔽触摸
- cocos2d-x学习笔记番外篇05:如何快速屏蔽触摸 推荐
- 如何快速屏蔽触摸
- cocos2d-x3.x屏蔽下层触摸(制作透明图层暂停界面)
- cocos2d JS touch(触摸监听)-快速添加事件监听器到管理器
- cocos2d-x3.x屏蔽下层触摸(制作透明图层暂停界面)
- Cocos2d 2.x~3.x触摸事件与屏蔽
- 简单说明cocos2d的触摸事件中如何确定选中对象
- 如何快速学习cocos2d-x?
- cocos2d-x3.x屏蔽触摸遮罩层屏蔽按钮
- cocos2d-x3.x屏蔽下层触摸(制作透明图层暂停界面)
- 如何快速搭建Cocos2d-JS游戏开发环境
- cocos2d-x 3.2 |如何在Layer中实现用户触摸
- 触摸事件的重新分发(当弹出一个新窗口时,如何屏蔽掉下面层的触摸事件)
- cocos2d-x3.x屏蔽下层触摸(制作透明图层暂停界面)
- Cocos2d-x v3.12 做一个layer触摸屏蔽层
- cocos2d-x3.x屏蔽下层触摸(制作透明图层暂停界面)