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

Tracking the player's progress

First, we need to keep track of how far the player has flown. We will use this later as well, for keeping track of a high score. This is easy to implement. Follow these steps to track how far the player has flown:

  1. In the GameScene.swift file, add two new properties to the GameScene class:
            let initialPlayerPosition = CGPoint(x: 150, y: 250) 
    var playerProgress = CGFloat() 
  2. In the didMove function, update the line that positions the player to use the new initialPlayerPosition constant instead of the old hardcoded value:
            // Add the player to the scene: 
    player.position = initialPlayerPosition
  3. In the didSimulatePhysics function, update the new playerProgress property with the player's new distance:
            // Keep track of how far the player has flown 
    playerProgress = player.position.x -
    initialPlayerPosition.x

Perfect! We now have access to the player's progress at all times in the GameScene class. We can use the distance traveled to reposition the ground at the correct time.

Looping the ground as player the moves forward

There are many possible methods to create an endless ground loop. We will implement a straightforward solution that jumps the ground forward after the player has travelled over roughly one third of its width. This method guarantees that the ground always covers the screen, given that our player starts in the middle third.

We will create the jump logic on the Ground class. Follow these steps to implement endless ground:

  1. Open the Ground.swift file and add two new properties to the Ground class:
    var jumpWidth = CGFloat() 
            // Note the instantiation value of 1 here: 
    var jumpCount = CGFloat(1) 
  2. In the createChildren function, we find the total width from one third of the children tiles and make it our jumpWidth. We will need to jump the ground forward every time the player travels this distance. You only need to add one line at the very bottom of the createChildren function:
            // Save the width of one-third of the children nodes 
    jumpWidth = tileSize.width * floor(tileCount / 3) 
  3. Add a new function named checkForReposition to the Ground class, after the createChildren function. The scene will call this function before every frame to check whether we should jump the ground forward:
    func checkForReposition(playerProgress: CGFloat) { 
                // The ground needs to jump forward 
                // every time the player has moved this distance: 
                let groundJumpPosition = jumpWidth * jumpCount
    
                if playerProgress>= groundJumpPosition { 
                    // The player has moved past the jump position! 
                    // Move the ground forward: 
    self.position.x += jumpWidth
                    // Add one to the jump count: 
    jumpCount += 1 
                } 
            } 
  4. Open GameScene.swift and add this line at the bottom of the didSimulatePhysics function to call the Ground class's new logic:
            // Check to see if the ground should jump forward: 
    ground.checkForReposition(playerProgress: playerProgress) 

Run the project. The ground will seem to stretch on forever as Pierre flies forward. This looping ground is a big step toward the final game world. It may seem like a lot of work for a simple effect, but the looping ground is important, and our method will perform well on any screen size. Great work!

Note

Checkpoint 4-B

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