Search code examples
swiftsprite-kitclosuresskactioneasing

SKEase action, how to use Float changing Action Setter Block?


In the following use case, I'm trying to animate the lineWidth of an SKShapeNode.

SKEase is part of the wonderful SpriteKitEasing github repo from Craig Grummitt.

One of its facilities is a Float changing ease action that appears to change the value of a float over time.

However I can't figure out how to use it. Xcode gives the following suggestions when typing it in:

 let lineWeight = SKEase.createFloatTween(<start: CGFloat, end: CGFloat, time: TimeInterval, easingFunction: AHEasingFunction, setterBlock: ((SKNode, CGFloat) -> Void))

With other SKEase actions from this library, Xcode is very helpful with ease types, and helping to figure out what to enter.

With this one, I have no idea what options are available for AHEasingFunctions... which I can probably find.

But I have absolutely no idea what or how to use the final part, the setterBlock seemingly expecting a function taking a pair of parameters unrelated to the activity. XCode won't accept SKShapeNodes or SKSpriteNodes here, only an SKNode, but I can't get beyond that.


Here's how the docs for SKEase describe it:

enter image description here


Solution

  • If you type let fn = SKEase.getEaseFunction( and then a dot for the enum types for curve-type and ease-type you'll get completion.

    With the SKNode to SKShapeNode you'll have to cast.

    Here's some code:

        let fn = SKEase.getEaseFunction(.curveTypeQuadratic, easeType: .easeTypeInOut)
        let easeFat = SKEase.createFloatTween(2.5, end: 30.0, time: easeTime/2, easingFunction: fn) { (node: SKNode, param: CGFloat) in
            let spinny = node as! SKShapeNode
            spinny.lineWidth = param
        }
        let easeThin = SKEase.createFloatTween(30.0, end: 2.5, time: easeTime/2, easingFunction: fn) { (node: SKNode, param: CGFloat) in
            let spinny = node as! SKShapeNode
            spinny.lineWidth = param
        }
    
        if let spinnyNode = self.spinnyNode {
            spinnyNode.lineWidth = 2.5
    
            let rotate = SKAction.rotate(byAngle: CGFloat(M_PI) * CGFloat(2.0), duration: easeTime)
            let easeFatThin = SKAction.sequence([easeFat, easeThin])
            let rotateAndEase = SKAction.group([rotate, easeFatThin])
    
            spinnyNode.run(SKAction.repeatForever(rotateAndEase))
            spinnyNode.run(SKAction.sequence([SKAction.wait(forDuration: easeTime),
                                              SKAction.fadeOut(withDuration: easeTime),
                                              SKAction.removeFromParent()]))
        }
    

    And a complete project on my GitHub.