在Cocos2d-x中提供兩種觸摸事件處理機制:CCStandardTouchDelegate和CCTargetedTouchDelegate。
一、如何使用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);}
PS: CCLayer的預設registerWithTouchDispatcher實現是註冊為CCStandardTouchDelegate, 另外,在調用的時候不能自己調用registerWithTouchDispatcher,而應該調用
this->setTouchEnabled(true);
注意:我們在使用觸摸事件機制的時候進行了註冊,那麼顯然在使用後,需要進行remove的處理吧,其實這部分的內容不需要我們手動處理,移除的操作會自動在OnExit時候執行,所以不需要我們去關心!
2、實現回呼函數
在兩種實現機制中都分別指定了處理觸摸事件的回呼函數,所以使用者在註冊了不同的處理機制後,就需要實現響應的回呼函數。
(1)Standard Touch
在CCStandardTouchDelegate包含四個回呼函數,分別如下:
| CCStandardTouchDelegate 預設事件 |
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); |
處理打斷事件 |
①這些回呼函數中的參數,接收到的touch觸摸是CCSet類型,說明是多點的touch。那麼就可以實現多點觸摸的處理了。如果要想實現多點觸摸,那麼首先需要在
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
方法中設定:
//設定多點觸摸 [__glView setMultipleTouchEnabled:YES];
那麼在回呼函數中就可以進行多點觸摸的處理了:
void HelloWorld::ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent){ CCLog("tap count = %d",pTouches->count()); for (CCSetIterator iterTouch = pTouches->begin(); iterTouch != pTouches->end(); iterTouch ++) { CCTouch *pCurTouch = (CCTouch*)(*iterTouch); CCPoint point = pCurTouch->getLocation(); CCLog("%f,%f",point.x,point.y); }}
(2)Target Touch
CCTargetedTouchDelegate 包含下面四個回呼函數:
| 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 有很大的區別。
第一,CCTargetedTouchDelegate 回調裡的參數接收的不是Touch事件的集合(CCSet),而是單個的Touch事件,cocos2d-x會將多點觸摸拆散成單個的Touch事件再進行回調。即事件參數不再是集合,而是一次只傳入一個觸摸點。
第二,使用者必須實現ccTouchBegan 函數,且如果某個使用者按下訊息需要繼續跟蹤,則ccTouchBegin返回true, 否則,ccTouchMoved,ccTouchEnded等介面不會被調用到。即ccTouchBegan方法返回一個布爾值,表示聲明是否要捕捉這個觸摸點,只有在此方法中捕捉到的觸摸點才會繼續引發其他3個事件,否則此觸摸點的其他事件都會被忽略。
第三,注意到
void CCTouchDispatcher::addTargetedDelegate(CCTouchDelegate *pDelegate, int nPriority, bool bSwallowsTouches)
在addTargetedDelegate方法中,前兩個參數分別對應觸摸接收對象和優先順序,其中優先順序是一個整型參數,值越低,則優先順序越高,也就越早獲得觸摸事件。通常,為了獲得較高的優先順序,可以將其指定為負數。
其中的第三個參數較為有趣,表明了是否"吞噬"一個觸摸,如果設定為true,一個觸摸一旦被捕捉,那麼所有優先順序更低的接收對象都無法接收到觸摸。即使用者在註冊TargetTouchDelegate的時候可以設定bSwallowsTouches標識,若某個TargetTouchDelegate將該標識設為true,且需要處理某個Touch事件(ccTouchBegan
返回true),則調到該Delegate之後cocos2d-x不會將Touch訊息發送給其他的TargetTouchDelegate和StandardTouchDelegate。
例如:CCMenu就是一個會"吞噬"且優先順序為-128的觸摸接收器,由於它的優先順序很高,所以功能表按鈕總能獲得觸摸響應。
二、touch 事件分發順序
cocos2d-x 首先派發事件給CCTargetedTouchDelegate, 再派發事件給CCStandardTouchDelegate。對於相同類型的TouchDelegate, 則是根據註冊的優先順序
來確定派發先後順序。如果優先順序也一樣,則按照註冊的順序派發事件。