SpriteKit: как перебрать предков узла?

Мы хотим перебирать предков узла, пока не найдем родителя с определенным классом.

SpriteKit позволяет перебирать потомков со свойством children, но свойство parent содержит только непосредственного родителя, а не массив родителей. Как мы перебираем всех предков узла?


person Crashalot    schedule 18.04.2017    source источник
comment
Я почти уверен, что использование childNodeWithName дает вам узлы в обоих направлениях, вам просто нужно использовать /, чтобы он начинался с корневого узла, точно не дает вам родителя, но может помочь, если ребенок знает имя дедушки   -  person Knight0fDragon    schedule 18.04.2017
comment
@Knight0fDragon интересная идея. почему бы не опубликовать как ответ, чтобы его увидело больше людей? если вы пробовали это и знаете, что это работает, я могу отметить это как ответ.   -  person Crashalot    schedule 18.04.2017
comment
Не ответ на ваш вопрос, это скорее другая стратегия   -  person Knight0fDragon    schedule 19.04.2017


Ответы (2)


Я не знаю функции, которая позволяет вам подниматься по иерархии, подобно функции enumerateChildNodes, которая позволяет вам спускаться по иерархии. Возможно, эта рекурсивная функция может помочь. Ниже я установил завершение рекурсии, когда нет родителя или когда родителем является класс SKScene. Возможно, вам придется настроить его так, чтобы рекурсия заканчивалась, когда был найден ваш конкретный класс.

func parentNodesOf(_ node: SKNode) -> [SKNode]
{
    if let parentNode = node.parent
    {
        if parentNode is SKScene
        {
            return []
        }
        else
        {
            return [parentNode] + parentNodesOf(parentNode)
        }
    }
    else
    {
        return []
    }
}

Надеюсь это поможет!

person JohnV    schedule 18.04.2017
comment
Возможно, это было бы еще полезнее, если бы добавить расширение класса SKNode (скажем, свойство parent). - person Whirlwind; 18.04.2017
comment
Истинный. Вы, вероятно, хотите, чтобы это было расширением SKNode, а не отдельно стоящей функцией. - person JohnV; 18.04.2017

Альтернатива ответу JohnV

extension SKNode {
    func forEachAncestor(_ closure: (_ ancestor: SKNode) -> Void) {
        var currentParent: SKNode? = self.parent
        while currentParent != nil {
            closure(currentParent!)
            currentParent = currentParent!.parent
        }
    }
}
person Nicolas Nascimento    schedule 18.04.2017
comment
Не 100% ответ, вы закрываете всех предков, где ОП хочет нацелиться на конкретного - person Knight0fDragon; 19.04.2017