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時,表示對本次觸屏事件進行攔截,也就是說當觸屏事件響應了本次觸屏委托后,將不會再繼續響應其他觸碰委托。*/void?HelloWorld::onEnter()?{//注冊觸碰響應事件CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this,0,false);CCLayer::onEnter();//一定不要忘了調用父類的onEnter} //2、關閉單點觸碰事件removeDelegate
????寫在onExit()中。
// /**????????* 關閉單點觸碰TargetedDelegate* 注銷觸碰:removeDelegate("注銷觸碰事件委托的對象");*/void?HelloWorld::onExit(){//注銷觸屏響應事件CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this);CCLayer::onExit();//一定不要忘了調用父類的onExit} //3、單點觸碰響應函數
????ccTouchBegan、ccTouchMoved、ccTouchEnded、ccTouchCancelled。
????其中ccTouchBegan的返回值為bool類型:
????????當返回true時 ,表示繼續響應ccTouchMoved、ccTouchEnded事件;
????????當返回false時,則不再繼續響應這兩個事件。
//virtual?bool?ccTouchBegan(CCTouch*?touch,CCEvent*?event);????????//手指碰到屏幕時調用virtual?void?ccTouchMoved(CCTouch*?touch,CCEvent*?event);????????//手指在屏幕上滑動時調用virtual?void?ccTouchEnded(CCTouch*?touch,CCEvent*?event);????????//手指離開屏幕是調用virtual?void?ccTouchCancelled(CCTouch?*pTouch,?CCEvent?*pEvent);?//取消觸碰 //4、關于CCTouch類
????CCTouch類是用來存儲用戶觸摸屏幕的過程中,其觸摸點的相關信息。也就是保存了觸碰的整個過程中,手指所在的位置坐標。
????需要在.h中添加引用命名空間:using namespace cocos2d; 才可以使用。
????常用操作如下:
5、代碼實戰
????接下來將舉個例子:使用單點觸碰實現精靈的移動。
? ? 5.1、聲明單點觸碰響應函數
????先在HelloWorld.h中,聲明觸碰響應函數,以及類的生命周期。
////觸屏事件virtual?bool?ccTouchBegan(CCTouch*?touch,CCEvent*?event);virtual?void?ccTouchMoved(CCTouch*?touch,CCEvent*?event);virtual?void?ccTouchEnded(CCTouch*?touch,CCEvent*?event);//生命周期virtual?void?onEnter();virtual?void?onExit(); //????
????5.2、開啟、關閉單點觸碰事件
????在HelloWorld.cpp中編寫開啟和關閉觸碰事件。
????
????5.3、創建測試精靈
????在HelloWorld::init()中創建一個CCSprite精靈,用于測試觸碰。
????
????5.4、實現觸碰響應函數
????ccTouchBegan:將精靈的位置設置到觸碰開始的位置。關鍵函數:touch->getLocation()
????ccTouchMoved:對精靈的位置進行移動。 ? ? ? ? ? ?關鍵函數:touch->getDelta()
????ccTouchEnded:將精靈的位置還原到觸碰開始的位置。關鍵函數:touch->getStartLocation()
////觸屏開始ccTouchBeganbool?HelloWorld::ccTouchBegan(CCTouch*?touch,CCEvent?*?event)?{CCLOG("ccTouchBegan");//獲取CCSprite精靈CCSprite*?sp?=?(CCSprite*)this->getChildByTag(1);//設置精靈的坐標為:?當前觸點位置CCPoint?pTouch?=?touch->getLocation();sp->setPosition(?pTouch?);return?true;}//觸屏移動ccTouchMovedvoid?HelloWorld::ccTouchMoved(CCTouch*?touch,CCEvent*?event)?{CCLOG("ccTouchMoved");//獲取可視區域尺寸大小CCSize?mysize?=?CCDirector::sharedDirector()->getVisibleSize();//獲取CCSprite精靈CCSprite*?sp?=?(CCSprite*)this->getChildByTag(1);//實現精靈的觸屏移動CCPoint?pos?=?touch->getDelta();????????//獲得觸屏滑動的偏移量CCPoint?currentPos?=?sp->getPosition();?//獲得精靈的當前坐標currentPos?=?ccpAdd(currentPos,?pos);???//精靈+偏移量?后的坐標sp->setPosition(currentPos);????????????//設置觸屏移動后的坐標}//觸屏結束ccTouchEndedvoid?HelloWorld::ccTouchEnded(CCTouch*?touch,CCEvent*?event)?{CCLOG("ccTouchEnded");//獲取CCSprite精靈CCSprite*?sp?=?(CCSprite*)this->getChildByTag(1);//設置精靈的坐標為:?觸屏開始時的觸點位置CCPoint?touchStartPos?=?touch->getStartLocation();sp->setPosition(?touchStartPos?);} //????
6、運行結果
【多點觸碰】
????多點觸碰StandardDelegate,可以支持多個點的同時觸摸響應事件。
1、開啟多點觸碰
????多點觸碰的委托注冊放在onEnter的生命函數中會造成程序異常退出。
????所以注冊多點觸碰都需要重寫如下函數:registerWithTouchDispatcher。
????開啟多點觸碰,除了注冊觸碰委托外,還需要調用setTouchEnabled(true)來啟用觸碰。
// /*** 注冊多點觸碰,重寫registerWithTouchDispatcher。* addStandardDelegate("觸碰事件委托的對象","優先級")*/void?HelloWorld::registerWithTouchDispatcher(){CCDirector::sharedDirector()->getTouchDispatcher()->addStandardDelegate(this,0);}//在HelloWorld::init()中啟用多點觸碰this->setTouchEnabled(true); //2、關閉多點觸碰
????與單點觸碰的關閉類似,寫在onExit()。
3、多點觸碰響應函數
????ccTouchesBegan、ccTouchesMoved、ccTouchesEnded、ccTouchesCancelled。
????其中ccTouchesBegan和單點觸碰不同,返回值為void。
//virtual?void?ccTouchesBegan(CCSet*?touches,?CCEvent*?event);???????//觸碰開始virtual?void?ccTouchesMoved(CCSet*?touches,?CCEvent*?event);???????//觸碰移動virtual?void?ccTouchesEnded(CCSet*?touches,?CCEvent*?event);???????//觸碰結束virtual?void?ccTouchesCancelled(CCSet?*pTouches,?CCEvent?*pEvent);?//取消多點觸屏 //4、關于CCSet類
????CCSet類是一個集合類,和C++中的Set是類似的。
????在這里CCSet的數據元素類型為CCTouch,其主要存儲的是多點觸碰的觸摸點CCTouch集合。
????使用迭代器CCSetIterator進行CCSet集合中多個觸點CCTouch的遍歷。
//for?(CCSetIterator?iter?=?touches->begin()?;iter?!=?touches->end();?iter++)?{//獲取觸點后,就和單點一樣的處理了CCTouch*?touch?=?(CCTouch*)(*iter);//......} //5、代碼實戰
????在電腦中無法看到多點觸碰的效果,因為……電腦操作只有一個鼠標。
????下面就講解一個多點觸碰的例子吧,至于效果,自己將代碼移植到手機上看吧。。。
????5.1、聲明多點觸碰響應函數
????先在HelloWorld.h中,聲明多點觸碰響應函數,以及類的生命周期。
////觸屏事件virtual?void?registerWithTouchDispatcher(void);virtual?void?ccTouchesBegan(CCSet*?touches,CCEvent*?event);virtual?void?ccTouchesMoved(CCSet*?touches,CCEvent*?event);virtual?void?ccTouchesEnded(CCSet*?touches,CCEvent*?event);//生命周期virtual?void?onExit(); //????
????5.2、開啟、關閉多點觸碰事件
????在HelloWorld.cpp中編寫開啟和關閉多點觸碰事件。
////在init中開啟多點觸碰bool?HelloWorld::init(){//.....//開啟多點觸屏。注意這句話必須要寫,否則無法多點觸屏this->setTouchEnabled(true);//.....}//注冊多點觸屏void?HelloWorld::registerWithTouchDispatcher(){CCDirector::sharedDirector()->getTouchDispatcher()->addStandardDelegate(this,0);}//注銷多點觸屏void?HelloWorld::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()
////觸屏開始,返回值是voidvoid?HelloWorld::ccTouchesBegan(CCSet*?touches,CCEvent*?event){CCLOG("ccTouchesBegan");}//觸屏移動void?HelloWorld::ccTouchesMoved(CCSet*?touches,CCEvent*?event){CCLOG("ccTouchesMoved");//創建CCSet的迭代器CCSetIteratorCCSetIterator?iter?=?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()?);}else?if(?touch->getID()?==?1)?//控制精靈sp2{CCSprite*?sp2?=?(CCSprite*)this->getChildByTag(2);sp2->setPosition(?touch->getLocation()?);}}}//觸屏結束void?HelloWorld::ccTouchesEnded(CCSet*?touches,CCEvent*?event){CCLOG("ccTouchesEnded");} //????
6、運行結果
7、分析與總結
????灰的那張精靈sp2為啥不動啊啊啊!因為電腦中只有一個鼠標……所以只能觸碰一個點。
????想要看到多點觸碰的效果,就把程序移植到手機上吧。
【兩類觸碰的區別】
????(1)單點使用的監聽類是CCtargetedTouchDelegate,而多點使用CCtangardTouchDelegate。
????(2)多點觸控還需要多一個步驟,就是單獨寫個函數來注冊多點觸控:registerWithTouchDispatcher。
????(3)多點觸控要有開啟才能用。 this->setTouchEnabled(true)。
????(4)多點觸控中的ccTouchesBegan不是布爾型。
轉載于:https://blog.51cto.com/shahdza/1542261
總結
以上是生活随笔為你收集整理的cocos2dx基础篇(9)——触碰事件Touch的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: cocos2dX 之CCParticle
- 下一篇: linux下puppet的“资源”管理