EventDispatch机制

本文深入探讨了Cocos2d-x3.x中的事件机制,包括通过访问Node的全局Zorder来排列优先级的过程。文章详细解释了如何遍历Scene下的所有子Layer,将比当前Layer优先级数小的节点存放在_nodePriorityMap中,并清除子Layer中优先级小的节点。此外,文章还介绍了每个Node的sortChildren操作以及二叉树中序遍历的类比,用于理解事件的派发过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

cocos2dx 3.x中的事件机制原理:

通过访问Node的全局Zorder来排列优先级。

            _globalZOrderNodeMap[node->getGlobalZOrder()].push_back(node);


_globalZOrderNodeMap 作为迭代的容器,最后处理根节点排序的结果(会清理掉当前存放的节点),真正有效的数据时排列好的:_nodePriorityMap。

首先遍历Scene下的所有子Layer(Node*),把子节点中比当前Layer优先级数值小的存放在_nodePriorityMap,接着清除子Layer中比当前Layer优先级小的节点,然后把当前节点放入_globalZOrderNodeMap 。

每个Node都有一个sortChildren操作,排列出来的就是根据Zorder,只要先处理比当前Layer深度优先的(Zorder),再处理当前layer,和小于或等于的Children——整个原理就跟二叉树中序遍历比较类似,判定条件是Zorder。

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. oid EventDispatcher::visitTarget(Node* node, bool isRootNode)  
  2. {      
  3.     int i = 0;  
  4.     auto& children = node->getChildren();  
  5.       
  6.     auto childrenCount = children.size();  
  7.       
  8.     if(childrenCount > 0)  
  9.     {  
  10.         Node* child = nullptr;  
  11.         // visit children zOrder < 0  
  12.         for( ; i < childrenCount; i++ )  
  13.         {  
  14.             child = children.at(i);  
  15.               
  16.             if ( child && child->getLocalZOrder() < 0 )  
  17.                 visitTarget(child, false);  
  18.             else  
  19.                 break;  
  20.         }  
  21.           
  22.         if (_nodeListenersMap.find(node) != _nodeListenersMap.end())  
  23.         {  
  24.             _globalZOrderNodeMap[node->getGlobalZOrder()].push_back(node);  
  25.         }  
  26.           
  27.         for( ; i < childrenCount; i++ )  
  28.         {  
  29.             child = children.at(i);  
  30.             if (child)  
  31.                 visitTarget(child, false);  
  32.         }  
  33.     }  
  34.     else  
  35.     {  
  36.         if (_nodeListenersMap.find(node) != _nodeListenersMap.end())  
  37.         {  
  38.             _globalZOrderNodeMap[node->getGlobalZOrder()].push_back(node);  
  39.         }  
  40.     }  
  41.     //递归的所有过程中只有根节点进入(Scene),事件的派发级是依据<span style="font-family: Arial, Helvetica, sans-serif;">_nodePriorityMap中的结果去派发</span>  
  42.   
  43.     if (isRootNode)  
  44.     {  
  45.         std::vector<float> globalZOrders;  
  46.         globalZOrders.reserve(_globalZOrderNodeMap.size());  
  47.           
  48.         for (const auto& e : _globalZOrderNodeMap)  
  49.         {  
  50.             globalZOrders.push_back(e.first);  
  51.         }  
  52.           
  53.         std::sort(globalZOrders.begin(), globalZOrders.end(), [](const float a, const float b){  
  54.             return a < b;  
  55.         });  
  56.           
  57.         for (const auto& globalZ : globalZOrders)  
  58.         {  
  59.             for (const auto& n : _globalZOrderNodeMap[globalZ])  
  60.             {  
  61.                 _nodePriorityMap[n] = ++_nodePriorityIndex;  
  62.             }  
  63.         }  
  64.           
  65.         _globalZOrderNodeMap.clear();  
  66.     }  
  67. }  


_nodePriorityIndex 为SceneGraphPriority控制量,最后组合成从0到N不重复的数字队列,去标示每个Node,所有的Node具有不同的优先级。

来源:http://blog.youkuaiyun.com/jingzhewangzi/article/details/40644955

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值