Game Development with Swift
上QQ阅读APP看书,第一时间看更新

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:

  1. Open Images.xcassets from your project navigator.
  2. 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.
  3. 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:

  1. We need to remove our old bee texture. Right-click on bee.png in the project navigator and choose Delete, then Move to Trash.
  2. Using Finder, browse to the asset pack you downloaded and locate the Enemies folder.
  3. Create a new folder inside Enemies and name it bee.atlas.
  4. Locate the bee.png and bee_fly.png images inside Enemies and copy them into your new bee.atlas folder. You should now have a folder named bee.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.
  5. 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.
  6. Find the bee.atlas folder and select the folder itself.
  7. 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!