SpriteKit Tutorial for Beginners

In this SpriteKit tutorial, you will learn how to create a simple 2D game using SpriteKit, Apple’s 2D game framework, while writing in Swift 4! By Brody Eller.

Leave a rating/review
Download materials
Save for later
Share
Update note: This SpriteKit tutorial has been updated by Brody Eller. The original post was written by Ray Wenderlich.

Like Batman and Robin or Superman and Lois Lane, SpriteKit and Swift are an amazing combination:

  • SpriteKit is one of the best ways to make games on iOS. It’s easy to learn, powerful, and is fully supported by Apple.
  • Swift is an easy language to get started with, especially if you are a beginner to the iOS platform.

In this tutorial, you will learn how to create a simple 2D game using Apple’s 2D game framework, SpriteKit — using Swift!

You can either follow along with this SpriteKit tutorial, or just jump straight to the sample project at the end. And yes. There will be ninjas.

SpriteKit vs. Unity

The most popular alternative to SpriteKit at the moment is a game framework called Unity. Unity was originally developed as a 3D engine, but it has full built-in 2D support, too.

Before you get started, put some thought into whether SpriteKit or Unity is the best choice for your game.

Advantages of SpriteKit

  • It’s built right into iOS. There is no need to download extra libraries or have external dependencies. You can also seamlessly use other iOS APIs like iAd, In-App Purchases, etc. without having to rely on extra plugins.
  • It leverages your existing skills. If you already know Swift and iOS development, you can pick up SpriteKit extremely quickly.
  • It’s written by Apple. This gives you some confidence that it will be well supported moving forward on all of Apple’s new products. For example, you can use the same SpriteKit code to make your game work on iOS, macOS, and tvOS without a hitch.
  • It’s free. Maybe one of the best reasons for small indies! You get all of SpriteKit’s functionality at no cost. Unity does have a free version but it doesn’t have all of the features of the Pro version. You’ll need to upgrade if you want to avoid the Unity splash screen, for example.

Advantages of Unity

  • Cross-platform. This is one of the big ones. If you use SpriteKit, you’re locked into the Apple ecosystem. With Unity, you can easily port your games to Android, Windows, and more.
  • Visual scene designer. Unity makes it extremely easy to lay out your levels and test your game in realtime with the click of a button. SpriteKit does have a scene editor, but it is very basic compared to what Unity offers.
  • Asset store. Unity comes with a built-in asset store where you can buy various components for your game. Some of these components can save you a good bit of development time!
  • More powerful. In general, Unity just has more features and functionality than the SpriteKit/Scene Kit combination.

Which Should I Choose?

After this you may be thinking, “Well, which 2D framework should I choose?”

The answer depends on what your goals are:

  • If you’re a complete beginner, or solely focused on the Apple ecosystem: Use SpriteKit — it’s built-in, easy to learn, and will get the job done.
  • If you want to be cross-platform, or have a more complicated game: Use Unity — it’s more powerful and flexible.

If you think Unity is for you, check out our book Unity Games by Tutorials.

Otherwise, keep reading on to get started with this SpriteKit tutorial!

Getting Started

Start by downloading the project files at the top or bottom of this page. Open the starter project and navigate to GameViewController.swift. Add the following at the end of viewDidLoad():

let scene = GameScene(size: view.bounds.size)
let skView = view as! SKView
skView.showsFPS = true
skView.showsNodeCount = true
skView.ignoresSiblingOrder = true
scene.scaleMode = .resizeFill
skView.presentScene(scene)

GameViewController is a normal UIViewController, except that its root view is an SKView, which is a view that contains a SpriteKit scene.

Here, you’ve instructed viewDidLoad() to create a new instance of the GameScene on startup, with the same size as the view itself. Setting skView.showsFPS to true means a frame rate indicator will be displayed.

That’s it for the initial setup; now it’s time to get something on the screen!

Adding a Sprite

Open GameScene.swift and add with the following to GameScene:

// 1
let player = SKSpriteNode(imageNamed: "player")
  
override func didMove(to view: SKView) {
  // 2
  backgroundColor = SKColor.white
  // 3
  player.position = CGPoint(x: size.width * 0.1, y: size.height * 0.5)
  // 4
  addChild(player)
}

Here’s what this does, step by step:

  1. Here you declare a private constant for the player (i.e. the ninja), which is an example of a sprite. As you can see, creating a sprite is easy — simply pass in the name of the image to use.
  2. Setting the background color of a scene in SpriteKit is as simple as setting the backgroundColor property. Here you set it to white.
  3. You position the sprite to be 10% across horizontally, and centered vertically.
  4. To make the sprite appear on the scene, you must add it as a child of the scene.

Build and run, and voilà — ladies and gentlemen, the ninja has entered the building!

SpriteKit Tutorial

Moving Monsters

Next you want to add some monsters into your scene for your ninja to combat. To make things more interesting, you want the monsters to be moving — otherwise there wouldn’t be much of a challenge! You’ll create the monsters slightly off screen to the right and set up an action that tells them to move to the left.

Add the following methods to GameScene.swift, inside the class, before the closing curly brace:

func random() -> CGFloat {
  return CGFloat(Float(arc4random()) / 0xFFFFFFFF)
}

func random(min: CGFloat, max: CGFloat) -> CGFloat {
  return random() * (max - min) + min
}

func addMonster() {
  
  // Create sprite
  let monster = SKSpriteNode(imageNamed: "monster")
  
  // Determine where to spawn the monster along the Y axis
  let actualY = random(min: monster.size.height/2, max: size.height - monster.size.height/2)
  
  // Position the monster slightly off-screen along the right edge,
  // and along a random position along the Y axis as calculated above
  monster.position = CGPoint(x: size.width + monster.size.width/2, y: actualY)
  
  // Add the monster to the scene
  addChild(monster)
  
  // Determine speed of the monster
  let actualDuration = random(min: CGFloat(2.0), max: CGFloat(4.0))
  
  // Create the actions
  let actionMove = SKAction.move(to: CGPoint(x: -monster.size.width/2, y: actualY),
                                 duration: TimeInterval(actualDuration))
  let actionMoveDone = SKAction.removeFromParent()
  monster.run(SKAction.sequence([actionMove, actionMoveDone]))
}

The first part of addMonster() should make sense based on what you’ve learned so far: you do some simple calculations to determine where you want to create the object, set the position of the object, and add it to the scene the same way you did for the player sprite.

The new element here is adding actions. SpriteKit provides a lot of extremely useful built-in actions that help you easily change the state of sprites over time, such as move actions, rotate actions, fade actions, animation actions, and more. Here you use three actions on the monster:

  • SKAction.move(to:duration:): You use this action to make the object move off-screen to the left. You can specify how long the movement should take, and here you vary the duration randomly from 2-4 seconds.
  • SKAction.removeFromParent(): SpriteKit comes with a helpful action that removes a node from its parent, effectively deleting it from the scene. Here you use this action to remove the monster from the scene when it is no longer visible. This is important because otherwise you would have an endless supply of monsters and would eventually consume all device resources.
  • SKAction.sequence(_:): The sequence action allows you to chain together a sequence of actions that are performed in order, one at a time. This way, you can have the “move to” action performed first, and once it is complete, you perform the “remove from parent” action.
Note: This code block includes some helper methods to generate a random number within a range using arc4random(). This suffices for the simple random number generation needs in this game, but if you want more advanced functionality, check out the random number APIs in GameplayKit.

One last thing before you move on. You need to actually call the method to create monsters! And to make things fun, let’s have monsters continuously spawning over time.

Simply add the following code to the end of didMove(to:):

run(SKAction.repeatForever(
      SKAction.sequence([
        SKAction.run(addMonster),
        SKAction.wait(forDuration: 1.0)
        ])
    ))

Here you run a sequence of actions to call a block of code, and then wait for 1 second. You repeat this sequence of actions endlessly.

That’s it! Build and run the project; now you should see monsters happily moving across the screen:

SpriteKit Tutorial

Brody Eller

Contributors

Brody Eller

Author

Felicity Johnson

Tech Editor

Essan Parto

Final Pass Editor

Richard Critz

Team Lead

Over 300 content creators. Join our team.