Packaging It Up
We've now got a playable game loop, so let's complete the beginning and end parts so the game is nicely packaged.
Displaying instructions
It is always a good idea to add some simple instructions to your game so new players know how to play. Let's display instructions instead of a score when the game starts.
Select your main.easel
file. Modify the TopContent
block in your Main
function
to match the highlighted code below.
You will need to delete what is there and replace it with the new code.
pub game fn World.Main() {
SpawnEachPlayer owner {
// ...
TopContent {
with Score {
if Score > 0 {
H1 { %(Score) }
} else {
VStack(align=Align:Center) {
P {
Span(bold=true, color=#00ff00) { "Click" }
" to accelerate, and press "
Span(bold=true, color=#00ff00) { "Spacebar" }
" to fire"
}
}
}
}
}
// ...
}
// ...
}
You will find a complete list of all available user interface elements in the UI Elements section of the reference documentation.
Click Preview and you should see the instructions displayed at the top of the screen. When you start shooting asteroids, the instructions will disappear and your score will be displayed instead.
Announcing deaths
Let's display a message when a player's ship explodes. This helps us create story and emotion in our game, and makes the game more engaging.
Select your ship.easel
file. Insert the following code into your Ship
function,
inside its on BeforeCollide
block:
pub fn ship.Ship([owner]) {
// ...
on BeforeCollide that {
if that.Category.Overlaps(Category:Asteroid) {
repeat 5 {
Spark(color=#ffffff, luminous=1, bloom=3, feather=1, dissipate=0.75s, splatter=1, speed=10)
}
Transmission(audience=Audience:All) {
P {
PlayerNameDisplay
"'s ship disintegrates into space dust"
}
}
Expire
break
}
}
}
The built-in Transmission function
displays a temporary message on the screen for a given duration.
Normally, user interface content like Transmission
is only shown to the owner
player.
We set audience=Audience:All
to make sure that, once we have multiplayer, all players will see the message,
not just the player whose ship exploded.
Click Preview, then collide your ship into an asteroid. You should see a message saying something like "raysplaceinspace's ship disintegrates into space dust".
Invincible until ready
Imagine you are new to this game. You're still figuring out what to do, and then, BOOM! You crash into an asteroid and die. That would be frustrating, right?
Let's make the ship invincible to damage until the player presses a key.
We will do this by sending a Signal called ReadyToPlay
on the ship
.
The ship will wait for this signal before it can be damaged by asteroids.
Adding the signal
Add a ReadyToPlay
signal by
selecting the ship.easel
file and adding the following highlighted snippet at the very top of your file,
before everything else:
signal ship.ReadyToPlay
pub fn ship.Ship([owner]) {
// ...
}
Sending the signal
Now we need to send the ReadyToPlay
signal when the player starts shooting plasma bolts.
Select your ship.easel
file. Insert the two following highlighted snippet into your on ButtonDown(KeySpacebar)
block:
// ...
pub fn ship.Ship([owner]) {
// ...
on ButtonDown(KeySpacebar) {
ReadyToPlay
Spawn projectile {
PlasmaBolt(ship=)
}
await Tick(0.1s)
}
// ...
}
We also want to send ReadyToPlay
when the player clicks the mouse and starts moving around.
Select your ship.easel
file. Insert the following highlighted snippet into the on ButtonDown(Click)
block:
// ...
pub fn ship.Ship([owner]) {
// ...
on ButtonDown(Click) {
ReadyToPlay
behavior<thrust> on BeforePhysics {
const ShipImpulsePerTick = 0.75
ApplyImpulse(ShipImpulsePerTick * Direction(Heading))
}
}
// ...
}
Waiting for the signal
Now let's wait for ReadyToPlay
before we allow the ship to be damaged by asteroids.
Select your ship.easel
file. Insert the following highlighted snippet into the Ship
function:
pub fn ship.Ship([owner]) {
// ...
on ButtonDown(KeySpacebar) {
// ...
}
with Pointer {
// ...
}
await ReadyToPlay
on BeforeCollide that {
if that.Category.Overlaps(Category:Asteroid) {
repeat 5 {
Spark(color=#ffffff, luminous=1, bloom=3, feather=1, dissipate=0.75s, splatter=1, speed=10)
}
Transmission(audience=Audience:All) {
P {
PlayerNameDisplay
"'s ship disintegrates into space dust"
}
}
Expire
break
}
}
}
Click Preview. Resist the urge to fire your plasma bolts, and instead try intentionally flying into an asteroid. You won't die!
Initial shield
We don't want to confuse a new player into thinking they are invincible all the time. Let's add some visual signals to distinguish the initial invincibility from the normal state.
Select your ship.easel
file. Insert the following two highlighted snippets around
the await ReadyToPlay
statement that you just added previously:
// ...
pub fn ship.Ship([owner]) {
// ...
PolygonSprite<initialShield>(shape=Circle(radius=2), opacity=0.25, ownerColor=true, luminous=1, bloom=3, shading=0.1, shadow=0.5, layer=-5)
await ReadyToPlay
delete PolygonSprite<initialShield>
on BeforeCollide that {
// ...
}
}
Click Preview. You should see a purple shield around your ship when you start the game, indicating that you are invincible. Start shooting plasma bolts, and the shield will disappear, along with your invincibility. Now players can take their time to learn the controls.
Save your work
If you haven't already, this would be a good place to save your work. Click the Save icon in the toolbar. This will save your project to a file on your computer, which you can load back into the editor later to continue working on your game.
If you are using Google Chrome, you will be asked to choose where to save your project. This is what we recommend:
- Go to your
Documents
folder - Create a new folder called
Easel Projects
, and go into that folder. - Create a subfolder called
Astroblast
, and choose that folder.
Now any changes you make from this point forward will be autosaved to your Astroblast
folder.
Note that other browsers (e.g. Safari and Firefox) will simply download a copy of your project to your Downloads folder, as autosave is not yet supported in other browsers.