按照相关资料说法:设置的数值越小,触摸优先级越高,同等优先级,优先响应后添加的
事实从源代码来看:同等优先级时会响应第一个添加的。
例如在3.0以前的版本中CCMenu就存在这样的情况,将子节点集合正序遍历改成反序遍历即可修正。
3.0之后触摸模块有改动,统一通过EventDispatcher控制,当然,依然是优先响应先添加的控件,在对集合遍历时时正序遍历,而此时集合为升序排序从小到大 0<,>0,设置的数值越小,触摸优先级越高在这里体现了
源代码如下:
void EventDispatcher::dispatchEventToListeners(EventListenerVector* listeners, const std::function<bool(EventListener*)>& onEvent) { bool shouldStopPropagation = false; auto fixedPriorityListeners = listeners->getFixedPriorityListeners(); auto sceneGraphPriorityListeners = listeners->getSceneGraphPriorityListeners(); ssize_t i = 0; // priority < 0 if (fixedPriorityListeners) { CCASSERT(listeners->getGt0Index() <= static_cast<ssize_t>(fixedPriorityListeners->size()), "Out of range exception!"); if (!fixedPriorityListeners->empty()) { for (; i < listeners->getGt0Index(); ++i) { auto l = fixedPriorityListeners->at(i); if (l->isEnabled() && !l->isPaused() && l->isRegistered() && onEvent(l)) { shouldStopPropagation = true; break; } } } } //省略.. }
升序排序代码如下:
void EventDispatcher::sortEventListenersOfFixedPriority(const EventListener::ListenerID& listenerID) { auto listeners = getListeners(listenerID); if (listeners == nullptr) return; auto fixedListeners = listeners->getFixedPriorityListeners(); if (fixedListeners == nullptr) return; // After sort: priority < 0, > 0 std::sort(fixedListeners->begin(), fixedListeners->end(), [](const EventListener* l1, const EventListener* l2) { return l1->getFixedPriority() < l2->getFixedPriority(); }); // FIXME: Should use binary search int index = 0; for (auto& listener : *fixedListeners) { if (listener->getFixedPriority() >= 0) break; ++index; } listeners->setGt0Index(index); #if DUMP_LISTENER_ITEM_PRIORITY_INFO log("-----------------------------------"); for (auto& l : *fixedListeners) { log("listener priority: node (%p), fixed (%d)", l->_node, l->_fixedPriority); } #endif }
到这里,再看同等优先级的问题,在注册添加回调的时候是这样的:
void EventDispatcher::forceAddEventListener(EventListener* listener) { EventListenerVector* listeners = nullptr; EventListener::ListenerID listenerID = listener->getListenerID(); auto itr = _listenerMap.find(listenerID); if (itr == _listenerMap.end()) { listeners = new EventListenerVector(); _listenerMap.insert(std::make_pair(listenerID, listeners)); } else { listeners = itr->second; } listeners->push_back(listener);//添加到容器尾部 if (listener->getFixedPriority() == 0) { setDirty(listenerID, DirtyFlag::SCENE_GRAPH_PRIORITY); auto node = listener->getAssociatedNode(); CCASSERT(node != nullptr, "Invalid scene graph priority!"); associateNodeAndEventListener(node, listener); if (node->isRunning()) { resumeEventListenersForTarget(node); } } else { setDirty(listenerID, DirtyFlag::FIXED_PRIORITY); } }所以回到上面,对容器做排序,同等优先级是不会交换位置的,所以先添加的还是在前面。然后到派遣事件时,还是先派遣到先添加的。所以现在可以证明同等优先级时会响应第一个添加的。
那么要改成同等优先级,优先响应后添加可以这样,在将监听添加进容器时插入:
void EventDispatcher::EventListenerVector::push_back(EventListener* listener) { #if CC_NODE_DEBUG_VERIFY_EVENT_LISTENERS CCASSERT(_sceneGraphListeners == nullptr || std::count(_sceneGraphListeners->begin(), _sceneGraphListeners->end(), listener) == 0, "Listener should not be added twice!"); CCASSERT(_fixedListeners == nullptr || std::count(_fixedListeners->begin(), _fixedListeners->end(), listener) == 0, "Listener should not be added twice!"); #endif if (listener->getFixedPriority() == 0) { if (_sceneGraphListeners == nullptr) { _sceneGraphListeners = new std::vector<EventListener*>(); _sceneGraphListeners->reserve(100); } //_sceneGraphListeners->push_back(listener); auto it = _sceneGraphListeners->begin(); for (; it != _sceneGraphListeners->end(); it++) { if ((*it)->getFixedPriority() == listener->getFixedPriority()) break; } _sceneGraphListeners->insert(it, listener); } else { if (_fixedListeners == nullptr) { _fixedListeners = new std::vector<EventListener*>(); _fixedListeners->reserve(100); } //_fixedListeners->push_back(listener); auto it = _fixedListeners->begin(); for (; it != _fixedListeners->end(); it++) { if ((*it)->getFixedPriority() == listener->getFixedPriority()) break; } _fixedListeners->insert(it, listener); } }
这样之后,就达到了同等优先级,优先响应后添加的
相关推荐
cocos2d-x 3.0 人物行走 . 包里有代码和 图片资源.
这是我重新弄的cocos2d-x-3.0的类图.之前别人兄台弄的,有些不全面,有些地方错误.我这个可以说是最新的了.每个类添加了中文的详细注解,同时也添加了中文的类名称翻译.这样对cocos2d-x-3.0的框架比较好上手. 有兴趣的...
Cocos2d-x3.0正式版 练练看 源码。有注释。
兄弟连cocos2d-x3.0 final视频教程 1.Cocos2d-x手机游戏开发C编程基础 2.Cocos2d-x手机游戏开发C++编程基础 3.Cocos2d-x3.0 final手机游戏开发核心技术 4.实例:贪吃蛇 5.实例:微信飞机大战
这是cocos2d-x 3.0 类关系图, 这个制作者是:gamecocos2dx 他做的Xmind,我导出的PNG格式,我推荐还是看Xmind,里面还有一些注释 gamecocos2dx Xmind下载地址:...
这是一个cocos2d-x 3.0中文开发文档.
http://blog.csdn.net/zoyzn/article/details/27251633一文的源码。cocos2d-x 3.0导出自定义类到lua,并导出自定义类的名称空间到lua。
cocos2d-x 3.0 骨骼动画 demo 以及注意事项
本游戏基于cocos2d-x 3.0版本,可能不适用于cocos2d-x 2.x版本,请看清楚,再参考! 使用方法:将Classes中的类全部拷贝到新建cocos项目的Classes项目中,将Resources下的所有文件拷贝到对应的文件下,运行即可!
cocos2d-x 3.0 rapidjson 读取Json
资源名称:Cocos2d-x实战:JS卷——Cocos2d-JS开发内容简介:本书是介绍Cocos2d-x游戏编程和开发技术书籍,介绍了使用Cocos2d-JS中核心类、瓦片地图、物理引擎、音乐音效、数据持久化、网络通信、性能优化、多平台...
官网中文docs文档的例子下载 创建工程的时候一定要创建一样的文件名 http://www.cocos2d-x.org/docs/tutorial/framework/native/how-to-drag-and-drop-sprites/zh
Cocos2d-x3.0final 自学教程的配套代码http://blog.csdn.net/column/details/cocos2dx2014.html
cocos2d-x 3.0 开发文档英文版(html)
Cocos2d-x3.0游戏实例《别救我》源码。 教程地址:http://blog.csdn.net/musicvs/article/details/24928929
Cocos2d-x 3.0 过渡学习 尊重原创,转载来自:star特530的CSDN博客 :http://blog.csdn.net/star530?viewmode=contents
Cocos2d-x-3.x游戏开发之旅-钟迪龙著 全新pdf版和附书代码(代码为工程文件,可复制) 附带目录标签
cocos2d-x 3.0-alpha0 SDK头文件和DLL文件
我自己从 cocos2d-x 3.0 版中的doc目录下使用doxygen自己生成的离线文档,希望能帮助大家