[cocos2d-x]深入--几个代表性的类 (续)
摘要: 此文对cocos2d-x
引擎中最具代表性,最能体现框架结构的几个类做了简单的介绍, 包括Director
,Application
, Renderer
, EventDispatcher
, Scheduler
. 对于这些类, 也只对关系主要流程的方法做了介绍, 略过了容错代码和其它细节. 主要目的是让大家快速的对cocos2d-x
引擎有一个全面笼统的认识, 也方便快速定位问题.
- 博客: http://www.cnblogs.com/jhzhu
- 邮箱: jhzhuustc@gmail.com
- 作者: 知明所以
- 时间: 2014-07-22
EventDispatcher
EventDispatcher,EventListener,Event之间的关系
EventDispatcher
: 事件分发器, 相当于所有事件的中控中心. 管理着EventListener
,当一个Event
到来的时候决定CallBack
的调用顺序。Event
(EventTouch
,EventKeyboard
等), 具体的事件数据,EventListener
(EventListenerTouch
,EventListenerKeyboard
等 ): 建立了Event
到CallBack
的映射关系,EventDispatcher
根据这种映射关系调用对应的CallBack
.
Event
Event
有以下几种类型:
enum class Type
{
TOUCH,
KEYBOARD,
ACCELERATION,
MOUSE,
FOCUS,
CUSTOM
};
Event
最重要的属性就是type
, 标识了它是那种类型的事件, 也决定了由哪个EventListner
来处理它.
EventListener
EventListner
有以下几种类型:
enum class Type
{
UNKNOWN,
TOUCH_ONE_BY_ONE,
TOUCH_ALL_AT_ONCE,
KEYBOARD,
MOUSE,
ACCELERATION,
FOCUS,
CUSTOM
};
除了UNKNOWN
, 跟Event::Type
相比,Event::Type::TOUCH
会同时被两种类型的EventListener
处理: TOUCH_ONE_BY_ONE
和TOUCH_ALL_AT_ONCE
. 这两种EventListener
分别处理单点触摸事件和多点触摸事件. 多说几句: 假如一个TouchEvent
事件中有多个触摸点, 那么类型为 EventListener::Type::TOUCH_ONE_BY_ONE
的 EventListener
会把这个事件分解成若干个单点触摸事件来处理. 而类型为 EventListener::Type::TOUCH_ALL_AT_ONCE
的 EventListener
就是来处理多点触摸的, 会一次处理它.
其它几种类型都是一一对应的, 即一种Event::Type
的Event
会被对应类型的EventListener
接受.
存放 EventListener 的地方
在EventDispatcher
中, 它把以上7种 EventListener::Type
类型的 EventListner
放到7个队列中. 也就是在这样一个字段中:
std::unordered_map<EventListener::ListenerID, EventListenerVector*> _listenerMap;
EventListener::ListenerID
: 每一种EventListener::Type
有唯一的EventListener::ListenerID
. 其实通过这段代码typedef std::string ListenerID;
可知:EventListener::ListenerID
就是简单string
, 就是一个名称而已.EventListenerVector
: 顾名思义, 就是一个EventListener
的向量容器. 相对于普通的向量容器, 它增加了priority
管理功能.
EventListener的fixedPriority
简单来说, 每个 EventListener
有自己的 fixedPriority
属性, 它是一个整数.
EventListener的遍历顺序
EventDispatcher
在抛发事件的时候, 会先处理 Event
的时候, 会优先遍历 fixedPriority
低的 EventListener
, 调用它的 CallBack
. 在某些条件下, 一个 Event
被一个 EventListener
处理之后, 会停止遍历其它的 EventListener
. 反映到实战中就是: 你监听了某种事件, 这种事件也出发了, 但是对应的回调函数并没有被调用, 也就是被优先级更高的 EventListener
截获了.
如果 fixedPriority
一样呢? 按照什么顺序?
fixedPriority
为0, 这个值是专门为 Scene Object 预留的. 即, 默认情况下, 绝大多数继承自Node
的对象添加的普通事件监听器, 其fixedPriority
都为0. 此时,Node
的globalZOrder
决定了优先级, 值越大, 越先被遍历到, 即在显示层中层级越高, 越先接受事件. 这在ui响应逻辑中也是合理的.fixedPriority
不为0, 那就按添加顺序.
Event在什么条件下会被优先级更高的EventListener截获?
- 对于
EventListenerTouchOneByOne
, 它有一个字段:_needSwallow
, 当它为true
的时候, 如果它接受了某个Event
, 优先级更低的EventListener
就接受不到了. 可以用EventListenerTouchOneByOne::setSwallowTouches(bool needSwallow)
来改变它. - 对于其它类型的
EventLIstener
, 只有在显示调用了Event::stopPropagation()
的时候, 才会中断遍历.
核心函数: EventDispatcher::dispatchEvent()
下面我们看看EventDispatcher
最核心的函数:
void EventDispatcher::dispatchEvent(Event* event)
: 当有响应的事件到来的时候, 都会调用这个函数来通知监听了此事件的对象.
其实, 上面的介绍, 已经把这个函数里绝大部分逻辑都描述了,这里做一个最后的总结
事件抛发的简要流程如下:
- 检查
_listenerMap
中所有的EventListnerVector
, 如果哪个容器的EventListener
优先级顺序需要更新, 则重新排序 - 对于类型为
Event::Type::TOUCH
的事件, 则按照EventListener的遍历顺序遍历所有的EventListener
. 只有接受了EventTouch::EventCode::BEGAN
事件的EventListener
, 才会收到其他类型的EventTouch
事件. - 对于其他类型的事件, 也按照EventListener的遍历顺序的顺序遍历对应的
EventListener
.
总结
Eventdispatcher
中的其它函数, 主要功能都是 添加EventListener
, 删除EventListener
等, 不做详细介绍.
总的来说, Eventdispatcher
是一个中转器:
- 事件的产生模块儿, 只关心自己构造正确的
Event
, 调用EventDispatcher::dispatchEvent(Event* event)
交给EventDispatcher
. - 需要监听事件的模块儿, 只需调用
EventDispatcher::addEventListener(EventListener* listener)
(或者它的其它变种)来注册自己作为监听者. - 而
EventDispatcher
的作用是:
- 把特定类型的
Event
送给对应类型的EventListener
. - 对于同一种
Event
, 规定了事件送达的优先级.
- 把特定类型的
Written with StackEdit.
[cocos2d-x]深入--几个代表性的类 (续)的更多相关文章
- [cocos2d-x]深入--几个代表性的类
摘要: 此文对cocos2d-x引擎中最具代表性,最能体现框架结构的几个类做了简单的介绍, 包括Director,Application, Renderer, EventDispatcher, Sch ...
- Cocos2d 3.0继承自Sprite的类在addChild后出现故障
当继承自Sprite的类被addChild到其它的Node里后出现例如以下图问题,说明没有调用父类Sprite::init()的方法.由于父类Sprite里的_textureAtlas须要初始化为nu ...
- 如何用boost::serialization去序列化派生模板类(续)
在 如何用boost::serialization去序列化派生模板类这篇文章中,介绍了序列化派生类模板类, 在写測试用例时一直出现编译错误,调了非常久也没跳出来,今天偶然试了一下...竟然调了出来. ...
- .NET中的加密算法总结(自定义加密Helper类续)
1.1.1 摘要 相信许多人都使用过.NET提供的加密算法,而且在使用的过程我们必须了解每种加密算法的特点(对称或非对称,密钥长度和初始化向量等等).我也看到过很多人写过.NET中加密算法总结,但我发 ...
- Cocos2d-x——CocosBuilder官方帮助文档翻译1 使用自定义类
原创:请注明转载! 在Cocos2d-x中使用CocosBuilder 使用自定义类 CocosBuilder的使用方法是通过自定义类.在CocosBuilder中选中一个对象并在属性栏中输入自定义类 ...
- cocos2d-x实战 C++卷 学习笔记--第4章 字符串 __String类
前言: <cocos2d-x实战C++卷>学习笔记.(cocos2d-x 是3.0版本) 介绍 cocos2d-x 通用的字符串类 __String . 使用cocos2d::__Str ...
- cocos2D(四)---- CCSprite
在介绍CCSprite之前,先要理解游戏开发中的一个核心概念:精灵.精灵也称为游戏对象,它能够用来表示游戏中的不论什么物体,比方敌人.子弹.甚至是一个背景图片.一段文字.CCSprite能够说是在co ...
- [cocos2dx笔记013]一个使用CCRenderTexture创建动态纹理显示数字的类
用CCLabelTTF显示的数字不好看.于是就想到用图片来代理.眼下网上的实现都是把每一个数字做一个CCSprite组合的方式. 可是我想.动态生成纹理的方式.没有就仅仅好自己手动写一个. 头文件 # ...
- Java类的继承与多态特性-入门笔记
相信对于继承和多态的概念性我就不在怎么解释啦!不管你是.Net还是Java面向对象编程都是比不缺少一堂课~~Net如此Java亦也有同样的思想成分包含其中. 继承,多态,封装是Java面向对象的3大特 ...
随机推荐
- ProgressBar.js – 漂亮的响应式 SVG 进度条
ProgressBar.js 是一个借助动态 SVG 路径的漂亮的,响应式的进度条效果.使用 ProgressBar.js 可以很容易地创建任意形状的进度条.这个 JavaScript 库提供线条,圆 ...
- 总结CSS3新特性(选择器篇)
CSS3新增了嗯- -21个选择器,脚本通过控制台在这里运行; ~: p ~ p { color : red;/*此条规则将用于p后边所有的p...就是除了第一个p的所有p,规则同p:not(:nth ...
- SAP用户权限解剖及自修改
通常BASIS会使用PFCG做权限管理,时你保存时会产生一个系统外的profile name,记得SU01时用户有profile 和role两栏位吗?它们的关系如何呢? 首先明白几个概念.1.acti ...
- Sharepoint学习笔记—习题系列--70-576习题解析 -(Q16-Q18)
Question 16 You are designing a SharePoint 2010 solution to manage statements of work. You need to d ...
- 阿里云服务器怎么去掉tomcat的8080端口
前言:最近在阿里云申请了一个云服务器,然后已买了一个域名.比如www.haha.com ; 在云服务器上安装了tomcat ,访问服务器就成了 http://www.haha.com:8080/ . ...
- PHP将uncode转utf8,一行代码解决问题
在很多场合能看到unicode编码过的文字,如“\u6d3b\u52a8\u63a5\u53e3”,虽然程序会认识,但人眼无法阅读,很不方便,网络上很多人写了很多的转换函数,但是一个比一个臃肿,终于发 ...
- yii2 输出xml格式数据
作者:白狼 出处:http://www.manks.top/yii2_xml_response.html.html本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文 ...
- vim添加Vundle插件
1.git clone https://github.com/VundleVim/Vundle.vim.git ~/.vim/bundle/Vundle.vim 2.vim /etc/vimrc se ...
- (1)编写一个接口ShapePara,要求: 接口中的方法: int getArea():获得图形的面积。int getCircumference():获得图形的周长 (2)编写一个圆类Circle,要求:圆类Circle实现接口ShapePara。 该类包含有成员变量: radius:public 修饰的double类型radius,表示圆的半径。 x:private修饰的double型变量x,
package com.hanqi.test; //创建接口 public interface ShapePara { //获取面积的方法 double getArea(); //获取周长的方法 do ...
- MySQL客户端工具 SQLyog
我最喜欢它的History功能,把执行过的操作对应语句都输出出来,一些麻烦的语句用GUI操作后,还能保存对应的sql语句.不错! 官网:http://www.webyog.com 下面是官方的介绍:S ...