Cocos2dx引擎9-注册事件监听器
来源:互联网 发布:战舰世界 爱宕数据 编辑:程序博客网 时间:2024/05/21 17:58
1、事件处理方法
下面为普通的点击事件监听器(下面简称EventListener)注册部分;注册EventListener需要实现onTouchBegan方法,可以实现onTouchEnded、onTouchCancelled方法,当然如果你想监听触控(鼠标)移动(拖动)监听器需要实现onTouchMoved方法,这里使用Lambda方式简单实现了onTouchBegin方法;
auto event =EventListenerTouchOneByOne::create();event->onTouchBegan= [sprite](Touch *touch, Event *event){ if(sprite->getBoundingBox().containsPoint(touch->getLocation())){ …… return true; //此时的返回值很关键;true会继续调用下面的onTouchEnded方法,false不会调用onTouchEnded方法 } return false;}; event->onTouchEnded= [this](Touch *touch, Event *event){ ……};
Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(event,sprite);//注册EventListener
在Cocos2dx事件处理系统中并不会区分事件是哪个Node发出的。不管你点击屏幕什么位置(当然点击黑边位置只会打印错误信息),Cocos2dx会将所有的注册EventListener处理方法都会执行一遍;故在事件处理程序中需要添加
if(sprite->getBoundingBox().containsPoint(touch->getLocation()))
来判断点击是否为该注册EventListener;
2、EventListener注册方法
在上述实例中时候用addEventListenerWithSceneGraphPriority方法注册的EventListener,在Cocos2dx中还支持其他几种EventListener的注册方式
(1) addCustomEventListener 添加自定义EventListener
(2) addEventListenerWithFixedPriority 使用优先级添加EventListener
(3) addEventListenerWithSceneGraphPriority 绑定Node方式添加EventListener,优先级为0,优先级最高
addCustomEventListener可以自己定义EventListener,在合适的时候手动分发该事件,这样使用该ID所有自定义EventListener都会被调用,使用这种方法可以实现广播的效果;
addEventListenerWithFixedPriority注册的EventListener会一直存在,直到手动移除该EventListener;
addEventListenerWithSceneGraphPriority注册EventListener时会绑定Node节点,在Node的析构函数(Node从内存删除时调用)中会将Node绑定的Listern移除;节点中使用该方法别较好,当切换Scene时,所有不需要的EventListener都会被移除;
下面分别介绍这三种添加方式
EventListenerCustom*EventDispatcher::addCustomEventListener(const std::string &eventName, conststd::function<void(eventcustom*)>& callback){ EventListenerCustom *listener =EventListenerCustom::create(eventName, callback); addEventListenerWithFixedPriority(listener,1); return listener;}</void(eventcustom*)>
在addCustomEventListener中:
(1) 使用自定义名称,回调函数,new一个自定义监EventListener
(2) 添加自定义EventListener
顾名思义,该方法的作用是添加一个自定义EventListener,callback为回调函数,需要手动调用Director::getInstance()->getEventDispatcher()->dispatchCustomEvent(…)或
Director::getInstance()->getEventDispatcher()->dispatchEvent(…)来触发
voidEventDispatcher::addEventListenerWithFixedPriority(EventListener* listener, intfixedPriority){ if (!listener->checkAvailable()) return; listener->setAssociatedNode(nullptr); listener->setFixedPriority(fixedPriority); listener->setRegistered(true); listener->setPaused(false); addEventListener(listener);}
在addEventListenerWithFixedPriority方法中:
(1) 判断EventListener可用
(2) 将关联节点设置为null,设置优先级,设置已注册,暂停标志
(3) 将该EventListener添加到EventListener列表中
voidEventDispatcher::addEventListenerWithSceneGraphPriority(EventListener*listener, Node* node) { //如果_onEvent=false,即没有默认的回调函数 if (!listener->checkAvailable()) return; listener->setAssociatedNode(node);// EventListener归属Node listener->setFixedPriority(0); listener->setRegistered(true); addEventListener(listener);//添加点击EventListener}
在addEventListenerWithSceneGraphPriority中
(1) 判断EventListener可用
(2) 设置EventListener关联节点,设置FixedPriority=0
(3) 添加EventListener
3、EventListener注册
voidEventDispatcher::addEventListener(EventListener* listener){ if (_inDispatch == 0) { forceAddEventListener(listener);//添加Listener} else{ _toAddedListeners.push_back(listener); //将EventListener临时添加到_toAddedListeners中 } listener->retain();//内存管理部分,引用计数+1}
在addEventListener方法中
(1)判断当前是否在分发事件或执行事件处理方法
(2)若为分发事件或执行事件处理方法,添加EventListener到EventListener列表;否则将EventListener临时添加到toAddedListeners中
Cocos2dx虽然是单线程循环渲染的,但是触摸屏点击、加速传感器等EventListener是在新线程中处理的,如果处理器为多核(现在大多手机是多核的)就会有可能出现多个线程同时执行;在添加EventListener的过程中,正在分发事件或执行事件处理方法,就会将该EventListener添加到_toAddedListeners中,待此时事件处理完毕后,才将_toAddedListeners中EventListener添加到EventListener列表中。具体实现会在下面事件分发中讲述。
voidEventDispatcher::forceAddEventListener(EventListener* listener){ EventListenerVector* listeners = nullptr; EventListener::ListenerID listenerID =listener->getListenerID(); auto itr = _listenerMap.find(listenerID); //根据EventListener类型查找EventListener列表 if (itr == _listenerMap.end()){ //该类型EventListener第一次被添加 listeners = new EventListenerVector(); //新建EventListener列表 _listenerMap.insert(std::make_pair(listenerID,listeners)); }else{ listeners = itr->second; } listeners->push_back(listener); //添加EventListener if (listener->getFixedPriority() == 0) { setDirty(listenerID,DirtyFlag::SCENE_GRAPH_PRIORITY); auto node =listener->getAssociatedNode(); CCASSERT(node != nullptr, "Invalidscene graph priority!"); associateNodeAndEventListener(node,listener); if (node->isRunning()){ resumeEventListenersForTarget(node); } }else{ setDirty(listenerID,DirtyFlag::FIXED_PRIORITY); }}
在forceAddEventListener方法中
(1)根据EventListener的类型才查找EventListener列表,若该类型EventListener是第一次添加,则新建该类型的EventListener列表
(2)将该EventListener添加到EventListener类表中,在添加EventListener过程中会首先判断_fixedPriority是否为0;若为0则加入_sceneGraphListeners中,否则加入_fixedListeners中
(3)设置对应listenerID的脏数据标志;当_fixedPriority为0时,需将EventListener和注册EventListener的节点Node绑定,插入到_nodeListenersMap中;
EventListener注册完成后,我们关心的就是事件分发了,下一篇将会介绍Cocos2dx-3.2的事件分发机制
- Cocos2dx引擎9-注册事件监听器
- cocos2dx事件监听器
- 注册时钟事件监听器
- 给按钮注册事件监听器
- cocos2dx源码分析:事件监听器EventListener
- Cocos2dx 用户事件 事件监听器 事件分发器
- cocos2dx+lua注册事件函数详解 事件
- SWT注册无类型事件监听器
- 【Android 开发教程】注册事件监听器
- android 动态注册sdcard插播事件监听器
- cocos2dx+lua注册事件函数详解
- cocos2dx+lua注册事件函数详解
- cocos2dx+lua注册事件函数详解
- cocos2dx+lua注册事件函数详解
- cocos2dx中lua注册事件函数详解
- cocos2dx+lua注册事件函数详解
- cocos2dx+lua注册事件函数详解
- cocos2dx+lua注册事件函数详解
- C++虚函数和虚继承浅析
- iOS 类别和扩展(Categories和Extensions)
- eclipse maven配置
- 转为json数据、json-lib和google gson对比
- IOS-使用AVAudioPlayer播放音乐文件无声音
- Cocos2dx引擎9-注册事件监听器
- mybatis学习笔记一mybatis结合spring mvc配置
- jvm(7)-虚拟机类加载机制
- dpdk初识
- Andriod中Style/Theme原理以及Activity界面文件选取过程浅析
- 手机卫士 第九天
- 简单的JSP交互程序
- php - 字符串内容为数组如何进行格式转换为数组
- 隐藏用户