Skip to main content

Game Over

Games often have end conditions, such as the player losing all their lives or completing all levels. In our case, when the player loses their ship, the game is over. Let's add a game over screen to indicate this to the player.

Creating the game over screen

First let's create the game over screen. To do this, we are going to use Easel's declarative user interface system.

Switch to main.easel, and insert the highlighted code snippet at the bottom of your file, after your Main function:

pub game fn World.Main() {
ImageSprite(body=@(0, 0), image=@backdrop.png, radius=7, repeatX=100, repeatY=100, layer=-100)
Camera(@(0,0), radius=BoundaryRadius)
Viewport(aspectRatio=1)

ButtonRemap(KeyW, ArrowUp)
ButtonRemap(KeyA, ArrowLeft)
ButtonRemap(KeyS, ArrowDown)
ButtonRemap(KeyD, ArrowRight)

SpawnEachPlayer owner {
Subspawn unit {
Ship
}
}

AsteroidFieldSystem
}

fn dialog.GameOverDialog([owner]) {
OverlayContent {
VStack(align=Align:Center) {
H1(fontSize=5) { FlyInWords("Game Over") }

HStack(align=Align:Center, animate=Animate:FlyFromBottom) {
RaisedButton(Main, backgroundColor=Color:Primary, expand=true) { "Play Again" }
}
}
}
}

We are not done yet, so just preview your game to make sure you have not made any syntax errors before moving on.

info

OverlayContent is a component that displays user interface content in the middle of the screen, on top of the game.

Showing the game over screen

Now, we want to show the game over dialog when the player's ship is destroyed.

Now, insert the highlighted code snippet just after the await Subspawn unit block, like so:

pub game fn World.Main() {
// ...

SpawnEachPlayer owner {
Subspawn unit {
Ship
}

Subspawn dialog {
GameOverDialog
}
}

// ...
}

fn dialog.GameOverDialog([owner]) {
// ...
}

Click Preview and you will see something is wrong. As soon as we enter the game, the game over dialog appears! This is because we are not waiting for the ship to be destroyed before showing the dialog.

info

We are using the name dialog for this entity because its main role is to display a dialog to the player. The name dialog means nothing to Easel itself, this is just a naming convention. See Roles to learn more.

Waiting for the ship to be destroyed

Select main.easel. Find the line Subspawn unit and change it to await Subspawn unit so it looks like this:

pub game fn World.Main() {
// ...

SpawnEachPlayer owner {
await Subspawn unit {
Ship
}

Subspawn dialog {
GameOverDialog
}
}

// ...
}

fn dialog.GameOverDialog([owner]) {
// ...
}

Click Preview and try crashing into asteroids until your ship is destroyed. You should see a game over message appear.

info

When you use await Subspawn rather than Subspawn, the code will pause at that line until the spawned entity is destroyed. See Subspawn and await for more details.

Recap

In this chapter, you made a game over screen! To do this, you used Easel's declarative user interface system to create a dialog that appears in the middle of the screen.

To display the game over screen at the right time, you had to use await to wait for the player's ship to be destroyed before showing the dialog.

info

The await keyword lets you write code that executes a sequence of steps line by line, even when sometimes a long wait is needed before continuing to the next line. See Asynchronous Programming to learn more this style of programming.

Lesson: User Interfaces

Let's take one more look at our GameOverDialog:

fn dialog.GameOverDialog([owner]) {
OverlayContent {
VStack(align=Align:Center) {
H1(fontSize=5) { FlyInWords("Game Over") }

HStack(align=Align:Center, animate=Animate:FlyFromBottom) {
RaisedButton(Main, backgroundColor=Color:Primary, expand=true) { "Play Again" }
}
}
}
}
  • Line 2: When you want to display content in the user interface, you first start with a section, like OverlayContent, to determine where on the screen you want to display your content. Other common sections include Content, TopContent, BottomContent, and Toolbar. See the UI sections reference for the full list of sections available to you.

  • Lines 3 and 6: Inside a section, you can use layout elements like VStack and HStack to arrange your content vertically or horizontally, if the default layout does not match what you want.

  • Lines 4 and 7: Add content elements like H1 and RaisedButton to display text and buttons. The UI elements reference lists most of the elements available for you to use.