Spritekit Multi-Node Animation Sequencer, Could It Be More Perfect?

I needed to be able to order a set of SKActions running across multiple nodes and wrote this test. It's easy to do multiple things on a single node, but there is no direct support for running sequences after working on multiple nodes (like swapping two nodes and then scrolling through some other nodes, then fading out at some other nodes). The following code processes the sequence, but I am wondering if scanning all nodes each update

might take too long if the number of nodes is too large.

class AnimatorSequence
{
    var animatorStack = [Animator]()
    var currentAnimator : Animator!

    func startAnimator()
    {
        currentAnimator = animatorStack.removeAtIndex(0)
        currentAnimator.execute()
    }

    func addAnimator( animator : Animator )
    {
        animatorStack.append(animator)
        if currentAnimator==nil && animatorStack.count == 1
        {
            startAnimator();
        }
    }

    func process()
    {
        if let anim = currentAnimator
        {
            if anim.isDone()
            {
                currentAnimator = nil
                if animatorStack.count > 0
                {
                    startAnimator();
                }
            }
        }
    }
}

let animatorSequencer = AnimatorSequence()

class Animator
{
    typealias functionType = (() -> Void)?
    var function : functionType
    var parentNode : SKNode

    init (function:functionType, parent : SKNode)
    {
        self.function = function
        self.parentNode = parent
    }

    func execute()
    {
        if let f = function
        {
            f()
        }
    }

    func isDone() -> Bool
    {
        var count = parentNode.children.count
        for node in parentNode.children
        {
            if !node.hasActions()
            {
                count--;
            }
        }
        return count==0;
    }
}

      

Call example:

    let a = Animator(function: { () -> Void in

        firstDot.node.runAction(moveToSecond)
        secondDot.node.runAction(moveToFirst)

        }
        , parent : self
    )

    animatorSequencer.addAnimator(a)

      

and every update

override func update(currentTime: CFTimeInterval)
{
    animatorSequencer.process()
}

      

The point of this is to allow me to easily arrange multiple multi-node animations with nothing more than a closure and not require anything complicated. This seems to work, but I'm wondering if there is a more efficient way to determine if all SKActions have completed.

+3


source to share


1 answer


I actually wrote a class to do what you are looking for. it is, in fact, a queue of SKActions called one after another. whatever you add to the queue will be processed sequentially so you don't have to worry about callback routines anymore. you can add actions from several different SKSpriteNodes without having to create action sequences.



https://github.com/evannnc/ActionQ

+2


source







All Articles