ocos2dx[3.2](12) 新事件分發機制 2014-10-01 02:04:07
原創作品,允許轉載,轉載時請務必以超鏈接形式標明文章 原始出處 、作者信息和本聲明。否則將追究法律責任。http://shahdza.blog.51cto.com/2410787/1560222
【嘮叨】
在2.x中處理事件需要用到委託代理(delegate),相信學過2.x的觸摸事件的同學,都知道創建和移除的流程十分繁瑣。
而在3.x中由於加入了C++11的特性,而對事件的分發機制通過事件分發器EventDispatcher 來進行統一的管理。
事件監聽器主要有:
> 觸摸事件 : EventListenerTouchOneByOne、EventListenerTouchAllAtOnce
> 鼠標響應事件 : EventListenerMouse
> 鍵盤響應事件 : EventListenerKeyboard
> 加速計事件 : EventListenerAcceleration
> 自定義事件 : EventListenerCustom
> 物理碰撞事件 : EventListenerPhysicsContact
> 遊戲手柄事件 : EventListenerController
【致謝】
【事件分發器】
事件分發器EventDispatcher,用於統一管理事件監聽器的所有事件的分發。
1、_eventDispatcher
_eventDispatcher是Node的屬性,通過Director::getInstance()->getEventDispatcher() 獲得。
_eventDispatcher的工作由三部分組成:
(1)事件分發器 :EventDispatcher。
(2)事件類型 :EventTouch, EventKeyboard 等。
(3)事件監聽器 :EventListenerTouch, EventListenerKeyboard 等。
監聽器實現了各種觸發後的邏輯,在適當時候由事件分發器分發事件類型,然後調用相應類型的監聽器。
2、添加/刪除監聽器
添加監聽器:addEventListenerWithSceneGraphPriority ,
addEventListenerWithFixedPriority 。
刪除監聽器:removeEventListener ,
removeAllEventListeners 。
3、主要函數
包含監聽器的添加、刪除、暫停、恢復,優先級的設置,手動分發事件等。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
| // class EventDispatcher : public Ref { /** * 添加監聽器 * - addEventListenerWithSceneGraphPriority * - addEventListenerWithFixedPriority * - addCustomEventListener */ //使用 場景圖的優先級 為指定事件添加一個監聽. //listener : 指定要監聽的事件. //node : 這個節點的繪製順序是基於監聽優先級. //優先級 : 0 void addEventListenerWithSceneGraphPriority(EventListener* listener, Node* node); //使用 一定的優先級 為指定事件添加一個監聽. //listener : 指定要監聽的事件. //fixedPriority : 這個監聽器的固定優先級. //優先級 : fixedPriority。(但是不能為0,因為他是場景圖的基本優先級) void addEventListenerWithFixedPriority(EventListener* listener, int fixedPriority); //用戶自定義監聽器 EventListenerCustom* addCustomEventListener( const std::string &eventName, const std::function< void (EventCustom*)>& callback); /** * 刪除監聽器 * - removeEventListener * - removeEventListenersForType * - removeEventListenersForTarget * - removeCustomEventListeners * - removeAllEventListeners */ //刪除指定監聽器 void removeEventListener(EventListener* listener); //刪除某類型對應的所有監聽器 //EventListener::Type:: // 單點觸摸 : TOUCH_ONE_BY_ONE // 多點觸摸 : TOUCH_ALL_AT_ONCE // 鍵盤 : KEYBOARD // 鼠標 : MOUSE // 加速計 : ACCELERATION // 自定義 : CUSTOM void removeEventListenersForType(EventListener::Type listenerType); //刪除綁定在節點target上的所有監聽器 void removeEventListenersForTarget(Node* target, bool recursive = false ); //刪除名字為customEventName的所有自定義監聽器 void removeCustomEventListeners( const std::string& customEventName); //移除所有監聽器 void removeAllEventListeners(); /** * 暫停、恢復在節點target上的所有監聽器 * - pauseEventListenersForTarget * - resumeEventListenersForTarget */ void pauseEventListenersForTarget(Node* target, bool recursive = false ); void resumeEventListenersForTarget(Node* target, bool recursive = false ); /** * 其他 * - setPriority * - setEnabled * - dispatchEvent * - dispatchCustomEvent */ //設置某監聽器的優先級 void setPriority(EventListener* listener, int fixedPriority); //啟用事件分發器 void setEnabled( bool isEnabled); bool isEnabled() const ; //手動派發自定義事件 void dispatchEvent(Event* event); //給名字為eventName的自定義監聽器, 綁定用戶數據 void dispatchCustomEvent( const std::string &eventName, void *optionalUserData = nullptr); } // |
4、關於事件監聽器的優先權
通過 addEventListenerWithSceneGraphPriority 添加的監聽器,優先權為0。
通過 addEventListenerWithFixedPriority 添加的監聽器,可以自定義優先權,但不能為0。
> 優先級越低,越先響應事件。
> 如果優先級相同,則上層的(z軸)先接收觸摸事件。
5、使用步驟
(1)獲取事件分發器 :dispatcher = Director::getInstance()->getEventDispatcher();
(2)創建監聽器 :auto listener = EventListenerTouchOneByOne::create();
(3)綁定響應事件函數:listener->onTouchBegan = CC_CALLBACK_2(callback, this);
(4)將監聽器添加到事件分發器dispatcher中:
dispatcher->addEventListenerWithSceneGraphPriority(Listener, this);
(5)編寫回調響應函數:
bool callback(Touch* touch, Event* event) { ... }
【觸摸事件】
1、單點觸摸:EventListenerTouchOneByOne
單點觸摸監聽器相關:
1
2
3
4
5
6
7
8
| // static EventListenerTouchOneByOne* create(); std::function< bool (Touch*, Event*)> onTouchBegan; //只有這個返回值為 bool std::function< void (Touch*, Event*)> onTouchMoved; std::function< void (Touch*, Event*)> onTouchEnded; std::function< void (Touch*, Event*)> onTouchCancelled; // |
使用舉例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| // //獲取事件分發器 auto dispatcher = Director::getInstance()->getEventDispatcher(); //創建單點觸摸監聽器 EventListenerTouchOneByOne auto touchListener = EventListenerTouchOneByOne::create(); //單點觸摸響應事件綁定 touchListener->onTouchBegan = CC_CALLBACK_2(HelloWorld::onTouchBegan, this ); touchListener->onTouchMoved = CC_CALLBACK_2(HelloWorld::onTouchMoved, this ); touchListener->onTouchEnded = CC_CALLBACK_2(HelloWorld::onTouchEnded, this ); touchListener->onTouchCancelled = CC_CALLBACK_2(HelloWorld::onTouchCancelled, this ); //在事件分發器中,添加觸摸監聽器,事件響應委託給 this 處理 dispatcher->addEventListenerWithSceneGraphPriority(touchListener, this ); //單點觸摸事件響應函數 bool onTouchBegan(Touch *touch, Event *unused_event) { CCLOG( "began" ); return true ; } void onTouchMoved(Touch *touch, Event *unused_event) { CCLOG( "moved" ); } void onTouchEnded(Touch *touch, Event *unused_event) { CCLOG( "ended" ); } void onTouchCancelled(Touch *touch, Event *unused_event) { CCLOG( "cancelled" ); } // |
2、多點觸摸:EventListenerTouchAllAtOnce
多點觸摸監聽器相關:
1
2
3
4
5
6
7
8
| // static EventListenerTouchAllAtOnce* create(); std::function< void ( const std::vector<Touch*>&, Event*)> onTouchesBegan; std::function< void ( const std::vector<Touch*>&, Event*)> onTouchesMoved; std::function< void ( const std::vector<Touch*>&, Event*)> onTouchesEnded; std::function< void ( const std::vector<Touch*>&, Event*)> onTouchesCancelled; // |
使用舉例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| // //獲取事件分發器 auto dispatcher = Director::getInstance()->getEventDispatcher(); //創建多點觸摸監聽器 EventListenerTouchAllAtOnce auto touchesListener = EventListenerTouchAllAtOnce::create(); //多點觸摸響應事件綁定 touchesListener->onTouchesBegan = CC_CALLBACK_2(HelloWorld::onTouchesBegan, this ); touchesListener->onTouchesMoved = CC_CALLBACK_2(HelloWorld::onTouchesMoved, this ); touchesListener->onTouchesEnded = CC_CALLBACK_2(HelloWorld::onTouchesEnded, this ); touchesListener->onTouchesCancelled = CC_CALLBACK_2(HelloWorld::onTouchesCancelled, this ); //在事件分發器中,添加觸摸監聽器,事件響應委託給 this 處理 dispatcher->addEventListenerWithSceneGraphPriority(touchesListener, this ); //多點觸摸事件響應函數 void onTouchesBegan( const std::vector<Touch*>& touches, Event *unused_event) { CCLOG( "began" ); } void onTouchesMoved( const std::vector<Touch*>& touches, Event *unused_event) { CCLOG( "moved" ); } void onTouchesEnded( const std::vector<Touch*>& touches, Event *unused_event) { CCLOG( "ended" ); } void onTouchesCancelled( const std::vector<Touch*>&touches, Event *unused_event) { CCLOG( "cancelled" ); } // |
沒有留言:
張貼留言