CCNode рекурсивный getChildByTag

Насколько я понимаю, метод CCNode::getChildByTag ищет только среди прямых потомков.

Но есть ли способ рекурсивно найти дочерний элемент CCNode по тегу во всей его иерархии потомков?

Я загружаю CCNode из файла ccb CocosBuilder и хочу получить подузлы, зная только их теги (а не их позицию/уровень в иерархии)


person sdabet    schedule 09.11.2012    source источник
comment
если вам это нужно, вы можете легко реализовать рекурсивный getChildByTag, который посещает всю иерархию.   -  person sergio    schedule 09.11.2012


Ответы (2)


Один из способов - создать свой метод. Или создайте категорию для CCNode с помощью этого метода. Это будет выглядеть примерно так

- (CCNode*) getChildByTagRecursive:(int) tag
{
    CCNode* result = [self getChildByTag:tag];

    if( result == nil )
    {
        for(CCNode* child in [self children])
        {
            result = [child getChildByTagRecursive:tag];
            if( result != nil )
            {
                break;
            }
        }
    }

    return result;
}

Добавьте этот метод в категорию CCNode. Вы можете создать категорию в любом файле, но я рекомендую создать отдельный файл только с этой категорией. В этом случае любой другой объект, куда будет импортирован этот заголовок, сможет отправить это сообщение любому подклассу CCNode.

На самом деле это сообщение сможет отправить любой объект, но при компиляции будет выдаваться предупреждение, если заголовок не импортирован.

person Morion    schedule 09.11.2012
comment
вы не вызываете это рекурсивно - person LearnCocos2D; 09.11.2012
comment
В какой класс пойдет этот метод? - person sdabet; 09.11.2012
comment
Ох, хорошо. До сих пор у меня никогда не было заголовков категорий, я на самом деле не мастер Objective C :). Спасибо за совет - person sdabet; 09.11.2012

Вот реализация cocos2d-x 3.x для рекурсивной функции getChildByTag:

/** 
 * Recursively searches for a child node
 * @param typename T (optional): the type of the node searched for.
 * @param nodeTag: the tag of the node searched for.
 * @param parent: the initial parent node where the search should begin.
 */
template <typename T = cocos2d::Node*>
static inline T getChildByTagRecursively(const int nodeTag, cocos2d::Node* parent) {
    auto aNode = parent->getChildByTag(nodeTag);
    T nodeFound = dynamic_cast<T>(aNode);
    if (!nodeFound) {
        auto children = parent->getChildren();
        for (auto child : children)
        {
            nodeFound = getChildByTagRecursively<T>(nodeTag, child);
            if (nodeFound) break;
        }
    }
    return nodeFound;
}

В качестве опции вы также можете передать тип искомого узла в качестве аргумента.

person schmittsfn    schedule 30.07.2014