转 事件分发机制

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之后菜单也不能响应。因为它也需要接受触摸事件。

原文地址:http://cn.cocos2d-x.org/tutorial/show?id=230

时间: 2024-12-27 20:30:17

转 事件分发机制的相关文章

Android事件分发机制完全解析,带你从源码的角度彻底理解(下)

记得在前面的文章中,我带大家一起从源码的角度分析了Android中View的事件分发机制,相信阅读过的 朋友对View的事件分发已经有比较深刻的理解了. 还未阅读过的朋友,请先参考 Android事件分发机 制完全解析,带你从源码的角度彻底理解(上) . 那么今天我们将继续上次未完成的话题,从源码的 角度分析ViewGruop的事件分发. 首先我们来探讨一下,什么是ViewGroup?它和普通的View有什么区 别? 顾名思义,ViewGroup就是一组View的集合,它包含很多的子View和子

认识一下Android 事件分发机制

1.引子 由于Android是采用分层布局(可以想象成PS时的图层概念一样),这样才可以在有限大小的手机屏幕上完成一些复杂的操作.当手指点击屏幕开始,这些动作在各层之间如何传递?就引出了Android的事件分发机制.之所以称为事件,是由于在Android中将所有在屏幕的动作封装成3个事件 ACTION_DOWN:手指按下 ACTION_MOVE:手指在屏幕滑动 ACTION_UP:手指从屏幕抬起 每次都是从ACTION_DOWN开始,到ACTION_UP结束,中间伴随着ACTION_MOVE:有

一篇文章彻底搞懂Android事件分发机制

本文讲的是一篇文章彻底搞懂Android事件分发机制,在android开发中会经常遇到滑动冲突(比如ScrollView或是SliddingMenu与ListView的嵌套)的问题,需要我们深入的了解android事件响应机制才能解决,事件响应机制已经是android开发者必不可少的知识.面试找工作的时候也是面试官经常会问的一个问题. 涉及到事件响应的常用方法构成 用户在手指与屏幕接触过程中通过MotionEvent对象产生一系列事件,它有四种状态: MotionEvent.ACTION_DOW

Android View 事件分发机制详解_Android

Android开发,触控无处不在.对于一些 不咋看源码的同学来说,多少对这块都会有一些疑惑.View事件的分发机制,不仅在做业务需求中会碰到这些问题,在一些面试笔试题中也常有人问,可谓是老生常谈了.我以前也看过很多人写的这方面的文章,不是说的太啰嗦就是太模糊,还有一些在细节上写的也有争议,故再次重新整理一下这块内容,十分钟让你搞明白View事件的分发机制. 说白了这些触控的事件分发机制就是弄清楚三个方法,dispatchTouchEvent(),OnInterceptTouchEvent(),o

android view事件分发机制

首先我们先写个简单的例子来测试View的事件转发的流程~ 1.案例 为了更好的研究View的事件转发,我们自定以一个MyButton继承Button,然后把跟事件传播有关的方法进行复写,然后添加上日志~ MyButton [java] view plaincopy package com.example.zhy_event03;      import android.content.Context;   import android.util.AttributeSet;   import an

Android事件分发机制

说在开头,之前项目中使用到了ListView和Button的组合,由于两者都有click事件,也意识到应该是Android的事件分发机制的原因.面试时也特意去恶补过,不过也是一知半解,此次因在项目中遇到该问题特意去详细了解一下. 引言 点击事件的分发机制由于主要发生在界面中,需要先了解Android系统的UI架构,如下图所示. 我们都知道Android程序的UI是由Activity这个组件构成的,而实际中是使用setContentView这个方法设置一个自定义布局的,这里的ContentView

android viewgroup事件分发机制

今天给大家代码ViewGroup事件分发的源码解析~~凡是自定义ViewGroup实现各种滑动效果的,不可避免的会出现很多事件的冲突,对ViewGroup事件分发机制的了解,也有益于大家了解冲突产生的原因,以及对冲突进行处理~ 1.案例 首先我们接着上一篇的代码,在代码中添加一个自定义的LinearLayout: [java] view plaincopy package com.example.zhy_event03;      import android.content.Context; 

Android View事件分发机制详解_Android

准备了一阵子,一直想写一篇事件分发的文章总结一下,这个知识点实在是太重要了. 一个应用的布局是丰富的,有TextView,ImageView,Button等,这些子View的外层还有ViewGroup,如RelativeLayout,LinearLayout.作为一个开发者,我们会思考,当点击一个按钮,Android系统是怎样确定我点的就是按钮而不是TextView的?然后还正确的响应了按钮的点击事件.内部经过了一系列什么过程呢? 先铺垫一些知识能更加清晰的理解事件分发机制: 1. 通过setC

30分钟搞清楚Android Touch事件分发机制_Android

Touch事件分发中只有两个主角:ViewGroup和View.Activity的Touch事件事实上是调用它内部的ViewGroup的Touch事件,可以直接当成ViewGroup处理. View在ViewGroup内,ViewGroup也可以在其他ViewGroup内,这时候把内部的ViewGroup当成View来分析. ViewGroup的相关事件有三个:onInterceptTouchEvent.dispatchTouchEvent.onTouchEvent.View的相关事件只有两个:

快速掌握Android开发中Touch事件分发机制

Touch事件分发中只有两个主角:ViewGroup和View.Activity的Touch事件事实上是调用它内部的ViewGroup的Touch事件,可以直接当成ViewGroup处理. View在ViewGroup内,ViewGroup也可以在其他ViewGroup内,这时候把内部的ViewGroup当成View来分析. ViewGroup的相关事件有三个:onInterceptTouchEvent.dispatchTouchEvent.onTouchEvent.View的相关事件只有两个: