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

Teaching our penguin to fly

Let's implement the control scheme for our penguin. The player can tap anywhere on the screen to make Pierre fly higher and release to let him fall. We are going to make quite a few changes--if you need help, refer to the checkpoint at the end of this chapter. Start by modifying the Player class; follow these steps to prepare our Player for flight:

  1. In Player.swift, add some new properties directly to the Player class:
            // Store whether we are flapping our wings or in free-fall: 
    var flapping = false 
            // Set a maximum upward force. 
            // 57,000 feels good to me, adjust to taste: 
            let maxFlappingForce: CGFloat = 57000 
            // Pierre should slow down when he flies too high: 
            let maxHeight: CGFloat = 1000 
  2. So far, Pierre has been flapping his wings by default. Instead, we want to display the soaring animation by default and only run the flap animation when the user presses the screen. In the init function, remove the line that runs flyAnimation and, instead, run soarAnimation:
    self.run(soarAnimation, withKey: "soarAnimation") 
  3. When the player touches the screen, we apply the upward force in the Player class's update function. Remember that GameScene calls the Player update function once per frame. Add this code in update:
            // If flapping, apply a new force to push Pierre higher. 
            if self.flapping { 
    var forceToApply = maxFlappingForce
    
                // Apply less force if Pierre is above position 600 
                if position.y> 600 { 
                    // The higher Pierre goes, the more force we  
                    // remove. These next three lines determine the    
                    // force to subtract: 
                    let percentageOfMaxHeight = position.y / maxHeight
                    let flappingForceSubtraction =  
    percentageOfMaxHeight * maxFlappingForce
    forceToApply -= flappingForceSubtraction
                } 
                // Apply the final force: 
                self.physicsBody?.applyForce(CGVector(dx: 0, dy:  
    forceToApply)) 
            } 
    
            // Limit Pierre's top speed as he climbs the y-axis. 
            // This prevents him from gaining enough momentum to shoot 
            // over our max height. We bend the physics for game play: 
            if self.physicsBody!.velocity.dy> 300 { 
                self.physicsBody!.velocity.dy = 300 
            } 
  4. Finally, we will provide two functions on Player to allow other classes to start and stop the flapping behavior. The GameScene class will call these functions when it detects touch input. Add the following functions to the Player class:
            // Begin the flap animation, set flapping to true: 
    func startFlapping() { 
    self.removeAction(forKey: "soarAnimation") 
    self.run(flyAnimation, withKey: "flapAnimation") 
    self.flapping = true 
            } 
    
            // Stop the flap animation, set flapping to false: 
    func stopFlapping() { 
    self.removeAction(forKey: "flapAnimation") 
    self.run(soarAnimation, withKey: "soarAnimation") 
    self.flapping = false 
            } 

Perfect, our Player is ready for flight. Now, we will simply invoke the start and stop functions from the GameScene class.