SpriteKit Project — AbsolutelyBrickingIt — Part 10: Add a game over scene
In this article, we’ll show a game over screen when the ball goes out of bounds.
Add image assets
Drag the images needed for the game over scene into the Assets
file in Xcode:
Add the game over scene
Add a new Swift file called GameOverScene
to the project. Add sprite nodes to the scene in the didMove(to view:_)
method as usual:
import SpriteKit
class GameOverScene: SKScene {
override func didMove(to view: SKView) {
let backgroundNode = SKSpriteNode(imageNamed: "background.menu")
backgroundNode.position = CGPoint(x: 0.5 * size.width, y: 0.5 * size.height)
addChild(backgroundNode)
let gameOverNode = SKSpriteNode(imageNamed: "text.game-over")
gameOverNode.position = CGPoint(x: 0.5 * size.width, y: 0.75 * size.height)
addChild(gameOverNode)
let menuNode = SKSpriteNode(imageNamed: "button.menu")
menuNode.position = CGPoint(x: 0.5 * size.width, y: 0.32 * size.height)
addChild(menuNode)
let playNode = SKSpriteNode(imageNamed: "button.play-again")
playNode.position = CGPoint(x: 0.5 * size.width, y: 0.2 * size.height)
addChild(playNode)
}
}
Use a coordinator to handle button taps
We can use a coordinator for the game over scene to pass handling of the button taps back to GameViewController
, just like we have done with all the other scenes so far:
protocol GameOverSceneCoordinator: AnyObject {
func gameOverSceneMenuTapped(_ scene: GameOverScene)
func gameOverScenePlayTapped(_ scene: GameOverScene)
}
class GameOverScene: SKScene {
weak var coordinator: GameOverSceneCoordinator?
private var menuNode: SKSpriteNode?
private var playNode: SKSpriteNode?
override func didMove(to view: SKView) {
..
addChild(menuNode)
self.menuNode = menuNode
..
addChild(playNode)
self.playNode = playNode
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in touches {
let point = touch.location(in: self)
if playNode?.contains(point) == true {
coordinator?.gameOverScenePlayTapped(self)
} else if menuNode?.contains(point) == true {
coordinator?.gameOverSceneMenuTapped(self)
}
}
}
}
Note that references to the menu and play button nodes are kept to handle touches on them.
Add the game over scene to GameViewController
GameViewController
will implement the coordinator methods for the game over scene, presenting the menu scene and the game scene when the corresponding button is tapped:
extension GameViewController: GameOverSceneCoordinator {
func gameOverSceneMenuTapped(_ scene: GameOverScene) {
present(scene: menuScene)
}
func gameOverScenePlayTapped(_ scene: GameOverScene) {
present(scene: gameScene)
}
}
Finally, we can replace the console output from before and present the game over scene in the coordinator implementation for handling the game scene’s game over event:
private extension GameViewController {
...
var gameOverScene: GameOverScene {
let scene = GameOverScene(size: sceneSize)
scene.coordinator = self
scene.scaleMode = .resizeFill
return scene
}
}
extension GameViewController: GameSceneCoordinator {
func gameSceneGameEnded(_ scene: GameScene) {
present(scene: gameOverScene)
}
}
Now we have a game over scene that is presented when the game ends due to the ball going out of bounds. The user can choose to return to the menu or play again from this screen:
Code
This article corresponds to the merge commit Add game over scene (#10)
in the GitHub repository AbsolutelyBrickingIt