Scoring
Many games have some sort of scoring system, where the player gains points for doing certain things in the game. This gives players a way to compare their mastery with other players. Let's give our player points for blowing up asteroids!
Creating a property to hold the score
To begin, we will create a property called Score to hold the player's score.
Create a new file called scores.easel. Copy-and-paste the following code into it:
pub prop owner.Score = 0
We are using a property because when a property changes, it sends signals which we can use to trigger other behaviors, like updating the score display.
Increasing the score
Now we will modify the laser to give the player 10 points every time it hits an asteroid.
Select laser.easel. Insert the following highlighted code into your Laser function:
pub fn projectile.Laser([unit, owner]) {
// ...
on Paint {
Streak(color=, radius=, dissipate=0.05s, bloom=2, bloomAlpha=1, glare=1, shadow=0.5)
}
once BeforeCollide that {
Strobe(shine=1, dissipate=0.5s)
repeat 5 { Spark(color=, radius=, shine=0.5, splatter=1, dissipate=0.5s) }
if that.Category.Overlaps(Category:Asteroid) {
that.ApplyDamage(10)
Score += 10
}
Expire
}
once Tick(1.5s) { Expire }
}
The += operator, known as the compound assignment operator, is a shorthand way to update a variable by adding a value to it.
See Assignments to learn more.
Displaying the score
We want to display the score on the screen so the player can see it increasing as they blow up asteroids.
To do this, we will create a ScoreSystem which we will later add to each player.
Creating the ScoreSystem
The ScoreSystem will display the player's score at the top of the screen.
Select your scores.easel file. Insert the following highlighted code into it:
pub prop owner.Score = 0
pub fn owner.ScoreSystem() {
TopContent {
H1 { %(Score) }
}
}
TopContent is a component that displays user interface content at the top of the screen.
Using ScoreSystem
Each player now needs their own ScoreSystem to see their own score.
Select main.easel. Insert the following highlighted code into your Main function:
pub game fn World.Main() {
// ...
SpawnEachPlayer owner {
ScoreSystem
await Subspawn unit {
Ship
}
Subspawn dialog {
GameOverDialog
}
}
// ...
}
// ...
Click Preview. You should see at the top of the screen is a big 0 representing your score.
Now blow up some asteroids. You should notice that something is wrong. Your score is not increasing!
Updating the score
The reason the score is not changing is that we forgot to tell our ScoreSystem to update whenever the score changes.
To do this, we need to use a with block.
Select scores.easel. Find the TopContent block and replace its contents with the following highlighted code snippet:
pub prop owner.Score = 0
pub fn owner.ScoreSystem() {
TopContent {
with Score {
H1 { %(Score) }
}
}
}
Click Preview again and blow up some asteroids. Now you should see your score increasing!
The with Score { ... } block runs its code block once, and reruns it again every time the Score property changes.
This makes sure the score display is always up-to-date!
Displaying instructions
When the player is on 0 points, we should explain to them what they need to do in order to get points.
Select scores.easel. Find the with Score block and replace its contents with the following highlighted code snippet:
pub prop owner.Score = 0
pub fn owner.ScoreSystem() {
TopContent {
with Score {
if Score > 0 {
H1 { %(Score) }
} else {
InsetPanel {
P {
Span(bold=true, color=#0f0) { "Arrow Keys" }
" to move, "
Span(bold=true, color=#0f0) { "Click" }
" to fire"
}
}
}
}
}
}
Click Preview. When you first enter the game, you should now see instructions at the top of the screen instead of a 0.
Blow up some asteroids, and you should see the instructions get replaced by your score!
Recap
In this chapter, you added scoring mechanics to your game!
You created a Score property to hold the player's score, and
you used Easel's user interface system to display the player's score on the screen.
Then you used a with block to keep the score display updated.
In Easel, you always use a with block whenever you need to synchronize a view (the score display) with a state (the Score).
The with block is an example of Reactive Programming,
a programming model where you say what code depends on what state,
and then the engine automatically re-runs the code that depends on that state whenever it changes.
See Reactive Programming to learn more about
this style of programming which is fundamental to writing games in Easel.