Blurring the scene in SpriteKit

You know what’s pretty cool? SKEffectNode, that’s what. In the game I’m currently hacking on I wanted to have the screen slowly blur out underneath my UI, and a little mucking about with SKEffectNode and Core Image turned up a really nice-looking solution:

The above code will work nicely with the 2D cameras in Swift post. Since my UI is rendered in a separate node attached directly to the scene (and not attached to world), it doesn’t get blurred and everything looks nice and slick.

Blurred background, crisp UI.

Blurred background, crisp UI.

2D Camera in SpriteKit

One thing I missed when I started working with SpriteKit is a proper camera system. In my old, OpenGL ES-based game framework I had a meticulously built 2D camera system that I used literally all of the time; full-on game engines like Unity or Unreal usually have a 2- or 3D camera as a first-order primitive.

Apple’s SpriteKit docs hint at a solution (and give a partial implementation in Objective-C) — attach an empty node to your world and keep the view centred on its position. Below is a complete Swift implementation that sets up a 2d world with its origin at the centre of the screen, plus a camera to move the view within the world and a fixed overlay for showing HUD elements:

Change what’s visible in the world by moving the camera:

Singletons in Swift

I often find myself using singletons when I’m writing iOS apps, especially in games. They’re a perfect pattern for passing state between game screens and making sure that things like player progress are always up-to-date. In Objective-C I’ve always implemented thread-safe singletons using dispatch_once:

Using Grand Central Dispatch to set up a singleton always felt incredibly low-level, so I was pleased to discover a much nicer implementation using computed properties whilst porting some old code into Swift:

Mark the instance static to make it global, and declare it with let to mark it as a constant. The only weird bit (to me, at least) is wrapping the instance in a struct; Swift doesn’t allow static variables inside computed properties, and wrapping the instance in an internal struct lets us get around that restriction.

You can access the (lazily-created, thread-safe) singleton instance through the sharedInstance getter: