With Apple’s recent release of the Swift programming language I have decided I have to check it out. One of the biggest reasons I’ve stayed away from Apple’s various SDKs is my dislike of Objective-C. Swift on the other hand is quite a nice little language at least from my experiences so far.
Keep in mind a couple thing while reading this. I am new to Swift ( everyone is, it’s a day old! ) and am new to Apple’s various SDKs and Frameworks. Therefore I give no promises that anything in this tutorial series is actually the proper way of doing things. Frankly it works on my computer and that’s about the extent of a warranty I can give! 🙂 I have heard great things about SpriteKit, the 2D game library Apple released with iOS 7, so I am working with it.
Let’s jump right in with some code. The following is a Mac OS app, but should work equally well on iOS devices. Keep in mind, to run Swift code you need to have Xcode 6, which is currently in beta. Obviously you need to have a Mac to follow around. There are “cloud based” virtual Mac services you can use as well, but my experiences weren’t great.
To get started I used one of the provided templates then replaced most of the code. There used to be a SpriteKit template, but now it has been rolled into “Game”.
In Xcode select File -> New -> Project
Then select OS X -> Application and choose Game, then click Next:
In the next dialog, name your application, be sure to select Swift as the programming language and SpriteKit as the Game Technology, click Next.
In the next dialog you select where you want to create the project and whether or not you want to create a git archive. In this case I am not, but if you are working with a team or want version controlling, allow it to create a git repository.
When done, click Create and your project will be created. When I run the generated project, I actually get:
Well, that’s not good! Truth is though, I want to start simpler than the included project, so we are going to replace all the code anyways. The starter template seems a bit odd to me, extending behaviour that should have probably been built in in the first place. Let’s get rid of the complexity and strip it down to basics.
When you look at the project hierarchy Xcode has created, you will see a number of generated files. Swift code files end with the extension .swift ( well, that makes sense… ). It’s these that we are going to replace. The generated project should look something like:
For each file listed below, edit your source to match:
AppDelegate.swift
import Cocoa
import SpriteKit
class AppDelegate: NSObject, NSApplicationDelegate {
@IBOutlet var window: NSWindow
@IBOutlet var skView: SKView
func applicationDidFinishLaunching(aNotification: NSNotification?) {
let scene = GameScene(size:self.skView.bounds.size)
scene.scaleMode = .AspectFill
self.skView!.presentScene(scene)
}
func applicationShouldTerminateAfterLastWindowClosed(sender: NSApplication) -> Bool {
return true;
}
}
GameScene.swift
import SpriteKit
class GameScene: SKScene {
override func didMoveToView(view: SKView) {
/* Setup your scene here */
let sprite = SKSpriteNode(imageNamed: “beach.png”)
sprite.position = CGPoint(x:0,y:0)
sprite.anchorPoint = CGPoint(x:0.0,y:0.0)
sprite.size = view.bounds.size
self.addChild(sprite)
}
}
You can completely delete the file GameScene.sks.
Additionally, I dragged an Image file “beach.png” into my project file from Finder. You can use any image you want, just be sure to update the filename in GameScene.swift accordingly. When dropping the image file, make sure you select Copy if needed, and that the image is being put in the proper target, like so:
Now when you run the program ( Play icon in top left of your Xcode window ), you should see:
Of course, in your case it should display whatever image you selected. Let’s take a quick look at what we’ve done here.
In our AppDelegate, we handle the applicationDidFinishLaunching event. Once our app is launched, we create an instance of our GameScene class, set the fill mode to AspectFill and make our newly created scene active for our SKView. This small function implementation demonstrates a few Swift concepts, i’ll start from the beginning.
Notice the line:
let scene = GameScene(size:self.skView.bounds.size)
How we pass in the name of the variable parameter (size), as well as a value (self.skView.bounds.size). When declaring a function in Swift you have to option of making the user name the parameters or not when they call the function. That is, when you are declaring a function, you can specify an internal and external parameter name and if you provide an external parameter name, the user must provide the name when calling the function. Consider the function:
func printSomething(item:String){
println(item)
}
For that function, you can simply call it like:
printSomething(“Hey”)
However, if you declared the function using an external parameter name, like so:
func printSomething(thingToPrint item:String){
println(item)
}
You then need to call the function like so:
printSomething(thingToPrint:“Hey”)
If you are familiar with Flash, TypeScript or Haxe, the syntax for functions in Swift should look pretty familiar. It’s basically
func functionName ( externalVarName localVarName:DataType ) -> ReturnType { FunctionBody }
The next line containing new Swift syntax is:
scene.scaleMode = .AspectFill
Scale mode is simply an enum defined like so ( in SKScene )
enum SKSceneScaleMode : Int { case Fill case AspectFill case AspectFit case ResizeFill }
That line is functionally the same as:
scene.scaleMode = SKSceneScaleMode.AspectFill
The final line here that might be a bit confusing is
self.skView!.presentScene(scene)
Specifically the exclamation mark after skView. This has the somewhat scary name of “implicitly unwrapped optionals”. See, all types in Swift must have a value, either at declaration or construction. The exception to this rule is Optional Types. If you’ve worked in C# this concept ( and syntax ) should look familiar to you, although in C# they are called nullable types. An optional type declaration looks like this:
var myVariable:String?
This is declaring a type that can either have a value, or the special value “nil”. For an optional type you can “implicitly unwrap” it, using the ! postfix operator, like so:
println(myVariable!)
When you do this, you are promising that myVariable currently has a value. If it doesn’t, you will get a runtime error.
The GameScene class is much more straight forward and uses very few new Swift features. We are loading a SKSpriteNode from file, once again you see an example of an external parameter name here, “imageNamed”. We then set the image pivot point to the bottom left corner, just because I like the image pivot point being the bottom left corner! SetPivot works in texture coordinated, so 0,0 is bottom left, while 1,1 is top right. We size our image to be the same as the view, then finally add the sprite to the SKScene using addChild().
And that is our very first simple application created in Swift displays a sprite on screen using SpriteKit.