获取Cocos Studio 2.X生成资源的子孙节点的方法

所有继承自Node类型的节点都支持使用getChildByName(name)和getChildByTag(tag)来获取当前节点的某个子节点。这两个函数已经能够满足我们大部分的需求。

但有时候我们需要获取某个节点的子节点的子节点、甚至子节点的子节点的子节点、甚至… 这样的需求是很常见的,而一层一层去get未免太繁琐。

对于Cocos Studio 1.x版本,Cocos2d-x提供了两个seek函数来帮我们解决这个问题:seekWidgetByName和seekWidgetByTag,放置在ui::UIHelper中,这两个函数会自动去搜索各个层,直到搜索到第一个匹配的对象。

但是UIHelper提供的两个函数中假定各个子节点类型为Widget,在2.0的机制下,Studio创建的节点可能同时包含Widget以及非Widget类型的节点,所以原来的方法就不适用新版本了。

不过虽然两个函数假定节点是Widget类型,但都只用到了node的接口,我们只要复制这两个函数,把其中的Widget改成Node,就能用了。

修改后的两个函数如下,照着修改UIHelper的内容。用js和lua的就你们自己写一个吧:

Node* seekNodeByTag(Node* root, int tag){ 
    if (!root) 
    { 
        return nullptr; 
    } 
    if (root->getTag() == tag) 
    { 
        return root; 
    } 
    const auto& arrayRootChildren = root->getChildren(); 
    ssize_t length = arrayRootChildren.size(); 
    for (ssize_t i=0;i<length;i++) 
    { 
        Node* child = dynamic_cast<Node*>(arrayRootChildren.at(i)); 
        if (child) 
        { 
            Node* res = seekNodeByTag(child,tag); 
            if (res != nullptr) 
            { 
                return res; 
            } 
        } 
    } 
    return nullptr; 
} 


Node* seekNodeByName(Node* root, const std::string& name) 
{ 
    if (!root) 
    { 
        return nullptr; 
    } 
    if (root->getName() == name) 
    { 
        return root; 
    } 
    const auto& arrayRootChildren = root->getChildren(); 
    for (auto& subWidget : arrayRootChildren) 
    { 
        Node* child = dynamic_cast<Node*>(subWidget); 
        if (child) 
        { 
            Node* res = seekNodeByName(child,name); 
            if (res != nullptr) 
            { 
                return res; 
            } 
        } 
    } 
    return nullptr; 
}

广度优先+递归消除算法:

Node * Helper::seekNodeByName_WF(Node *root,const std::string &name) 
{ 
   if(!root || root->getName() == name) 
      return root; 

   auto vecChildren = &root->getChildren(); 
   std::vector<decltype(vecChildren)>vec; 
   vec.push_back(vecChildren); 
   size_t index = 0; 
   do  
   { 
      vecChildren = vec[index]; 
      for(auto node : *vecChildren) 
      { 
            if(node->getName() == name) 
            { 
               return node; 
            } 
            vec.push_back(&node->getChildren()); 
        } 
       ++index; 
    } while (index != vec.size()); 

return nullptr; 
} 
Node * Helper::seekNodeByTag_WF(Node *root,int tag) 
{ 
    if(!root || root->getTag() == tag) 
        return root; 

    auto vecChildren = &root->getChildren(); 
    std::vector<decltype(vecChildren)>vec; 
    vec.push_back(vecChildren); 
    size_t index = 0; 
    do  
    { 
       vecChildren = vec[index]; 
        for(auto node : *vecChildren) 
        { 
            if(node->getTag() == tag) 
            { 
                return node; 
            } 
            vec.push_back(&node->getChildren()); 
        } 
        ++index; 
    } while (index != vec.size()); 

    return nullptr; 
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值