转 事件分发机制

简介:

1. 介绍

(1)在使用时,首先创建一个事件监听器,事件监听器包含以下几种:

触摸事件(EventListenerTouch)

键盘响应事件(EventListenerKeyboard)

加速记录事件(EventListenerAcceleration)

鼠标相应事件(EventListenerMouse)

自定义事件(EventListenerCustom)


(2)以上事件监听器统一由_eventDispatcher来进行管理。它的工作需要三部分组成:

事件分发器 EventDispatcher

事件类型 EventTouch, EventKeyboard 等

事件监听器 EventListenerTouch, EventListenerKeyboard 等


(3)监听器实现了各种触发后的逻辑,在适当时候由事件分发器分发事件类型,然后调用相应类型的监听器。


2. 其他事件派发处理模块

上一篇我们介绍了触摸事件派发处理模块,这篇我们将介绍其他事件派发处理模块,这些模块都使用了相同的处理方式。


(1)键盘响应事件

除了键盘,还可以是终端设备的各个菜单,他们使用同一个监听器来进行处理。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 初始化并绑定
auto listener = EventListenerKeyboard::create();
listener->onKeyPressed = CC_CALLBACK_2(KeyboardTest::onKeyPressed,      this      );
listener->onKeyReleased = CC_CALLBACK_2(KeyboardTest::onKeyReleased,      this      );
 
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener,      this      );
 
// 键位响应函数原型
void      KeyboardTest::onKeyPressed(EventKeyboard::KeyCode keyCode, Event* event)
{
          log      (      "Key with keycode %d pressed"      , keyCode);
}
 
void      KeyboardTest::onKeyReleased(EventKeyboard::KeyCode keyCode, Event* event)
{
          log      (      "Key with keycode %d released"      , keyCode);
}


(2)加速计事件

在使用加速计事件监听器之前,需要先启用此硬件设备:


1
Device::setAccelerometerEnabled(      true      );


然后创建相应的监听器,在创建回调函数时,可以使用lambda表达式创建匿名函数,也可以绑定已有的函数逻辑实现,如下:



1
2
3
4
5
6
7
8
auto listener = EventListenerAcceleration::create(CC_CALLBACK_2(AccelerometerTest::onAcceleration,     this      ));
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener,      this      );
 
// 加速计回调函数原型实现
void      AccelerometerTest::onAcceleration(Acceleration* acc, Event* event)
{
          // 这里处理逻辑
}


(3)鼠标相应事件

在3.0中多了鼠标捕获事件派发,这可以在不同的平台上,丰富我们游戏的用户体验。


1
2
3
4
5
6
7
_mouseListener = EventListenerMouse::create();
_mouseListener->onMouseMove = CC_CALLBACK_1(MouseTest::onMouseMove,      this      );
_mouseListener->onMouseUp = CC_CALLBACK_1(MouseTest::onMouseUp,      this      );
_mouseListener->onMouseDown = CC_CALLBACK_1(MouseTest::onMouseDown,      this      );
_mouseListener->onMouseScroll = CC_CALLBACK_1(MouseTest::onMouseScroll,      this      );
 
_eventDispatcher->addEventListenerWithSceneGraphPriority(_mouseListener,      this      );


使用如上方法,创建一个鼠标监听器。然后分别实现各种回调函数,并且绑定。



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
void      MouseTest::onMouseDown(Event *event)
{
          EventMouse* e = (EventMouse*)event;
          string str =      "Mouse Down detected, Key: "      ;
          str += tostr(e->getMouseButton());
          // ...
}
 
void      MouseTest::onMouseUp(Event *event)
{
          EventMouse* e = (EventMouse*)event;
          string str =      "Mouse Up detected, Key: "      ;
          str += tostr(e->getMouseButton());
          // ...
}
 
void      MouseTest::onMouseMove(Event *event)
{
          EventMouse* e = (EventMouse*)event;
          string str =      "MousePosition X:"      ;
          str = str + tostr(e->getCursorX()) +      " Y:"      + tostr(e->getCursorY());
          // ...
}
 
void      MouseTest::onMouseScroll(Event *event)
{
          EventMouse* e = (EventMouse*)event;
          string str =      "Mouse Scroll detected, X: "      ;
          str = str + tostr(e->getScrollX()) +      " Y: "      + tostr(e->getScrollY());
          // ...
}


(4)自定义事件

以上是系统自带的事件类型,事件由系统内部自动触发,如触摸屏幕,键盘响应等,除此之外,还提供了一种自定义事件,简而言之,它不是由系统自动触发,而是人为的干涉,如下:


1
2
3
4
5
6
7
8
9
_listener = EventListenerCustom::create(      "game_custom_event1"      , [=](EventCustom* event){
          std::string str(      "Custom event 1 received, "      );
          char      * buf =      static_cast      <      char      *>(event->getUserData());
          str += buf;
          str +=      " times"      ;
          statusLabel->setString(str.c_str());
});
 
_eventDispatcher->addEventListenerWithFixedPriority(_listener, 1);


以上定义了一个“自定义事件监听器”,实现了一些逻辑,并且添加到事件分发器。那么以上逻辑是在什么情况下响应的呢?请看:



1
2
3
4
5
6
7
8
static      int      count = 0;
++count;
char      * buf =      new      char      [10];
sprintf      (buf,      "%d"      , count);
EventCustom event(      "game_custom_event1"      );
event.setUserData(buf);
_eventDispatcher->dispatchEvent(&event);
CC_SAFE_DELETE_ARRAY(buf);


定义了一个EventCustom,并且设置了其UserData数据,手动的通过_eventDispatcher->dispatcherEvent(&event);将此事件分发出去,从而触发之前所实现的逻辑。



(5)移除事件监听器

移除一个已经被添加了的监听器:


1
_eventDispatcher->removeEventListener(listener);


移除当前事件分发器中所有监听器:



1
_eventDispatcher->removeAllEventListeners();


当使用removeAll的时候,此节点的所有的监听将被移除,推荐使用指定删除的方式。


注意:removeAll之后菜单也不能响应。因为它也需要接受触摸事件。

目录
相关文章
|
Android开发
【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 四 | View 事件传递机制 )(一)
【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 四 | View 事件传递机制 )(一)
136 0
|
Android开发
【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 四 | View 事件传递机制 )(二)
【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 四 | View 事件传递机制 )(二)
118 0
|
Android开发
【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 六 )(二)
【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 六 )(二)
108 0
|
Java Android开发
【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 七 )(五)
【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 七 )(五)
97 0
|
Java Android开发
【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 七 )(二)
【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 七 )(二)
140 0
|
Android开发 容器
【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 七 )(一)
【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 七 )(一)
125 0
|
Android开发
【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 五 )(三)
【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 五 )(三)
84 0
|
Java Android开发 容器
【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 五 )(四)
【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 五 )(四)
101 0
|
Java Android开发
【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 三 )(二)
【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 三 )(二)
91 0
|
Android开发
【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 七 )(三)
【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 七 )(三)
124 0