Adventures in Swift: exploring SpriteKit

I decided to have a go at Apple’s programming language Swift, and for some extra fun I opted for making a simple SpriteKit game for OS X. I have made the code available at GitHub in this repository.

Game play

One Knight, lots of soccer balls and a black hole that eats objects that comes close enough. The Knight scores 1 point for each ball that he can get into the black hole. There is a time limit of 1 minute to get as many soccer balls as possible into the black hole. If the Knight gets too close to the black hole, he will be devoured and it is game over.

Getting some graphics to work with

To quickly get an animated sprite as a main character in the game, I browsed opengameart.org and found this beautiful gif by irmirxhttp://opengameart.org/content/animated-runner-character

Knight

For easy use in Xcode I used Pixen to pick out the desired frames and then TexturePacker to generate a sprite sheet and the structs needed for accessing the frames for animation.

Setting up the project

I used the OS X -> Game template in Xcode to get a basic game scene in place. I did not bother with iOS as I found it easier to explore this framework on OS X instead of deploying an iOS app to a simulator/iPhone/iPad.

There are three game scenes: a start scene (“press space to start”), the actual game scene and the Game Over scene. Instead of bloating all logic into the main SKScene-derived game scene, I applied some separation of concerns by having a dedicated class for each moving object within the game (a hero class, a ball class and a black hole class). Each class defines the physics, graphics and actions for the objects that they represent. To get the game classes separated, I had to inject Swift closures as callback functions.

SpriteKit physics

The cool thing with SpriteKit is that you simply define the physical properties of the world and all the objects within it, and the main interactions will be automatically handled by the physics engine. For example, a ball will bounce against walls and against other balls in ways that are defined by its mass, friction and “bounciness”.

When the player interacts with a game object, a move-, force- or impulse action can be applied:

var moveAction = SKAction.moveByX(40, y:0, duration:0.1)
sprite.runAction(moveAction)
sprite.physicsBody?.applyImpulse(CGVectorMake(0, 1000))

This means that you don’t have to bother with calculation of animation- and movement updates at calculated frame intervals to get a natural behavior of the objects.

Collision detection

If the objects just bounced around according to the physics defined, there would only be play and no game. To get at least some excitement, we need to detect collisions. This can be done by implementing a SKPhysicsContactDelegate for the PhysicsWorld property in the GameScene. The didBeginContact function will be triggered when two sprites collide and you can find out which sprites have collided by checking the names of the SKNode:s that are provided in the contact function (and you can also define which collisions trigger a detection by defining contact bit masks).

Closures come in handy when you want to know when an action is finished. When the knight sprite touches the perimeter of the black hole, we define an action that moves the sprite into the center of the black hole. When the action is finished, we execute a closure, which in turn calls a callback function (also a closure) that puts the game into game over state.

let drawnIntoBlackHole = SKAction.moveTo( BlackHole.getCenterPosition(), duration: 1)
node.runAction(drawnIntoBlackHole, completion: { () -> Void in
 gameOverFunction()
})

The game

This game is plain stupid, I know. But it was a good start for exploring Swift, Xcode and SpriteKit. I will definitely continue! And my 8-year old son actually likes to play it. He also has a long wish list of new features to add and tons of new game ideas to try out. :-).

Game screenshot

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s