Swift Game Development(Third Edition)
上QQ阅读APP看书,第一时间看更新

Centering the camera on a sprite

Games often require the camera to follow the player sprite as it moves through space. We definitely want this camera behavior for Pierre, our penguin character, whom we will soon be adding to the game. With iOS9, Apple added a new SKCameraNode class, which makes this task easy. We will attach an SKCameraNode to our scene and position it directly over the player to keep their character centered in the view.

You can find the code for our camera functionality in the following code block. Read the comments for a detailed explanation. This is a quick recap of the changes:

  • Our didMove function was becoming too crowded. We broke out our flying bee code into a new function named addTheFlyingBee. Later, we will encapsulate game objects, such as bees, into their own classes.
  • We created two new constants on the GameScene class: the camera node and the bee node.
  • We updated the didMove function. It assigns the new camera node to the scene's camera.
  • We have added a new function to add a background sprite, just to show that the bee is actually moving and that the camera is centered on the bee.
  • Inside the new addTheFlyingBee function, we removed the bee constant, as GameScene now declares it above as its own property.
  • We are implementing a new function: didSimulatePhysics. SpriteKit calls this function every frame after performing physics calculations and adjusting positions. It's a great place to update our camera position. The code to change the camera position and keep the view centered on the player resides in this new function.

Please update your entire GameScene.swift file to match mine:

import SpriteKit

classGameScene: SKScene { 
    // Create a constant cam as a SKCameraNode: 
let cam = SKCameraNode() 
    // Create our bee node as a property of GameScene so we can 
    // access it throughout the class 
    // (Make sure to remove the old bee declaration below) 
let bee = SKSpriteNode() 

override func didMove(to view: SKView) { 
self.anchorPoint = .zero 
self.backgroundColor = UIColor(red: 0.4, green: 0.6, blue: 
            0.95, alpha: 1.0) 

        // Assign the camera to the scene 
self.camera = cam 

        // Call the new bee function 
self.addTheFlyingBee()

        // Add background
        self.addBackground()

} 

    // A new function 
Override func didSimulatePhysics() { 
        // Keep the camera centered on the bee 
        // Notice the !operator after camera. SKScene's camera 
        // is an optional, but we know it is there since we 
        // assigned it above in the didMove function. We can tell 
        // Swift that we know it can unwrap this value by using 
        // the !operator after the property name. 
self.camera!.position = bee.position
    } 

    // new function to add background
func addBackground(){

let bg = SKSpriteNode(imageNamed:"background-menu")
bg.position = CGPoint(x: 250, y: 250)
self.addChild(bg)
    }

    // I moved all of our bee animation code into a new function: 
func addTheFlyingBee() { 
        // Position our bee 
bee.position = CGPoint(x: 250, y: 250) 
bee.size = CGSize(width: 28, height: 24) 
        // Add the bee to the scene 
self.addChild(bee) 

        // Find the bee textures from the texture atlas 
let beeAtlas = SKTextureAtlas(named:"Enemies") 
let beeFrames:[SKTexture] = [ 
beeAtlas.textureNamed("bee"), 
beeAtlas.textureNamed("bee-fly")] 
        // Create a new SKAction to animate between the frames  
let flyAction = SKAction.animate(with: beeFrames, 
timePerFrame: 0.14) 
        // Create an SKAction to run the flyAction repeatedly 
let beeAction = SKAction.repeatForever(flyAction) 
        // Instruct our bee to run the final repeat action: 
bee.run(beeAction) 

        // Set up new actions to move our bee back and forth: 
let pathLeft = 
SKAction.moveBy(x: -200, y: -10, duration: 2) 
let pathRight = 
SKAction.moveBy(x: 200, y: 10, duration: 2) 
let flipTextureNegative = 
SKAction.scaleX(to: -1, duration: 0) 
let flipTexturePositive = 
SKAction.scaleX(to: 1, duration: 0) 
        // Combine actions into a cohesive flight sequence 
let flightOfTheBee = SKAction.sequence([ 
pathLeft,flipTextureNegative, pathRight, 
flipTexturePositive]) 
        // Last, create a looping action that will repeat forever 
let neverEndingFlight = 
SKAction.repeatForever(flightOfTheBee) 

        // Tell our bee to run the flight path, and away it goes! 
bee.run(neverEndingFlight) 
    } 
} 

Run the game. You should see our bee stuck directly at the center of the screen, flipping back and forth every two seconds:

Centering the camera on a sprite

The bee is actually changing position, just as before, but the camera is moving to keep the bee centered on the screen. When we add more game objects in Chapter 3, Mixing in the Physics, our bee will appear to be flying as the entire world pans past the screen.

Note

Checkpoint 2-B

The code up to this point is available in this chapter's code resources.