最近在学习cocos2dx,从网上下载了一个叫赵云要格斗的源代码,去在编译的时候getTouchDispatcher() 方法找不到,于是就去找度娘,值此之际正好学习下Cocos2d-x-3.0触屏事件的触屏事件
解决上面的问题:getTouchDispatcher()是在2.0时代的方法,在3.0以后就废弃了
2.0时代:
默认情况下CCLayer都是没有启动触摸事件的,所以需要在初始化函数中 this->setTouchEnabled(true); 启用触摸事件处理。
1、首先需要在 registerWithTouchDispatcher() 方法中注册处理触摸事件的机制。
void HelloWorld::registerWithTouchDispatcher()
{
//Standard Touch
CCDirector::sharedDirector()->getTouchDispatcher()->addStandardDelegate(this, 0);
//Targeted Touch
// CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 0, true);
}
默认CCLayer的默认registerWithTouchDispatcher实现是注册为CCStandardTouchDelegate, 另外,在调用的时候不能自己调用registerWithTouchDispatcher,而应该调用this->setTouchEnabled(true)
2、实现回调函数
(1)Standard Touch
virtual void ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent); 处理按下事件
virtual void ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent); 处理按下并移动事件
virtual void ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent); 处理松开事件
virtual void ccTouchesCancelled(CCSet *pTouches, CCEvent *pEvent); 处理打断事件
(2)Target Touch
CCTargetedTouchDelegate 包含下面四个回调函数:
virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent); 处理用户按下事件,true表示继续处理, 否则false.
virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent); 处理按下并移动事件
virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent); 处理松开事件
virtual void ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent); 处理打断事件
CCTargetedTouchDelegate 和 CCStandardTouchDelegate 有很大的区别。
3.0时代:
思路是把摇杆封装成一个类,然后照看继承CCLayer,就可以响应触摸事件了
源代码:
void HRocker::startRocker(bool _isStopOther)
{
CCSprite *rocker = (CCSprite*)this->getChildByTag(tag_rocker);
rocker->setVisible(true);
CCSprite *rockerBG = (CCSprite *)this->getChildByTag(tag_rockerBG);
rockerBG->setVisible(true);
CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this,-1,_isStopOther);
}
2.0时代代码,编译不过去
改过后的代码:
void HRocker::startRocker(bool _isStopOther)
{
CCSprite *rocker = (CCSprite*)this->getChildByTag(tag_rocker);
rocker->setVisible(true);
CCSprite *rockerBG = (CCSprite *)this->getChildByTag(tag_rockerBG);
rockerBG->setVisible(true);
auto listener1 = EventListenerTouchOneByOne::create();
listener1->onTouchBegan = CC_CALLBACK_2(HRocker::onTouchBegan,this);
listener1->onTouchMoved = CC_CALLBACK_2(HRocker::onTouchMoved,this);
listener1->onTouchEnded = CC_CALLBACK_2(HRocker::onTouchEnded,this);
listener1->setSwallowTouches(true);
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener1,this);
}
以上是3.0的单点触摸的实现
注意点:
1.单点触摸:(即只有注册的Layer才能接收触摸事件)
2.onTouchBegan:如果返回true:本层的后续Touch事件可以被触发,并阻挡向后层传递
如果返回false,本层的后续Touch事件不能被触发,并向后传递
简单点来说,如果
(1)Layer 只有一层的情况:
virtual bool onTouchBegan(CCTouch *pTouch, CCEvent *pEvent); a.返回false,则ccTouchMoved(),ccTouchEnded()不会再接收到消息 b.返回true,则ccTouchMoved(),ccTouchEnded()可以接收到消息
(2)Layer 有多层的情况: virtual bool onTouchBegan(CCTouch *pTouch, CCEvent *pEvent); a.返回false,则本层的onTouchMoved(),onTouchEnded()不会再接收到消息,但是本层之下的其它层会接收到消息 b.返回true,则本层的onTouchMoved(),onTouchEnded()可以接收到消息,但是本层之下的其它层不能再接收到消息
3.listener->setSwallowTouches(true),不向下触摸,简单点来说,比如有两个sprite ,A 和 B,A在上B在下(位置重叠),触摸A的时候,B不会受到影响。listener->setSwallowTouches(false)反之,向下传递触摸,触摸A也等于触摸了B