数。首先来看CCTouchDelegate类的继承关系,如下图所示。
CCTouchDelegate的子类中,CCStandardTouchDelegate协议是标准的获得多点触摸点的范例,
CCTargetedTouchDelegate不用处理触摸点的集合,它是返回单点的。 但是需要注意的是,CCTargetedTouchDelegate并没有屏蔽多点触摸,而是将多点离散成了单点,同时传递过来
了。可以在开始触摸的函数中返回true来实现之后获得的触摸点肯定是自己的。此外,我们常用的类是布景层类CCLayer,也就是说,在布景层类中可以重
写ccTouchesBegan等函数获得触屏的信息。
一对注册过的CCNode进行响应对应的触屏事件。
作用:当用户手指在手机屏幕上离开、抬起响应的回调函数。
参数1:CCTouch包含用户触屏点坐标。
注意:由于CCLayer默认使用了CCTouchDelegate触屏委托,所以继承CCLayer的子类无须再次使用此接口。
//重写触屏回调函数 virtual bool ccTouchBegan(cocos2d::CCTouch* touch, cocos2d::CCEvent* event); virtual void ccTouchMoved(cocos2d::CCTouch* touch, cocos2d::CCEvent* event); virtual void ccTouchEnded(cocos2d::CCTouch* touch, cocos2d::CCEvent* event); //重写生命周期函数 virtual void onEnter(); virtual void onExit();
bool HelloWorld::init() { bool bRet = false; do { CC_BREAK_IF(! CCLayer::init()); CCSprite * spr = CCSprite::create("Icon.png"); spr->setPosition(ccp(150,150)); addChild(spr,0,922); bRet = true; } while (0); return bRet; }
void HelloWorld::onEnter(){ CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this,0,false); CCLayer::onEnter(); } void HelloWorld::onExit(){ CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this); CCLayer::onExit(); } bool HelloWorld::ccTouchBegan(CCTouch* touch, CCEvent* event) { CCLOG("ccTouchBegan"); return true; } void HelloWorld::ccTouchMoved(CCTouch* touch, CCEvent* event){ CCLOG("ccTouchMoved"); } void HelloWorld::ccTouchEnded(CCTouch* touch, CCEvent* event) { CCLOG("ccTouchEnded"); //获取离开屏幕时对应的坐标 CCPoint point = touch->getLocation(); //获取到精tag=922的精灵 CCSprite* sp = (CCSprite*)this->getChildByTag(922); //暂停所有动作 sp->stopAllActions(); //执行move动作到用户离开时的位置 sp->runAction(CCMoveTo::create(1, point)); }
因为委托一般都是成对出现的,有注册就要对应有移除。如果你想对一个CCNode进行委托监听,那么创建本类时就可以进行监听了,而当本类退出时也可以对应删除其监
听。所以一般情况下,推荐大家将触屏事件的注册与移除代码都写在onEnter与onExit中。如果注册的委托不及时移除掉,就有可能造成程序的异常退出。
<2> 以上代码中,我们将精灵move逻辑写在触屏监听用户手指离开的函数ccTouchEnded中进行处理,其原因是考虑用户体验。
很多用户在手指第一次触摸屏幕时并不是有目的性的、或者说是尝试性地去触碰屏幕,那么如果系统很快响应了这些用户的错误操作逻辑,用户就会比较反感,所以一般情况
下,例如按钮等我们只在用户离开屏幕时进行响应。当然,这些细微的用户体验也会根据不同类型的游戏进行改进。
<3> 由于Cocos2D-X是基于OpenGL ES实现的,所以在CCTouch中保存用户触屏坐标,位置是3D坐标系中的坐标,所以需要将其转换成2D坐标。当然,Cocos2D-X也在
CCTouch中为开发者提供了转换坐标的函数getLocation进行2D坐标点的转换。
<4> 在上面的示例项目中,在精灵进行runAction之前,我先调用了这个精灵的stopAllActions()函数,将停止此精灵的所有动作。很多时候游戏中的精灵会有很多不同的动作需
要执行,为了防止在运行新的动作时上一个动作可能还没暂停的情况,所以这里先对所有动作进行一个停止的操作。主要原因是当精灵同时runAction两个不同的动作时,会出
现乱掉的情况。
2、示例效果图
精灵会随着屏幕的点击到达指定的位置
virtual void ccTouchesBegan(cocos2d::CCSet *pTouches, cocos2d::CCEvent *pEvent); virtual void ccTouchesMoved(cocos2d::CCSet *pTouches, cocos2d::CCEvent *pEvent); virtual void ccTouchesEnded(cocos2d::CCSet *pTouches, cocos2d::CCEvent *pEvent);
CCSetIterator iter = pTouches->begin(); for (; iter != pTouches->end(); iter++) { CCTouch* pTouch = (CCTouch*)(*iter); CCPoint location = pTouch->getLocation(); }
CCDirector::sharedDirector()->getTouchDispatcher()->addStandardDelegate(CCTouchDelegate* pDelegate,int nPriority)
virtual void registerWithTouchDispatcher(void);
//重写多触点回调函数 virtual void registerWithTouchDispatcher(void); virtual void ccTouchesBegan(cocos2d::CCSet *pTouches, cocos2d::CCEvent *pEvent); virtual void ccTouchesMoved(cocos2d::CCSet *pTouches, cocos2d::CCEvent *pEvent); virtual void ccTouchesEnded(cocos2d::CCSet *pTouches, cocos2d::CCEvent *pEvent); //生命周期函数 virtual void onExit();
bool HelloWorld::init() { bool bRet = false; do { CC_BREAK_IF(! CCLayer::init()); //开启多触点监听务必调用此函数 setTouchEnabled(true); CCSprite * sp1 = CCSprite::create("Icon.png"); sp1->setColor(ccc3(255, 255, 0));//便于区分 CCSprite * sp2 = CCSprite::create("Icon.png"); sp1->setPosition(ccp(150,100)); sp2->setPosition(ccp(150,200)); addChild(sp1,0,91); addChild(sp2,0,92); bRet = true; } while (0); return bRet; }
//注册多触点的委托监听 void HelloWorld::registerWithTouchDispatcher(void){ CCDirector::sharedDirector()->getTouchDispatcher()->addStandardDelegate(this, 0); } //用户手指第一次触碰 void HelloWorld::ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent){ CCSetIterator iter = pTouches->begin(); for (; iter != pTouches->end(); iter++) { CCTouch* pTouch = (CCTouch*)(*iter); CCPoint location = pTouch->getLocation(); if(pTouch->getID()==0){//第一个触点 CCSprite * sp1 = (CCSprite*)this->getChildByTag(91); sp1->setPosition(location); }else if(pTouch->getID()==1){//第二个触点 CCSprite * sp2= (CCSprite*)this->getChildByTag(92); sp2->setPosition(location); } } } //用户手指进行移动或者拖拽 void HelloWorld::ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent){ CCSetIterator iter = pTouches->begin(); for (; iter != pTouches->end(); iter++) { CCTouch* pTouch = (CCTouch*)(*iter); CCPoint location = pTouch->getLocation(); if(pTouch->getID()==0){//第一个触点 CCSprite * sp1 = (CCSprite*)this->getChildByTag(91); sp1->setPosition(location); }else if(pTouch->getID()==1){//第二个触点 CCSprite * sp2= (CCSprite*)this->getChildByTag(92); sp2->setPosition(location); } } } //用户手指抬起 void HelloWorld::ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent){ CCSetIterator iter = pTouches->begin(); for (; iter != pTouches->end(); iter++) { CCTouch* pTouch = (CCTouch*)(*iter); CCPoint location = pTouch->getLocation(); CCLOG("pTouch 触摸点 %i 的坐标: x:%f,y:%f",pTouch->getID(),location.x,location.y); } } //删除多触点的委托监听 void HelloWorld::onExit(){ CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this); CCLayer::onExit(); }
原文链接:http://m.blog.csdn.net/blog/yangyu20121224/10029143