Quantcast
Channel: FlexMonkey
Viewing all articles
Browse latest Browse all 257

Radiating Visual Pulses: Visualising AudioKit Sounds in SpriteKit with SKAction

$
0
0



As I continue to experiment with my AudioKit/SpriteKitphysics based audio generation app, I wanted a way to visually feedback on collisions.

The effect I wanted to recreate was an animated pulse radiating from the boxes; a cloned box that would grow and fade out with each collision.

I’ve implemented this effect in my TouchEnabledShapeNode. It exposes a displayCollision() method that accepts a single color argument.

The first step is to clone the box. Since the visual geometry of a SKShapeNode is defined by its CGPath, whatever its shape, we can extract that from the box and generate a new node from that:

        let newNode = SKShapeNode(path: self.path)
        
        newNode.strokeColor = color
        
        addChild(newNode)

Next, I need to calculate how much I’ll need to scale this new node during the animation. I’ve decided I want it to grow my 50 points during the animation, so I use CGPathGetPathBoundingBox() to get the current dimensions and add 50 points to the with and height:

        let boundingBox = CGPathGetPathBoundingBox(self.path)
        let targetWidth = boundingBox.width+50
        let targetHeight = boundingBox.height+50

With those target dimensions, I can calculate the x and y scales required:

        let scaleX = targetWidth / boundingBox.width
        let scaleY = targetHeight / boundingBox.height

Unlike UIKit, we can’t use UIView.animateWithDuration() with SpriteKit components. Instead, we create instances of SKAction which define what properties are to be animated and add them to runAction() which is invoked on the target SKNode.

Using the calculated scale factors, I create a single action that will simultaneously scale the new node horizontally and vertically:

        let scaleAction = SKAction.scaleXTo(scaleX, y: scaleY , duration: 0.25)
        scaleAction.timingMode = SKActionTimingMode.EaseOut

While the new node is growing, I also want it to fade out, so I create another action to do that:

        let fadeAction = SKAction.fadeAlphaTo(0, duration: 0.25)
        fadeAction.timingMode = SKActionTimingMode.EaseOut

Both of these actions are bundled into a single group which makes them run concurrently:

        let actionGroup = SKAction.group([scaleAction, fadeAction])

Finally, the group is passed into the runAction() method which is invoked on the new node:

        newNode.runAction(actionGroup, completion: { newNode.removeFromParent() })


All the source code for this post is available in my GitHub repository here.

Viewing all articles
Browse latest Browse all 257

Trending Articles