How to Make a Game Like Mega Jump With Sprite Kit and Swift: Part 2/2

In this final part of the tutorial series, you’ll finish your game like Mega Jump, and add the level design, accelerometer support, and HUD using Swift and Sprite Kit! By Michael Briscoe.

Leave a rating/review
Save for later
Share
You are currently viewing page 3 of 4 of this article. Click here to view the first page.

Building the HUD

Before you start awarding points, you’re going to build a simple heads-up display (HUD) so that the player can see their score and star count.

Your HUD will show the total number of collected stars on the top-left of the scene and the current score on the top-right of the scene. For this, you need to create two SKLabelNodes.

Add the following class properties to the file GameScene.swift:

// Labels for score and stars
var lblScore: SKLabelNode!
var lblStars: SKLabelNode!

To build the HUD, add the following code to init(size:) in GameScene.swift, just before the line that initializes motionManager:

// Build the HUD
        
// Stars
// 1
let star = SKSpriteNode(imageNamed: "Star")
star.position = CGPoint(x: 25, y: self.size.height-30)
hudNode.addChild(star)
        
// 2
lblStars = SKLabelNode(fontNamed: "ChalkboardSE-Bold")
lblStars.fontSize = 30
lblStars.fontColor = SKColor.whiteColor()
lblStars.position = CGPoint(x: 50, y: self.size.height-40)
lblStars.horizontalAlignmentMode = SKLabelHorizontalAlignmentMode.Left
        
// 3
lblStars.text = String(format: "X %d", GameState.sharedInstance.stars)
hudNode.addChild(lblStars)
        
// Score
// 4
lblScore = SKLabelNode(fontNamed: "ChalkboardSE-Bold")
lblScore.fontSize = 30
lblScore.fontColor = SKColor.whiteColor()
lblScore.position = CGPoint(x: self.size.width-20, y: self.size.height-40)
lblScore.horizontalAlignmentMode = SKLabelHorizontalAlignmentMode.Right
        
// 5
lblScore.text = "0"
hudNode.addChild(lblScore)

Take a closer look at this section of code:

  1. First you add a star graphic in the top-left corner of the scene to tell the player that the following number is the collected star count.
  2. Next to the star, you place a left-aligned SKLabelNode.
  3. You initialize the label with the number of stars from GameState.
  4. You add a right-aligned SKLabelNode in the top-right corner of the scene.
  5. You initialize that label to zero, as there is no score currently.

Build and run. You’ll see the two labels at the top of the screen.

23-HUD

The last layer of your game is complete! Now let’s have some points already!

Awarding Points

It’s finally time to award points for the player’s hard work. There are two ways to score points in Uber Jump: climbing up the scene and collecting stars.

To award points for collecting stars, open GameObjectNode.swift and simply add the following code to the bottom of collisionWithPlayer in StarNode, just before the return statement:

// Award score
GameState.sharedInstance.score! += (starType == .Normal ? 20 : 100)

That’s it! You add 20 points to the score for a normal star and 100 points for the special type.

To show this updated score, go back to didBeginContact in GameScene.swift. Recall from Part One of this tutorial that this method sets a flag named updateHUD to true when it determines that the values displayed in the HUD need to change.

Add the following two lines of code to didBeginContact inside the if updateHUD {...} condition curly braces. There should be a comment there that reads TODO: Update HUD in Part 2:

lblStars.text = String(format: "X %d", GameState.sharedInstance.stars)
lblScore.text = String(format: "%d", GameState.sharedInstance.score)

Build and run, and tap to start the game. As you collect stars, watch your score increase.

24-HUDPointsFromStars

To work out when to award points for traveling up the screen, you need to store the highest point along the y-axis that the player has reached during this play-through. You’ll use this data to increase the score only when the player reaches a new high point, rather than award points constantly as the player bobs up and down the screen.

Add the following class property to the file GameScene.swift:

// Max y reached by player
var maxPlayerY: Int!

The player node initially starts at a y-coordinate of 80.0, so you need to initialize maxPlayerY to 80 if you don’t want to give the player 80 points just for starting the game. ;]

Add the following line to init(size:) in GameScene.swift, just after the line that sets the background color:

// Reset
maxPlayerY = 80

To increase the score when the player travels up the screen, go to the top of update:, and add the following lines:

// New max height ?
// 1
if Int(player.position.y) > maxPlayerY! {
  // 2
  GameState.sharedInstance.score! += Int(player.position.y) - maxPlayerY!
  // 3
  maxPlayerY = Int(player.position.y)           
  // 4
  lblScore.text = String(format: "%d", GameState.sharedInstance.score)
}

This deserves closer inspection:

  1. First, you check whether the player node has travelled higher than it has yet travelled in this play-through.
  2. If so, you add to the score the difference between the player node’s current y-coordinate and the max y-value.
  3. You set the new max y-value.
  4. Finally, you update the score label with the new score.

Build and run, and tap to start. As you play, your score will go up as you move higher through the level.

25-HUDPointsFromY

Now consider the star count. You need to increment it every time the player node collides with a star, so open GameObjectNode.swift, and add the following code to collisionWithPlayer within StarNode, just after the line that awards the points:

// Award stars
GameState.sharedInstance.stars! += (starType == .Normal ? 1 : 5)

That’s all that needs doing! Build and run, and tap to start. Watch the star count increase as you collect them.

26-HUDStars

As you play, you may notice that when you fall, all the game objects you passed are still in the game. “Hey!” you are surely thinking “I spent a considerable amount of time with Mega Jump, and I am sure that’s not how it was in that game!” Yes, but that’s easy to fix.

Recall that you added a method named checkNodeRemoval to GameObjectNode that checks whether or not to remove a node. It’s now time to call that method every frame.

Add the following code to update in GameScene.swift, just before the line that checks if the player node’s position is greater than 200:

// Remove game objects that have passed by
foregroundNode.enumerateChildNodesWithName("NODE_PLATFORM", usingBlock: {
  (node, stop) in
  let platform = node as! PlatformNode
  platform.checkNodeRemoval(self.player.position.y)
})

foregroundNode.enumerateChildNodesWithName("NODE_STAR", usingBlock: {
  (node, stop) in
  let star = node as! StarNode
  star.checkNodeRemoval(self.player.position.y)
})

Here you enumerate through the platforms in the foreground node and call checkNodeRemoval for each one. You then do the same for each of the stars.

Build and run, and tap to start. Now when you fall, it’s nothing but empty sky!

27-RemoveOldGameNodes

Michael Briscoe

Contributors

Michael Briscoe

Author

Over 300 content creators. Join our team.