1. 程式人生 > >cocos2dx之觸控事件

cocos2dx之觸控事件

兩種Cocos2d-x觸控事件:
1,我們已經見到了CCLayer處理觸控事件的方法。當我們開啟CCLayer的TouchEnable屬性後,層中的4個回撥函式就會在接收到事件時被觸發,我們把這類事件稱作標準觸控(standard touch)事件,它的特點是任何層都會平等地接收全部觸控事件。
2,除此以外,Cocos2d-x還提供了另一種被稱作帶目標的觸控事件(targeted touch)機制。在帶目標的觸控機制中,接收者並不平等,較早處理事件的接收者有權停止事件的分發,使它不再繼續傳遞給其他接收者。換句話說,帶目標的觸控事件並不一定會被廣播給所有的接收者。通常,遊戲的選單按鈕、搖桿按鈕等元件常使用目標觸控事件,以保證觸控事件不對其他層產生不良影響。


標準觸控事件:
我們知道利用CCLayer可以方便地啟用層上的標準觸控事件。實際上,並不是只有層才支援接收觸控事件,任何一個遊戲元素都可以接受事件,只不過層中提供了現成的支援。下面我們將以層為例,來探究一下層是如何開啟標準觸控事件的。
如果設定開啟觸控,則會呼叫registerWithTouchDispatcher方法。而在registerWithTouchDispatcher方法中,我們呼叫了CCTouchDispatcher的addStandard- Delegate方法。在引擎中,CCTouchDispatcher負責觸控事件的分發處理,此處的addStan- dardDelegate方法會把當前物件註冊到分發器中。被註冊的物件必須實現CCStandardTouch- Delegate介面,當引擎從系統接收到觸控事件時,就會呼叫介面中對應的方法,觸發觸控事件。
相比之下,關閉觸控則簡單得多:只需要呼叫CCTouchDispatcher的removeDelegate方法即可。
因此可以總結,為了使一個物件接受標準觸控事件,主要有以下4個步驟。
1,需要此物件實現CCStandardTouchDelegate介面。
2,使用addStandardDelegate方法把自己註冊給觸控事件分發器。
3,過載事件回撥函式,處理觸控事件;
4,當不再需要接收觸控事件時,使用removeDelegate方法來登出觸控事件的接收。

注: 必須多點同時觸控看能不能出發,單點你是沒辦法出發的,在模擬器上就別想觸發了。



帶目標的觸控事件:
我們可以為任意物件新增標準觸控事件,然而如同前文所述,標準觸控事件中存在兩個較為不便的地方,具體如下所示:
1,只要事件分發器接收到使用者的觸控事件,就會分發給所有的訂閱者,因此常常會出現按下按鈕時,觸控事件穿透按鈕分發給後面的層這種尷尬的情況。
2,當系統存在多個觸控點時,標準觸控事件會把所有觸控點都傳遞給回撥函式,然而在許多情況下每個觸控點之間是獨立的,螢幕上是否存在其他觸控點我們並不不關心,因此我們不必為了處理多個觸控事件手動遍歷一遍觸控點。
3,為此,Cocos2d-x為我們提供了一個簡化的解決方案:帶目標的觸控事件。與標準觸控事件類似,我們也需要首先使接受事件的物件實現一個介面CCTargetedTouchDelegate,然後把物件註冊到觸控分發器中,最後當不再需要接受觸控事件時登出自身。




觸控中的陷阱
觸控處理機制的規則並不複雜,但是存在一些容易讓人產生誤解的陷阱。
第一個陷阱是接收觸控的物件並不一定正顯示在螢幕上。觸控分發器和引擎中的繪圖是相互獨立的,所以並不關心觸控代理是否處於螢幕上。因此,在實際使用中,應該在不需要的時候及時從分發器中移除觸控代理,尤其是自定義的觸控物件。而CCLayer也僅僅會在切換場景時將自己從分發器中移除,所以同場景內手動切換CCLayer的時候,也需要注意禁用觸控來從分發器移除自己。
另一個陷阱出自CCTargetedTouchDelegate。儘管每次只傳入一個觸控點,也只有在開始階段被宣告過的觸控點後續才會傳入,但是這並不意味著只會接收一個觸控點:只要被宣告過的觸控點都會傳入,而且可能是亂序的。因此,一個良好的習慣是,如果使用CCTargeted- TouchDelegate,那麼只宣告一個觸控,針對一個觸控作處理即可。