cocos2dx基础篇(9)——触碰事件Touch
【唠叨】
cocos2dx游戏引擎的重点是在于移动设备的跨平台开发,而移动设备上的游戏大部分都是通过屏幕触碰来进行的。比如主菜单的按钮触碰,打飞机中飞机的触碰移动,都需要用到触碰操作。想一想之前讲的菜单按钮CCMenu,菜单项的点击响应事件,其实就是触碰。
cocos2dx引擎中实现触碰的类CCTouchDelegate。而CCLayer类默认继承了CCTouchDelegate接口,所以CCLayer的子类无须再重新使用这些接口,这样就很方便地为我们提供了触摸操作相关的操作。
触碰事件主要分为两类:单点触碰 和 多点触碰。
本节组织结构如下:
一、单点触碰TargetedDelegate、以及参数CCTouch类。
二、多点触碰StandardDelegate、以及参数CCSet类。
三、两类触碰的区别。
【Demo下载】
https://github.com/shahdza/Cocos_LearningTest/tree/master/demo_%E8%A7%A6%E7%A2%B0%E4%BA%8B%E4%BB%B6Touch
【3.x】
请移步:http://shahdza.blog.51cto.com/2410787/1560222
【单点触碰】
单点触碰TargetedDelegate,顾名思义,就是只接受一个点的触摸响应事件。
在使用触碰之前,必须要先注册触碰委托。单点触碰的注册委托函数为addTargetedDelegate。
1、开启单点触碰事件addTargetedDelegate
写在onEnter()中。
///***开启单点触碰TargetedDelegate*注册触碰:addTargetedDelegate("触碰事件委托的对象","优先级","是否拦截触屏事件");*优先级的值越小,就越高越早被响应。*当第3个参数为true时,表示对本次触屏事件进行拦截,也就是说当触屏事件响应了本次触屏委托后,将不会再继续响应其他触碰委托。*/voidHelloWorld::onEnter(){//注册触碰响应事件CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this,0,false);CCLayer::onEnter();//一定不要忘了调用父类的onEnter}//
2、关闭单点触碰事件removeDelegate
写在onExit()中。
///***关闭单点触碰TargetedDelegate*注销触碰:removeDelegate("注销触碰事件委托的对象");*/voidHelloWorld::onExit(){//注销触屏响应事件CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this);CCLayer::onExit();//一定不要忘了调用父类的onExit}//
3、单点触碰响应函数
ccTouchBegan、ccTouchMoved、ccTouchEnded、ccTouchCancelled。
其中ccTouchBegan的返回值为bool类型:
当返回true时 ,表示继续响应ccTouchMoved、ccTouchEnded事件;
当返回false时,则不再继续响应这两个事件。
//virtualboolccTouchBegan(CCTouch*touch,CCEvent*event);//手指碰到屏幕时调用virtualvoidccTouchMoved(CCTouch*touch,CCEvent*event);//手指在屏幕上滑动时调用virtualvoidccTouchEnded(CCTouch*touch,CCEvent*event);//手指离开屏幕是调用virtualvoidccTouchCancelled(CCTouch*pTouch,CCEvent*pEvent);//取消触碰//
4、关于CCTouch类
CCTouch类是用来存储用户触摸屏幕的过程中,其触摸点的相关信息。也就是保存了触碰的整个过程中,手指所在的位置坐标。
需要在.h中添加引用命名空间:using namespace cocos2d; 才可以使用。
常用操作如下:
//classCCTouch:publicCCObject{CCPointgetLocation();//返回当前触点的坐标CCPointgetPreviousLocation();//返回前一个触点的坐标CCPointgetStartLocation();//返回开始触碰时的坐标CCPointgetDelta();//返回最近两个触点的偏移量坐标};//
5、代码实战
接下来将举个例子:使用单点触碰实现精灵的移动。
5.1、声明单点触碰响应函数
先在HelloWorld.h中,声明触碰响应函数,以及类的生命周期。
////触屏事件virtualboolccTouchBegan(CCTouch*touch,CCEvent*event);virtualvoidccTouchMoved(CCTouch*touch,CCEvent*event);virtualvoidccTouchEnded(CCTouch*touch,CCEvent*event);//生命周期virtualvoidonEnter();virtualvoidonExit();//
5.2、开启、关闭单点触碰事件
在HelloWorld.cpp中编写开启和关闭触碰事件。
////开启触屏监听voidHelloWorld::onEnter(){CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this,0,false);CCLayer::onEnter();//一定不要忘了}//关闭触屏监听voidHelloWorld::onExit(){CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this);CCLayer::onExit();//一定不要忘了}//
5.3、创建测试精灵
在HelloWorld::init()中创建一个CCSprite精灵,用于测试触碰。
////添加一个CCSprite精灵CCSprite*sp=CCSprite::create("Icon.png");sp->setPosition(midPos);this->addChild(sp,0,1);//tag标记为1//
5.4、实现触碰响应函数
ccTouchBegan:将精灵的位置设置到触碰开始的位置。关键函数:touch->getLocation()
ccTouchMoved:对精灵的位置进行移动。 关键函数:touch->getDelta()
ccTouchEnded:将精灵的位置还原到触碰开始的位置。关键函数:touch->getStartLocation()
////触屏开始ccTouchBeganboolHelloWorld::ccTouchBegan(CCTouch*touch,CCEvent*event){CCLOG("ccTouchBegan");//获取CCSprite精灵CCSprite*sp=(CCSprite*)this->getChildByTag(1);//设置精灵的坐标为:当前触点位置CCPointpTouch=touch->getLocation();sp->setPosition(pTouch);returntrue;}//触屏移动ccTouchMovedvoidHelloWorld::ccTouchMoved(CCTouch*touch,CCEvent*event){CCLOG("ccTouchMoved");//获取可视区域尺寸大小CCSizemysize=CCDirector::sharedDirector()->getVisibleSize();//获取CCSprite精灵CCSprite*sp=(CCSprite*)this->getChildByTag(1);//实现精灵的触屏移动CCPointpos=touch->getDelta();//获得触屏滑动的偏移量CCPointcurrentPos=sp->getPosition();//获得精灵的当前坐标currentPos=ccpAdd(currentPos,pos);//精灵+偏移量后的坐标sp->setPosition(currentPos);//设置触屏移动后的坐标}//触屏结束ccTouchEndedvoidHelloWorld::ccTouchEnded(CCTouch*touch,CCEvent*event){CCLOG("ccTouchEnded");//获取CCSprite精灵CCSprite*sp=(CCSprite*)this->getChildByTag(1);//设置精灵的坐标为:触屏开始时的触点位置CCPointtouchStartPos=touch->getStartLocation();sp->setPosition(touchStartPos);}//
6、运行结果
【多点触碰】
多点触碰StandardDelegate,可以支持多个点的同时触摸响应事件。
1、开启多点触碰
多点触碰的委托注册放在onEnter的生命函数中会造成程序异常退出。
所以注册多点触碰都需要重写如下函数:registerWithTouchDispatcher。
开启多点触碰,除了注册触碰委托外,还需要调用setTouchEnabled(true)来启用触碰。
///***注册多点触碰,重写registerWithTouchDispatcher。*addStandardDelegate("触碰事件委托的对象","优先级")*/voidHelloWorld::registerWithTouchDispatcher(){CCDirector::sharedDirector()->getTouchDispatcher()->addStandardDelegate(this,0);}//在HelloWorld::init()中启用多点触碰this->setTouchEnabled(true);//
2、关闭多点触碰
与单点触碰的关闭类似,写在onExit()。
//voidHelloWorld::onExit(){//关闭触碰CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this);CCLayer::onExit();//一定不要忘了}//
3、多点触碰响应函数
ccTouchesBegan、ccTouchesMoved、ccTouchesEnded、ccTouchesCancelled。
其中ccTouchesBegan和单点触碰不同,返回值为void。
//virtualvoidccTouchesBegan(CCSet*touches,CCEvent*event);//触碰开始virtualvoidccTouchesMoved(CCSet*touches,CCEvent*event);//触碰移动virtualvoidccTouchesEnded(CCSet*touches,CCEvent*event);//触碰结束virtualvoidccTouchesCancelled(CCSet*pTouches,CCEvent*pEvent);//取消多点触屏//
4、关于CCSet类
CCSet类是一个集合类,和C++中的Set是类似的。
在这里CCSet的数据元素类型为CCTouch,其主要存储的是多点触碰的触摸点CCTouch集合。
使用迭代器CCSetIterator进行CCSet集合中多个触点CCTouch的遍历。
//for(CCSetIteratoriter=touches->begin();iter!=touches->end();iter++){//获取触点后,就和单点一样的处理了CCTouch*touch=(CCTouch*)(*iter);//......}//
5、代码实战
在电脑中无法看到多点触碰的效果,因为……电脑操作只有一个鼠标。
下面就讲解一个多点触碰的例子吧,至于效果,自己将代码移植到手机上看吧。。。
5.1、声明多点触碰响应函数
先在HelloWorld.h中,声明多点触碰响应函数,以及类的生命周期。
////触屏事件virtualvoidregisterWithTouchDispatcher(void);virtualvoidccTouchesBegan(CCSet*touches,CCEvent*event);virtualvoidccTouchesMoved(CCSet*touches,CCEvent*event);virtualvoidccTouchesEnded(CCSet*touches,CCEvent*event);//生命周期virtualvoidonExit();//
5.2、开启、关闭多点触碰事件
在HelloWorld.cpp中编写开启和关闭多点触碰事件。
////在init中开启多点触碰boolHelloWorld::init(){//.....//开启多点触屏。注意这句话必须要写,否则无法多点触屏this->setTouchEnabled(true);//.....}//注册多点触屏voidHelloWorld::registerWithTouchDispatcher(){CCDirector::sharedDirector()->getTouchDispatcher()->addStandardDelegate(this,0);}//注销多点触屏voidHelloWorld::onExit(){CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this);CCLayer::onExit();//不要忘了写!}//
5.3、创建测试精灵
在HelloWorld::init()中创建两个CCSprite精灵,用于测试触碰。
////添加两个CCSprite精灵,用于多点触屏CCSprite*sp1=CCSprite::create("Icon.png");sp1->setPosition(ccp(100,160));this->addChild(sp1,0,1);CCSprite*sp2=CCSprite::create("Icon_gray.png");sp2->setPosition(ccp(200,160));this->addChild(sp2,0,2);//
5.4、实现多点触碰响应函数
ccTouchesMoved中:将精灵的位置设置到触点位置,sp1精灵设置到第0个触点位置;sp2精灵设置到第1个触点位置。
关键函数:
(1)CCTouch* touch = (CCTouch*)(*iter)
(2)touch->getID()
////触屏开始,返回值是voidvoidHelloWorld::ccTouchesBegan(CCSet*touches,CCEvent*event){CCLOG("ccTouchesBegan");}//触屏移动voidHelloWorld::ccTouchesMoved(CCSet*touches,CCEvent*event){CCLOG("ccTouchesMoved");//创建CCSet的迭代器CCSetIteratorCCSetIteratoriter=touches->begin();//遍历多点触点集合touchesfor(;iter!=touches->end();iter++){//获取触点后,就和单点一样的处理了CCTouch*touch=(CCTouch*)(*iter);if(touch->getID()==0)//控制精灵sp1{CCSprite*sp1=(CCSprite*)this->getChildByTag(1);sp1->setPosition(touch->getLocation());}elseif(touch->getID()==1)//控制精灵sp2{CCSprite*sp2=(CCSprite*)this->getChildByTag(2);sp2->setPosition(touch->getLocation());}}}//触屏结束voidHelloWorld::ccTouchesEnded(CCSet*touches,CCEvent*event){CCLOG("ccTouchesEnded");}//
6、运行结果
7、分析与总结
灰的那张精灵sp2为啥不动啊啊啊!因为电脑中只有一个鼠标……所以只能触碰一个点。
想要看到多点触碰的效果,就把程序移植到手机上吧。
【两类触碰的区别】
(1)单点使用的监听类是CCtargetedTouchDelegate,而多点使用CCtangardTouchDelegate。
(2)多点触控还需要多一个步骤,就是单独写个函数来注册多点触控:registerWithTouchDispatcher。
(3)多点触控要有开启才能用。 this->setTouchEnabled(true)。
(4)多点触控中的ccTouchesBegan不是布尔型。
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。