2016年4月12日 星期二

20160408_cocos2dx[3.2] 新事件分發機制上

https://www.google.com.tw/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#safe=off&q=cocos2d-x+%E8%87%AA%E8%A8%82+%E4%BA%8B%E4%BB%B6

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 來進行統一的管理。
    事件監聽器主要有:
    > 觸摸事件     EventListenerTouchOneByOneEventListenerTouchAllAtOnce
    > 鼠標響應事件 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"); }
//


沒有留言:

張貼留言

cocos2dx-lua 建立滑鼠監聽

重要關鍵字  EVENT_MOUSE_SCROLL addEventListenerWithSceneGraphPriority      if IsPc() then --建立滑鼠監聽         local listener = cc.EventListenerMouse...