Add the Continue Game Feature (Player Reward)

In Creating an Ad Unit for Rewarded Ads, you set up a rewarded ad unit that serves video ads to Gloop Drop. The idea is that when players watch one of these ads, they’ll earn a reward: the ability to continue their game. At the moment, though, this Continue Game feature doesn’t yet exist, so you’ll need to build it, starting with a few tweaks to the UI.

Adding a Start Button

Open the Assets.xcassets asset catalog and create a new sprite atlas named game_ui. Copy the three image files—[email protected], [email protected], and [email protected]—from the resources/game_ui folder into the newly created sprite atlas. (Don’t forget to delete the default Sprite image set.)

With the new sprite atlas in place, you’re ready to add a new sprite node. Open the GameScene.swift file and add the following property for the Start button sprite:

 // Start game button
 let​ startGameButton = ​SKSpriteNode​(imageNamed: ​"start"​)

Next, you need to create a few methods to set up the sprite node and handle the actions to show and hide the button. Below the setupLabels() method, add the following new methods:

 func​ ​setupStartButton​() {
  startGameButton.name = ​"start"
  startGameButton.​setScale​(0.55)
  startGameButton.zPosition = ​Layer​.ui.rawValue
  startGameButton.position = ​CGPoint​(x: frame.midX, y: frame.midY)
 addChild​(startGameButton)
 
 // Add animation
 let​ scaleUp = ​SKAction​.​scale​(to: 0.55, duration: 0.65)
 let​ scaleDown = ​SKAction​.​scale​(to: 0.50, duration: 0.65)
 let​ playBounce = ​SKAction​.​sequence​([scaleDown, scaleUp])
 let​ bounceRepeat = ​SKAction​.​repeatForever​(playBounce)
  startGameButton.​run​(bounceRepeat)
 }
 
 func​ ​showStartButton​() {
  startGameButton.​run​(​SKAction​.​fadeIn​(withDuration: 0.25))
 }
 
 func​ ​hideStartButton​() {
  startGameButton.​run​(​SKAction​.​fadeOut​(withDuration: 0.25))
 }

The actions in the first method give the Start button a sort of pulse-like animation. The fade actions in the other two methods keep the Start button from appearing too abruptly.

While you’re here, scroll down a little to the showMessage(_:) method. Locate the following line of code:

 messageLabel.position = ​CGPoint​(x: frame.midX, y: player.frame.maxY + 100)

and change it to this:

 messageLabel.position = ​CGPoint​(x: frame.midX,
  y: frame.midY + startGameButton.size.height/2)

If you skip this change, the Start button and the message label would overlap—you can’t have that, now, can you?

The next step is to update the didMove(to:) method so that it calls the newly created setupStartButton() method.

Scroll up until you see the didMove(to:) method (or use the jump bar), and find the comment // Set up User Interface. Below that comment, and after the call to setupLabels(), add the following code:

 setupStartButton​()

Build and run the project and you’ll see the Start button pulsating just below the text.

images/UsingAdsToIncreaseRevenue/ads-build-02.png

You may have noticed that the Start button doesn’t work correctly. It also doesn’t disappear when you start a new game. It’s time to fix that.

In the spawnMultipleGloops() method, below the call to hideMessage(), add the following code:

 // Hide start button
 hideStartButton​()

Now, in the gameOver() method, below the line that reads popRemainingDrops(), add this:

 // Show start button
 showStartButton​()

That change takes care of calling the methods that show and hide the Start button. Now you need to update the touch method to handle when the player taps the button.

Locate the touchDown(atPoint:) method and update it to match the following:

 func​ ​touchDown​(atPoint pos: ​CGPoint​) {
 let​ touchedNodes = ​nodes​(at: pos)
 for​ touchedNode ​in​ touchedNodes {
 // print("touchedNode: (String(describing: touchedNode.name))")
 if​ touchedNode.name == ​"player"​ && gameInProgress == ​true​ {
  movingPlayer = ​true
  } ​else​ ​if​ touchedNode == startGameButton && gameInProgress == ​false​ {
 spawnMultipleGloops​()
 return
  }
  }
 }

This updated method simplifies how touches are handled and now includes a check to see if the touched node is the startGameButton object. If it is, you call spawnMultipleGloops(), and the game starts.

Build and run the project to check it out. If everything works, you’re ready to make the next UI update: adding the Continue and Watch Ad buttons.

Adding the Continue and Watch Ad Buttons

In the Assets.xcassets asset catalog, create a new sprite atlas named continue_game. Copy all of the image files from the resources/continue_game folder into the newly created sprite atlas. (Don’t forget to delete the default Sprite image set.)

Now, open the GameScene.swift file and add the following properties:

 // Continue Game
 let​ watchAdButton = ​SKSpriteNode​(imageNamed: ​"watchAd"​)
 let​ continueGameButton = ​SKSpriteNode​(imageNamed: ​"continueRemaining-0"​)
 let​ maxNumberOfContinues = 6
 var​ numberOfFreeContinues: ​Int​ = 0
 
 var​ isContinue: ​Bool​ = ​false

You’ll use these properties to create the new sprites and to help maintain the status of the player’s continues.

Next, you’ll be adding an extension to the GameScene class that handles the Continue Game functionality. Although this isn’t a requirement, it helps to keep things organized and focused.

Scroll all the way to the bottom of the GameScene.swift file and add the following block of code:

 extension​ ​GameScene​ {
 func​ ​setupContinues​() {
  watchAdButton.name = ​"watchAd"
  watchAdButton.​setScale​(0.75)
  watchAdButton.zPosition = ​Layer​.ui.rawValue
  watchAdButton.position = ​CGPoint​(x: startGameButton.frame.maxX + 75,
  y: startGameButton.frame.midY - 25)
 addChild​(watchAdButton)
 
  continueGameButton.name = ​"continue"
  continueGameButton.​setScale​(0.85)
  continueGameButton.zPosition = ​Layer​.ui.rawValue
  continueGameButton.position = ​CGPoint​(x: frame.maxX - 75,
  y: ​viewBottom​() + 60)
 addChild​(continueGameButton)
 
 updateContinueButton​()
  }
 
 func​ ​updateContinueButton​() {
 if​ numberOfFreeContinues > maxNumberOfContinues {
 let​ texture = ​SKTexture​(imageNamed: ​"continueRemaining-max"​)
  continueGameButton.texture = texture
  } ​else​ {
 let​ texture = ​SKTexture​(imageNamed:
 "continueRemaining-​​(​numberOfFreeContinues​)​​"​)
  continueGameButton.texture = texture
  }
  }
 }

There’s a lot going on here, but nothing you haven’t seen before.

Finally, in the in the didMove(to:) method, below the line that reads setupStartButton(), add a call to setupContinues(), like so:

 setupContinues​()

Build and run the project and you’ll see two new buttons, as shown in the image.

images/UsingAdsToIncreaseRevenue/ads-build-03.png

Excellent, you’re ready to implement the methods that handle continuing the game.

Continuing the Game

With the GameScene.swift file still open, go to the GameScene extension at the bottom of the file. Below the updateContinueButton() method, add the following new method:

 func​ ​useContinue​() {
 if​ numberOfFreeContinues > 0 {
  isContinue = ​true
  numberOfFreeContinues -= 1
 spawnMultipleGloops​()
  }
 }

You’ll call this new method when the player taps the Continue button. Notice that it first checks to make sure the player has at least one continue before setting isContinue = true and calling spawnMultipleGloops(). It also decrements the numberOfFreeContinues by 1.

Now, jump to the spawnMultipleGloops() method and locate the following code:

 // Reset the level and score
 if​ gameInProgress == ​false​ {
  score = 0
  level = 1
 }

and replace it with this:

 // Reset the level and score
 if​ gameInProgress == ​false​ && isContinue == ​false​ {
  score = 0
  level = 1
 } ​else​ {
  isContinue = ​false
 }

Thanks to this change, when the player continues the game, the score and level are not reset.

You now need to update how touches are handled. Jump to the touchDown(atPoint:) method and update it to match this:

 func​ ​touchDown​(atPoint pos: ​CGPoint​) {
 let​ touchedNodes = ​nodes​(at: pos)
 for​ touchedNode ​in​ touchedNodes {
 // print("touchedNode: (String(describing: touchedNode.name))")
 if​ touchedNode.name == ​"player"​ && gameInProgress == ​true​ {
  movingPlayer = ​true
  } ​else​ ​if​ touchedNode == watchAdButton && gameInProgress == ​false​ {
 // TODO: Add call to gameSceneDelegate?.showRewardVideo()
 return
  } ​else​ ​if​ touchedNode == continueGameButton && gameInProgress == ​false​ {
 useContinue​()
 return
  } ​else​ ​if​ touchedNode == startGameButton && gameInProgress == ​false​ {
 spawnMultipleGloops​()
 return
  }
  }
 }

Finally, give the player one free continue. Go back to the properties section and modify the numberOfFreeContinues property to match this:

 var​ numberOfFreeContinues: ​Int​ = 1 {
 didSet​ {
 updateContinueButton​()
  }
 }

This update gives the player one free continue and automatically calls the updateContinueButton() method whenever the value changes. The updateContinueButton() is what is responsible for changing the texture of the Continue button sprite to match the number of continues available.

Build and run the project. Score a few points and then lose the game. Instead of starting a new game, tap the Continue button to keep playing.

images/UsingAdsToIncreaseRevenue/ads-build-04.png

Update the Message Text

images/aside-icons/info.png

At this point, you may want to update the calls to showMessage(_:) to make them more in line with the UI updates. For example, showMessage("Game Over Start a New Game or Continue") in gameOver() and showMessage("Tap Start to Play the Game") in didMove(to:).

Now that you’ve got the Continue Game functionality in place and working, you’re ready to implement the rewarded ads—and for that, you’ll use the AdMob helper file again.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset