Cocos2d-x 3.2 EventDispatcher事件分发机制

本文转载于Cocos2d-x v3.2学习笔记中的(九)事件分发机制(EventDispatcher)

EventDispatcher事件分发机制先创建事件,注册到事件管理中心_eventDispatcher,通过发布事件得到响应进行回调,完成事件流。

 

有五种不同的事件机制:

  • EventListenerTouch 响应触控事件

  • EventListenerKeyboard 响应键盘事件

  • EventListenerAcceleration 响应加速器事件

  • EventListenMouse 响应鼠标事件

  • EventListenerCustom 响应自定义的事件

 

优先权:

1.优先级越低,越先响应事件

2.如果优先级相同,则上层的(z轴)先接收触摸事件。

 

事件监听器的优先级:

1.addEventListenerWithSceneGraphPriority 的事件监听器优先级是0,而且在 addEventListenerWithFixedPriority 中的事件监听器的优先级不可以设置为 0,因为这个是保留给 SceneGraphPriority 使用的。

2.另外,有一点非常重要,FixedPriority listener添加完之后需要手动remove,而SceneGraphPriority listener是跟node绑定的,在node的析构函数中会被移除。移除方 法:dispatcher->removeEventListener(listener);

 

事件管理单例获取:

_eventDispatcher 是Node的属性,通过它管理当前节点(场景、层、精灵等)的所有事件的分发。但它本身是一个单例模式值的引用,在Node的构造函数中,通过 Director::getInstance()->getEventDispatcher(); 获取,有了这个属性,就能方便的处理事件。

 

触摸事件

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
void  EventDispatcherTest::funEventTouch(Sprite* sprite)
{
     this ->_eventDispatcher->removeAllEventListeners();
     
     auto listener = EventListenerTouchOneByOne::create();
     listener->onTouchBegan = CC_CALLBACK_2(EventDispatcherTest::onTouchBeganss, this );
     listener->onTouchMoved = CC_CALLBACK_2(EventDispatcherTest::onTouchMovedss, this );
     listener->onTouchEnded = CC_CALLBACK_2(EventDispatcherTest::onTouchEndedss, this );
     listener->onTouchCancelled = CC_CALLBACK_2(EventDispatcherTest::onTouchCancelledss, this );
     listener->setSwallowTouches( true ); //是否向下传递
     this ->_eventDispatcher->addEventListenerWithSceneGraphPriority(listener,sprite);
}
 
bool  EventDispatcherTest::onTouchBeganss(Touch* touch,Event* ev)
{
     auto target =  static_cast <Sprite*>(ev->getCurrentTarget());
 
     Vec2 locationInNode = target->convertToNodeSpace(touch->getLocation());
     Size s = target->getContentSize();
     Rect rect = Rect(0, 0, s.width, s.height);
   //判断触摸区域是否在目标上
     if  (rect.containsPoint(locationInNode))
     {
         label->setString( "onTouchBegan......" );
         target->setOpacity(180);
         return  true ;
     }
     return  false ;
}
void  EventDispatcherTest::onTouchMovedss(Touch* touch,Event* ev)
{
     auto target =  static_cast <Sprite*>(ev->getCurrentTarget());
     target->setPosition(target->getPosition() + touch->getDelta());
     label->setString( "onTouchMoved......" );
}
void  EventDispatcherTest::onTouchEndedss(Touch* touch,Event* ev)
{
     auto target =  static_cast <Sprite*>(ev->getCurrentTarget());
     target->setOpacity(255);
     label->setString( "onTouchEnded......" );
}
void  EventDispatcherTest::onTouchCancelledss(Touch* touch,Event* ev)
{
     label->setString( "onTouchCancelled......" );
}

键盘事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void  EventDispatcherTest::funEventKeyboard()
{
     this ->_eventDispatcher->removeAllEventListeners();
 
     auto listener = EventListenerKeyboard::create();
     listener->onKeyPressed = CC_CALLBACK_2(EventDispatcherTest::onKeyPressedss, this );
     listener->onKeyReleased = CC_CALLBACK_2(EventDispatcherTest::onKeyReleasedss, this );
     this ->_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this );
}
 
void  EventDispatcherTest::onKeyPressedss(EventKeyboard::KeyCode keycode,Event* ev)
{
     char  txt[100] = {};
     sprintf_s(txt, "key %d is Pressed!" ,( int )keycode);
     label->setString(txt);
}
 
void  EventDispatcherTest::onKeyReleasedss(EventKeyboard::KeyCode keycode,Event* ev)
{
     label->setString( "key is Released!" );
}

 

鼠标事件

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
void  EventDispatcherTest::funEventMouse(Sprite* sprite)
{
     this ->_eventDispatcher->removeAllEventListeners();
 
     auto listener = EventListenerMouse::create();
     listener->onMouseDown = CC_CALLBACK_1(EventDispatcherTest::onMouseDownss, this );
     listener->onMouseMove = CC_CALLBACK_1(EventDispatcherTest::onMouseMovess, this );
     listener->onMouseUp = CC_CALLBACK_1(EventDispatcherTest::onMouseUpss, this );
     listener->onMouseScroll = CC_CALLBACK_1(EventDispatcherTest::onMouseScrollss, this );
     this ->_eventDispatcher->addEventListenerWithSceneGraphPriority(listener,sprite);
}
 
void  EventDispatcherTest::onMouseDownss(Event* ev)
{
     label->setString( "onMouseDown!" );
}
void  EventDispatcherTest::onMouseMovess(Event* ev)
{
     label->setString( "onMouseMove!" );
}
void  EventDispatcherTest::onMouseUpss(Event* ev)
{
     label->setString( "onMouseUp!" );
}
void  EventDispatcherTest::onMouseScrollss(Event* ev)
{
     label->setString( "onMouseScroll!" );
}

 

自定义事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//自定義事件
funEventCustom();
 
//2秒後派發一次自定義事件,測試
scheduleOnce(schedule_selector(EventDispatcherTest::dispatcherCustomEvents),2.0f);
 
void  EventDispatcherTest::funEventCustom()
{
     auto listener = EventListenerCustom::create( "custom_event_1" ,CC_CALLBACK_1(EventDispatcherTest::onEventCustom, this ));
     this ->_eventDispatcher->addEventListenerWithFixedPriority(listener,1); //添加到事件分發器
}
 
void  EventDispatcherTest::dispatcherCustomEvents( float  at)
{
     //派發事件custom_event_1  事件內容為字符串custom event test!
     this ->_eventDispatcher->dispatchCustomEvent( "custom_event_1" , "custom event test!" );
}
 
void  EventDispatcherTest::onEventCustom(EventCustom* event)
{
     auto data =  static_cast < char *>(event->getUserData());
     label->setString(data);
}

 

加速器事件

除了触摸,移动设备上一个很重要的输入源是设备的方向,因此大多数设备都配备了加速计,用于测量设备静止或匀速运动时所受到的重力方向。

 

重力感应来自移动设备的加速计,通常支持X,Y和Z三个方向的加速度感应,所以又称为三向加速计。在实际应用中,可以根据3个方向的力度大小来计算手机倾斜的角度或方向。

 

加速计监听器EventListenerAcceleration,其静态create方法中有个Acceleration的参数。Acceleration是一个类,包含了加速计获得的3个方向的加速度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void  EventDispatcherTest::funEventAcceleration()
{
     //啟動硬件設備
     Device::setAccelerometerEnabled( true ); 
 
     auto listener = EventListenerAcceleration::create(CC_CALLBACK_2(EventDispatcherTest::onAcceleration, this ));
     this ->_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this );
}
 
void  EventDispatcherTest::onAcceleration(Acceleration* acc,Event* event)
{
     char  str[100]={};
     sprintf_s(str, "x:%2d,y:%2d,z:%2d,timestamp:%2d" ,acc->x,acc->y,acc->z,acc->timestamp);
     log (str);
}

 

示例代码

EventDispatcherTest.h

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
#ifndef __EventDispatcherTest__
#define __EventDispatcherTest__
 
#include "cocos2d.h"
 
USING_NS_CC;
 
class  EventDispatcherTest :  public  Layer
{
public :
     CREATE_FUNC(EventDispatcherTest);
     virtual  bool  init();
     static  Scene* createScene();
     LabelTTF* label;
     void  funEventTouch(Sprite* sprite);
     void  funEventKeyboard();
     void  funEventMouse(Sprite* sprite);
     void  funEventCustom();
     void  funEventAcceleration();
 
     bool  onTouchBeganss(Touch* touch,Event* ev);
     void  onTouchMovedss(Touch* touch,Event* ev);
     void  onTouchEndedss(Touch* touch,Event* ev);
     void  onTouchCancelledss(Touch* touch,Event* ev);
 
     void  onKeyPressedss(EventKeyboard::KeyCode keycode,Event* ev);
     void  onKeyReleasedss(EventKeyboard::KeyCode keycode,Event* ev);
 
     void  onMouseDownss(Event* ev);
     void  onMouseMovess(Event* ev);
     void  onMouseUpss(Event* ev);
     void  onMouseScrollss(Event* ev);
 
     void  dispatcherCustomEvents( float  at);
     void  onEventCustom(EventCustom* event);
 
 
     void  onAcceleration(Acceleration* acc,Event* event);
};
 
#endif
 
EventDispatcherTest.h

 

EventDispatcherTest.cpp

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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#include "EventDispatcherTest.h"
Scene* EventDispatcherTest::createScene()
{
     auto scene = Scene::create();
     auto layer = EventDispatcherTest::create();
     scene->addChild(layer);
     return  scene;
}
 
bool  EventDispatcherTest::init()
{
 
     Size visibleSize = Director::getInstance()->getVisibleSize();
     Vec2 origin = Director::getInstance()->getVisibleOrigin();
     label = LabelTTF::create( "Hello World" "Arial" , 24);
     label->setPosition(Vec2(origin.x + visibleSize.width/2,
         origin.y + visibleSize.height - label->getContentSize().height));
     this ->addChild(label, 100);
 
     auto sprite = Sprite::create( "MagentaSquare.png" ,Rect(0,0,100,100));
     sprite->setPosition(visibleSize/2);
     this ->addChild(sprite);
 
     //funEventTouch(sprite); //觸摸事件
     //funEventKeyboard();    //鍵盤事件
     //funEventMouse(sprite);//鼠標事件
     //funEventAcceleration();//加速器事件
 
     //自定義事件
      funEventCustom();
      //2秒後派發一次自定義事件,測試
      scheduleOnce(schedule_selector(EventDispatcherTest::dispatcherCustomEvents),2.0f);
     return  true ;
}
 
void  EventDispatcherTest::funEventTouch(Sprite* sprite)
{
     this ->_eventDispatcher->removeAllEventListeners();
     
     auto listener = EventListenerTouchOneByOne::create();
     listener->onTouchBegan = CC_CALLBACK_2(EventDispatcherTest::onTouchBeganss, this );
     listener->onTouchMoved = CC_CALLBACK_2(EventDispatcherTest::onTouchMovedss, this );
     listener->onTouchEnded = CC_CALLBACK_2(EventDispatcherTest::onTouchEndedss, this );
     listener->onTouchCancelled = CC_CALLBACK_2(EventDispatcherTest::onTouchCancelledss, this );
     listener->setSwallowTouches( true ); //是否向下传递
     this ->_eventDispatcher->addEventListenerWithSceneGraphPriority(listener,sprite);
}
 
bool  EventDispatcherTest::onTouchBeganss(Touch* touch,Event* ev)
{
     auto target =  static_cast <Sprite*>(ev->getCurrentTarget());
 
     Vec2 locationInNode = target->convertToNodeSpace(touch->getLocation());
     Size s = target->getContentSize();
     Rect rect = Rect(0, 0, s.width, s.height);
 
     if  (rect.containsPoint(locationInNode))
     {
         label->setString( "onTouchBegan......" );
         target->setOpacity(180);
         return  true ;
     }
     return  false ;
}
void  EventDispatcherTest::onTouchMovedss(Touch* touch,Event* ev)
{
     auto target =  static_cast <Sprite*>(ev->getCurrentTarget());
     target->setPosition(target->getPosition() + touch->getDelta());
     label->setString( "onTouchMoved......" );
}
void  EventDispatcherTest::onTouchEndedss(Touch* touch,Event* ev)
{
     auto target =  static_cast <Sprite*>(ev->getCurrentTarget());
     target->setOpacity(255);
     label->setString( "onTouchEnded......" );
}
void  EventDispatcherTest::onTouchCancelledss(Touch* touch,Event* ev)
{
     label->setString( "onTouchCancelled......" );
}
 
 
void  EventDispatcherTest::funEventKeyboard()
{
     this ->_eventDispatcher->removeAllEventListeners();
 
     auto listener = EventListenerKeyboard::create();
     listener->onKeyPressed = CC_CALLBACK_2(EventDispatcherTest::onKeyPressedss, this );
     listener->onKeyReleased = CC_CALLBACK_2(EventDispatcherTest::onKeyReleasedss, this );
     this ->_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this );
}
 
void  EventDispatcherTest::onKeyPressedss(EventKeyboard::KeyCode keycode,Event* ev)
{
     char  txt[100] = {};
     sprintf_s(txt, "key %d is Pressed!" ,( int )keycode);
     label->setString(txt);
}
 
void  EventDispatcherTest::onKeyReleasedss(EventKeyboard::KeyCode keycode,Event* ev)
{
     label->setString( "key is Released!" );
}
 
void  EventDispatcherTest::funEventMouse(Sprite* sprite)
{
     this ->_eventDispatcher->removeAllEventListeners();
 
     auto listener = EventListenerMouse::create();
     listener->onMouseDown = CC_CALLBACK_1(EventDispatcherTest::onMouseDownss, this );
     listener->onMouseMove = CC_CALLBACK_1(EventDispatcherTest::onMouseMovess, this );
     listener->onMouseUp = CC_CALLBACK_1(EventDispatcherTest::onMouseUpss, this );
     listener->onMouseScroll = CC_CALLBACK_1(EventDispatcherTest::onMouseScrollss, this );
     this ->_eventDispatcher->addEventListenerWithSceneGraphPriority(listener,sprite);
}
 
void  EventDispatcherTest::onMouseDownss(Event* ev)
{
     label->setString( "onMouseDown!" );
}
void  EventDispatcherTest::onMouseMovess(Event* ev)
{
     label->setString( "onMouseMove!" );
}
void  EventDispatcherTest::onMouseUpss(Event* ev)
{
     label->setString( "onMouseUp!" );
}
void  EventDispatcherTest::onMouseScrollss(Event* ev)
{
     label->setString( "onMouseScroll!" );
}
 
void  EventDispatcherTest::funEventCustom()
{
     auto listener = EventListenerCustom::create( "custom_event_1" ,CC_CALLBACK_1(EventDispatcherTest::onEventCustom, this ));
     this ->_eventDispatcher->addEventListenerWithFixedPriority(listener,1); //添加到事件分發器
}
 
void  EventDispatcherTest::dispatcherCustomEvents( float  at)
{
     //派發事件custom_event_1  事件內容為字符串custom event test!
     this ->_eventDispatcher->dispatchCustomEvent( "custom_event_1" , "custom event test!" );
}
 
void  EventDispatcherTest::onEventCustom(EventCustom* event)
{
     auto data =  static_cast < char *>(event->getUserData());
     label->setString(data);
}
 
void  EventDispatcherTest::funEventAcceleration()
{
     //啟動硬件設備
     Device::setAccelerometerEnabled( true ); 
 
     auto listener = EventListenerAcceleration::create(CC_CALLBACK_2(EventDispatcherTest::onAcceleration, this ));
     this ->_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this );
}
 
void  EventDispatcherTest::onAcceleration(Acceleration* acc,Event* event)
{
     char  str[100]={};
     sprintf_s(str, "x:%2d,y:%2d,z:%2d,timestamp:%2d" ,acc->x,acc->y,acc->z,acc->timestamp);
     log (str);
}
 
EventDispatcherTest.cpp

 

推荐阅读:

【官方文档】事件分发机制

转载于:https://www.cnblogs.com/dudu580231/p/4565779.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值