溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Cocos-2d CCLayer的觸摸響應(yīng)CCTouchDelegate和CCStandardTouchDelegate 和 CCTargetedTouchDelegate

發(fā)布時間:2020-07-17 20:27:52 來源:網(wǎng)絡(luò) 閱讀:743 作者:天之姣子 欄目:開發(fā)技術(shù)

Cocos2d中,CCLayer類被設(shè)計用來獲取觸摸信息,該類實現(xiàn)了兩個協(xié)議:CCStandardTouchDelegate和CCTargetedTouchDelegate,我們可以使用這兩者中的任何一個來獲取觸摸事件。

相關(guān)類

首先來了解一下相關(guān)的幾個類、處理觸屏事件時操作和執(zhí)行的流程

CCTouch:它封裝了觸摸點,可以通過locationInView函數(shù)返回一個CCPoint。

CCTouchDelegate:它是觸摸事件委托,就是系統(tǒng)捕捉到觸摸事件后交由它或者它的子類處理,所以我們在處理觸屏事件時,必須得繼承它。它封裝了下面這些處理觸屏事件的函數(shù):

CCTargetedTouchDelegate和CCStandardTouchDelegate是CCTouchDelegate的子類,類結(jié)構(gòu)圖如下:


 Cocos-2d CCLayer的觸摸響應(yīng)CCTouchDelegate和CCStandardTouchDelegate 和 CCTargetedTouchDelegate

CCStandardTouchDelegate用于處理多點觸摸;CCTargetedTouchDelegate用于處理單點觸摸。

CCTouchDispatcher:實現(xiàn)觸摸事件分發(fā),它封裝了下面這兩個函數(shù),可以把CCStandardTouchDelegate和CCTargetedTouchDelegate添加到分發(fā)列表中:

void addStandardDelegate(CCTouchDelegate *pDelegate, int nPriority);

void addTargetedDelegate(CCTouchDelegate *pDelegate, int nPriority, bool bSwallowsTouches);

CCTouchHandler:封裝了CCTouchDelegate和其對應(yīng)的優(yōu)先級,優(yōu)先級越高,分發(fā)的時候越容易獲得事件處理權(quán),CCStandardTouchHandler和CCTargetedTouchHandler是它的子類。


開啟觸摸

CCLayer默認是不捕獲觸摸事件的,要使得其能夠捕獲到相應(yīng)的觸摸實踐,我們需要將 isTouchEnabled 屬性設(shè)置成 YES:

self.isTouchEnabled = YES;

CCStandardTouchDelegate

當(dāng)設(shè)置好屬性后,就可以使用很多方法來捕獲觸摸事件。CCLayer默認使用的CCStandardTouchDelegate,該協(xié)議的方法有:

-(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
-(void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
-(void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
-(void)ccTouchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;

我們可以看到,該協(xié)議中的方法于CocoaTouch的用法類似。

方便多點觸摸的處理

觸摸信息可以直接從touches參數(shù)中獲取

NSMutableSet *mutableTouches = [touches mutableCopy];

也可使用event參數(shù)來獲取

NSSet *allTouches = [event allTouches];


CCTargetedTouchDelegate

除了CCStandardTouchDelegate,也可以使用CCTargetedTouchDelegate來捕獲觸摸。該協(xié)議定義如下:

@protocol CCTargetedTouchDelegate
-(BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event;
@optional
-(void)ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event;
-(void)ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event;
-(void)ccTouchCancelled:(UITouch *)touch withEvent:(UIEvent *)event;
@end

使用CCTargetedTouchDelegate有兩點優(yōu)點:

  1. 你不需要處理NSSets,事件的發(fā)送者已經(jīng)將NSSets分割,確保在每次調(diào)用時有且只有一個UITouch對象。單點觸摸

  2. 如果在ccTouchBegin中返回True,就可以對當(dāng)前的UITouch對象具有所有權(quán),這樣就可以在后續(xù)的move/ended/cancelled方法中確認時當(dāng)前的觸摸,這樣就可以在多點觸摸中減少工作量。

響應(yīng)觸摸的輔助方法

于通常直接在代碼中添加要響應(yīng)的方法外,還需要多一步操作。CCLayer的定義中有一個函數(shù):(以下是standard的方法)

-(void) registerWithTouchDispatcher { [[CCTouchDispatcher sharedDispatcher] addStandardDelegate:self priority:0]; }

該函數(shù)的作用就是指定需要使用哪種協(xié)議來處理觸摸事件,上述的代碼就是指定使用CCStandardTouchDelegate。為了不使用默認的協(xié)議,需要在CCLayer中重寫該函數(shù):(以下是target方法)

-(void) registerWithTouchDispatcher { [[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:INT_MIN+1 swallowsTouches:YES]; }

經(jīng)過修改后,就可以使用CCTargetedTouchDelegate來處理觸摸事件了。

target方法中,有三個參數(shù),其中第二個參數(shù)很重要,指的是優(yōu)先級,比如你有兩個Layer都設(shè)置了相應(yīng)觸摸事件,那么優(yōu)先級高的,會先響應(yīng)觸摸事件。(數(shù)值越低表示優(yōu)先級越高)

關(guān)于swallowsTouches參數(shù)

Cocos2d用CCTouchDispatcher類分發(fā)從IOS獲取的觸摸事件。它有兩種分發(fā)方式一種是CCStandardTouchDelegate,一種是CCTargetedTouchDelegate。前者將所有的Touch信息直接傳遞給實現(xiàn)該協(xié)議的對象,而后者則要求實現(xiàn)該代理的類一次只能處理一個事件,并且吃掉該事件,不再傳播(swallowTouches=YES;)。

所以CCTargetedTouchDelegate這個協(xié)議針對單點觸控,而CCStandardTouchDelegate則可以處理當(dāng)前屏幕觸摸的每個觸摸點,好像最多是十個吧。CCLayer默認情況下如果設(shè)定接受Touch事件,是使用標準協(xié)議。

我們可以看到,在注冊協(xié)議的時候分別對應(yīng)這樣的方式:


-(void) addStandardDelegate:(id<CCStandardTouchDelegate>) delegate priority:(int)priority;

-(void) addTargetedDelegate:(id<CCTargetedTouchDelegate>) delegate priority:(int)priority swallowsTouches:(BOOL)swallowsTouches;

他們的區(qū)別在swallowsTouches參數(shù),它表示是否吃掉該事件,而且只在目標協(xié)議里有意義。我們來分析各個協(xié)議的工作機理:

Standard這套協(xié)議(沒有swallowsTouches參數(shù)則,不吃掉事件),他會按照優(yōu)先級給每個層排序。然后把touch按照順序分別傳進去,也就是說從上到下的所有層 只要開啟了self.istouchenabled = YES 那么他們都會收到touch,而且不可以吃掉該事件。測試顯示即使上面一層相應(yīng)了該事件,它仍然會傳遞到下一層。

targeted這套協(xié)議只支持單點觸控,即使是多點觸控也當(dāng)單點觸控來用,但是返回的UITouch 就不知道是哪個了。他的好處是有swallow選項,即可判斷是否繼續(xù)傳遞 touch,而且,他的cctouchbegan函數(shù)是個bool值,如果你不返回一個yes的話,后面的 move 和 ended 都不會執(zhí)行,如果要使用該協(xié)議,要在layer中手動設(shè)定代理:addStandardDelegate。因為CCLayer內(nèi)部只注冊標準代理。

Standard協(xié)議無法吃掉事件,也許多個層都會相應(yīng)的時候會出問題,而研究target協(xié)議實現(xiàn)的源碼,也可以發(fā)現(xiàn)其實吃掉一個事件很簡單,只要在Touch的集合中執(zhí)行removeObject方法即可。

CCMenu繼承了CCLayer,但是它注冊的是targeted協(xié)議,所以我們很少發(fā)現(xiàn)CCMenu的混亂,因為它會將touch吃掉。


向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI