Удалить определенный список SKAction из SKNode

Во время разработки некоторых взаимодействий между разными узлами я понял, что мне нужно удалить определенный список действий из узла. Текущая версия Sprite-Kit framework предоставляет некоторые методы экземпляра, такие как:

Очевидно, что каждое действие, выполняемое в моем узле, имеет ключ String для идентификации. Поэтому я подумал о чем-то очень похожем на removeAllAction, а затем сделал расширение SKNode:

public extension SKNode {
    func removeAllAction(in list:[String]) {
       list.forEach { if self.action(forKey: $0) != nil { self.action(forKey: $0)?.speed = 0.0; self.removeAction(forKey: $0)}}
    }
}

И в моем проекте я могу использовать его как:

let actionList = ["idle_walk_sx","idle_walk_dx","walk_dx","walk_sx","walk_idle_sx","walk_idle_dx","rotate_sx_dx","rotate_dx_sx"]
self.removeAllAction(in: actionList)

Код работает хорошо. Но я не совсем уверен в двух факторах:

  • эффективности speed исправлений (до нуля), я счел целесообразным ввести его в условиях повторных действий. Должен ли я удалить его, чтобы избежать странности или оставить его?
  • Как можно расширить это расширение (расширить его) на любые дочерние элементы, у которых есть один и тот же список для удаления?

person Alessandro Ornano    schedule 15.01.2017    source источник
comment
где и когда вы устанавливаете скорость, на что и почему?   -  person Confused    schedule 16.01.2017
comment
speed = 0 не нужен, когда вы удаляете действие, оно выполняется немедленно, поэтому на этапе оценки действий оно не будет вызываться. Кроме того, if list.count > 0 также не нужен, так как forEach позаботится о счете 0 для вас.   -  person Knight0fDragon    schedule 16.01.2017
comment
@Knight0fDragon Хорошая мысль, согласен.   -  person Alessandro Ornano    schedule 16.01.2017
comment
могут ли idle_walk_sx и idle_walk_dx происходить одновременно?   -  person Knight0fDragon    schedule 16.01.2017
comment
@Knight0fDragon Эм, не в моем случае, но в целом может случиться, о чем вы думаете?   -  person Alessandro Ornano    schedule 16.01.2017
comment
ну, я бы не стал добавлять несколько ключей к вашему действию, у меня был бы 1 набор действий с именем animation_state и использование userData для определения фактического имени состояния действия.   -  person Knight0fDragon    schedule 16.01.2017
comment
таким образом, вы не будете без нужды перебирать кучу состояний анимации только для того, чтобы удалить 1 (или 2), которые вы ищете   -  person Knight0fDragon    schedule 16.01.2017
comment
@Knight0fDragon узел может иметь другие действия вне текущего состояния анимации (направление ..), например, вы можете прыгать и двигаться влево, одновременно анимируя своего персонажа ..   -  person Alessandro Ornano    schedule 16.01.2017
comment
Это нормально, userData может хранить ключи действий, которые в настоящее время прикреплены к спрайту, и когда вы хотите удалить действия, вы просто перебираете то, что находится в userData.   -  person Knight0fDragon    schedule 16.01.2017
comment
@Knight0fDragon Ах да!, хорошее возможное решение.   -  person Alessandro Ornano    schedule 16.01.2017


Ответы (1)


Я согласен с комментариями. Вероятно, speed не нужен, поэтому код + сканирование дочерних узлов может быть примерно таким:

public extension SKNode {
    func removeAllAction(in list:[String]) {
        list.forEach { if self.action(forKey: $0) != nil { self.removeAction(forKey: $0)}}
        self.children
            .filter { $0.hasActions() }
            .forEach { $0.removeAllAction(in: list) }
    }
}
person Alessandro Ornano    schedule 18.01.2017