SpriteKit Animations and Texture Atlases in Swift

Create an animated walking bear while you learn about using texture atlases with animations in this SpriteKit tutorial! By Kevin Colligan.

Leave a rating/review
Download materials
Save for later
Share
Update note: This tutorial has been updated for iOS 11, Xcode 9, and Swift 4.0 by Kevin Colligan. The original tutorial was written by Tony Dahbura.

Smoky says: Only you can start this bear!

Smoky says: Only you can start this bear!

In this SpriteKit tutorial, you’ll create an interactive animation of a walking bear and learn how to:

  • Create efficient animations with texture atlases.
  • Change the direction the bear faces based on where it’s moving.
  • Make your animated bear move in response to touch events.

This tutorial assumes you know the basics of SpriteKit. If not, you might want to start with the SpriteKit Swift 3 Tutorial for Beginners.

It’s time to get started.

Create the Swift Project

Start up Xcode, select File\New\Project…, choose the iOS\Game template and click Next.

Create project

Enter AnimatedBearSwift for the Product Name, Swift for Language, SpriteKit for Game Technology. Make sure the options for Integrate GameplayKit, Include Unit Tests, and Include UI Tests are unchecked and click Next:

Project options

Choose where to save your project, and click Create.

Now that your project is open, select one of the iPad simulators and build and run to check out the starter project. After a brief splash screen, you should see the following:

Hello World!

If you tap on the screen, you’ll see spinning geometric shapes which flare to life then fade from view. Pretty cool, but those won’t do for your bear.

You can download ready-to-animate art, courtesy of GameArtGuppy.com, by clicking the Download Materials button at the top or bottom of this tutorial. When you unzip the materials, you’ll find a folder named BearImages.atlas which contains eight numbered bear images.

Big bunch of bears

With the help of SpriteKit, you’ll cycle through these eight images to create the illusion of movement — kind of like an old-fashioned flip-book.

bear gif

You could create an animation by loading in each of these images individually. But there’s a better way: Use a texture atlas to make your animation more efficient.

Texture Atlases

If you’re new to texture atlases, you can think of them as one big mashup of all your smaller images. Rather than eight separate bear images, your texture atlas will be one big image along with a file that specifies the boundaries between each individual bear image.

SpriteKit is optimized to work with texture atlases. So using this approach can improve memory usage and rendering performance.

It’s also nearly effortless.

Just place your image files in a folder with a name that ends with .atlas — like the BearImages.atlas folder you downloaded. Xcode will notice the .atlas extension and automatically combine the images into a texture atlas for you at compile time.

Drag BearImages.atlas over your project and drop it under the AnimatedBearSwift folder in Xcode:

Import images

In the dialog box that appears, be sure that the Copy items if needed, Create groups and AnimatedBearSwift options are all checked, and click Finish:

Import images 2

If you expand the folder in Xcode it should look like this:

Import images 3

Before you start animating, get your Xcode template ready by completing a few small tasks.

First, click on AnimatedBearSwift in the Project navigator. Make sure that the AnimatedBearSwift target is selected. In the Deployment Info section, choose iPad for Devices and uncheck the Portrait and Upside Down options so only Landscape Left and Landscape Right are left checked, as shown below:

Choose iPad, landscape orientation and delete the GameScene.sks file

Next, find GameScene.sks in the project navigator and press Delete. Choose Move to Trash when prompted.

Be sure you’re deleting GameScene.sks, and not GameScene.swift. GameScene.sks is a scene editor which allows developers to visually lay out sprites and other components of a scene. For this tutorial, you’ll build your scene programmatically.

Similarly, delete Actions.sks as you also don’t need that for this tutorial.

With that out of the way, it’s time get that bear moving :] !

A Simple Animation

Start by plopping the bear in the middle of the screen and looping the animation, just to make sure things are working.

Open GameViewController.swift and replace the contents with the following:

import UIKit
import SpriteKit

class GameViewController: UIViewController {

  override func viewDidLoad() {
    super.viewDidLoad()
    if let view = view as? SKView {
      // Create the scene programmatically
      let scene = GameScene(size: view.bounds.size)
      scene.scaleMode = .resizeFill
      view.ignoresSiblingOrder = true
      view.showsFPS = true
      view.showsNodeCount = true
      view.presentScene(scene)
    }
  }
  
  override var prefersStatusBarHidden: Bool {
    return true
  }
}

This implementation has just what you need to start, so you won’t need the starter code generated by Xcode.

GameViewController is a subclass of UIViewController that has its root view set to an SKView, which is a view that contains a SpriteKit scene.

Here, you’ve overridden viewDidLoad() to create a new instance of GameScene on startup. You define the scene to have the same size as the view, set the scaleMode along with other basic properties and present the scene. For this tutorial, the rest of your code will be in GameScene.swift.

Note: You use optional binding — the if let view = view as? SKView bit — to make sure the view is the correct type before proceeding.

You’re also overriding the prefersStatusBarHidden getter to hide the status bar so that all the attention will be focused on the bear.

Switch over to GameScene.swift and replace the contents with the following:

import SpriteKit

class GameScene: SKScene {
  
  private var bear = SKSpriteNode()
  private var bearWalkingFrames: [SKTexture] = []
  
  override func didMove(to view: SKView) {
    backgroundColor = .blue
  }
}

At this point you’ve just removed all the project template code to create a nice blank slate (and defined a couple private variables you’ll need later). Build and run to make sure everything builds OK — you should see a blue screen.

Note: If you are running in the simulator, you may need to manually rotate the screen by selecting Hardware\Rotate Right.

Setting up the Texture Atlas

Add a new method, just after didMove(to:):

func buildBear() {
  let bearAnimatedAtlas = SKTextureAtlas(named: "BearImages")
  var walkFrames: [SKTexture] = []

  let numImages = bearAnimatedAtlas.textureNames.count
  for i in 1...numImages {
    let bearTextureName = "bear\(i)"
    walkFrames.append(bearAnimatedAtlas.textureNamed(bearTextureName))
  }
  bearWalkingFrames = walkFrames
}

First, you create an SKTextureAtlas from the bear images. walkFrames is an array of SKTexture objects and will store a texture for each frame of the bear animation.

You populate that array by looping through your images’ names (they are named with a convention of bear1.png -> bear8.png) and grabbing the corresponding texture.

Still in buildBear(), add the following right after bearWalkingFrames = walkFrames:

let firstFrameTexture = bearWalkingFrames[0]
bear = SKSpriteNode(texture: firstFrameTexture)
bear.position = CGPoint(x: frame.midX, y: frame.midY)
addChild(bear)

Here, you’re creating an SKSpriteNode using the first frame texture and positioning it in the center of the screen to set up the start of the animation.

Finally, you need to call the method. Add the following code to the end of didMove(to:)

buildBear()

If you were to build and run now, the bear still wouldn’t be moving. In order to do so, we need an SKAction. In the same file, add the following new method right after the buildBear() method:

func animateBear() {
  bear.run(SKAction.repeatForever(
    SKAction.animate(with: bearWalkingFrames,
                     timePerFrame: 0.1,
                     resize: false,
                     restore: true)),
    withKey:"walkingInPlaceBear")
}

This action will cause the animation to run with a 0.1 second wait-time for each frame. The "walkingInPlaceBear" key identifies this particular action with a name. That way, if you call this method again to restart the animation, it will simply replace the existing animation rather than create a new one.

The repeatForever action repeats whatever action it is provided forever, which results in the given animate action repeatedly animating through the textures in the texture atlas.

Now all you need to do is call this method to kick off the animation! Add the following line to the end of didMove(to:):

animateBear()

And that’s it! Build and run the project. You’ll see your bear happily strolling on the screen.

Does a bear walk on an iPad? Yes!

Kevin Colligan

Contributors

Kevin Colligan

Author

Kyle Gorlick

Tech Editor

Morten Faarkrog

Final Pass Editor

Richard Critz

Team Lead

Over 300 content creators. Join our team.