Organizing your assets
We will quickly overrun our project navigator with image files if we add all our textures as we did with our bee. Luckily, Xcode provides several solutions.
Exploring Images.xcassets
We can store images in an .xcassets
file and refer to them easily from our code. This is a good place for our background images:
- Open
Images.xcassets
from your project navigator. - We do not need to add any images here now but, in the future, you can drag image files directly into the image list, or right-click, then Import.
- Notice that the SpriteKit demo's spaceship image is stored here. We do not need it anymore, so we can right-click on it and choose Removed Selected Items to delete it.
Collecting art into texture atlases
We will use texture atlases for most of our in-game art. Texture atlases organize assets by collecting related artwork together. They also increase performance by optimizing all of the images inside each atlas as if they were one texture. SpriteKit only needs one draw call to render multiple images out of the same texture atlas. Plus, they are very easy to use! Follow these steps to build your bee texture atlas:
- We need to remove our old bee texture. Right-click on
bee.png
in the project navigator and choose Delete, then Move to Trash. - Using Finder, browse to the asset pack you downloaded and locate the
Enemies
folder. - Create a new folder inside
Enemies
and name itbee.atlas
. - Locate the
bee.png
andbee_fly.png
images insideEnemies
and copy them into your newbee.atlas
folder. You should now have a folder namedbee.atlas
containing the two bee PNG files. This is all you need to do to create a new texture atlas – simply place your related images into a new folder with the.atlas
suffix. - Add the atlas to your project. In Xcode, right-click on the project folder in the project navigator and click Add Files…, as we did earlier for our single bee texture.
- Find the
bee.atlas
folder and select the folder itself. - Check Copy items if needed, then click Add.
The texture atlas will appear in the project navigator. Good work; we organized our bee assets into one collection and Xcode will automatically create the performance optimizations mentioned earlier.
Updating our bee node to use the texture atlas
We can actually run our project right now and see the same bee as before. Our old bee texture was bee.png
, and a new bee.png
exists in the texture atlas. Though we deleted the standalone bee.png
, SpriteKit is smart enough to find the new bee.png
in the texture atlas.
We should make sure our texture atlas is working, and that we successfully deleted the old inpidual bee.png
. In GameScene.swift
, change our SKSpriteNode
instantiation line to use the new bee_fly.png
graphic in the texture atlas:
// create our bee sprite
// notice the new image name: bee_fly.png
let bee = SKSpriteNode(imageNamed: "bee_fly.png")
Run the project again. You should see a different bee image, its wings held lower than before. This is the second frame of the bee animation. Next, we will learn to animate between the two frames to create an animated sprite.
Iterating through texture atlas frames
We need to study one more texture atlas technique: we can quickly flip through multiple sprite frames to make our bee come alive with motion. We now have two frames of our bee in flight; it should appear to hover in place if we switch back and forth between these frames.
Our node will run a new SKAction
to animate between the two frames. Update your didMoveToView
function to match mine (I removed some older comments to save space):
override func didMoveToView(view: SKView) { self.backgroundColor = UIColor(red: 0.4, green: 0.6, blue: 0.95, alpha: 1.0) // create our bee sprite // Note: Remove all prior arguments from this line: let bee = SKSpriteNode() bee.position = CGPoint(x: 250, y: 250) bee.size = CGSize(width: 28, height: 24) self.addChild(bee) // Find our new bee texture atlas let beeAtlas = SKTextureAtlas(named:"bee.atlas") // Grab the two bee frames from the texture atlas in an array // Note: Check out the syntax explicitly declaring beeFrames // as an array of SKTextures. This is not strictly necessary, // but it makes the intent of the code more readable, so I // chose to include the explicit type declaration here: let beeFrames:[SKTexture] = [ beeAtlas.textureNamed("bee.png"), beeAtlas.textureNamed("bee_fly.png")] // Create a new SKAction to animate between the frames once let flyAction = SKAction.animateWithTextures(beeFrames, timePerFrame: 0.14) // Create an SKAction to run the flyAction repeatedly let beeAction = SKAction.repeatActionForever(flyAction) // Instruct our bee to run the final repeat action: bee.runAction(beeAction) }
Run the project. You will see our bee flap its wings back and forth – cool! You have learned the basics of sprite animation with texture atlases. We will create increasingly complicated animations using this same technique later in the book. For now, pat yourself on the back. The result may seem simple, but you have unlocked a major building block towards your first SpriteKit game!