Skip to main content

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 {
P {
Span(bold=true, color=#00ff00) { "Click" }
" to accelerate, and press "
Span(bold=true, color=#00ff00) { "Spacebar" }
" to fire"
}
}
}
}

// ...
}

// ...
}
info

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)
}

Print(audience=Audience:All) {
P {
PlayerNameDisplay
"'s ship disintegrates into space dust"
}
}

Expire
break
}
}
}
info

The built-in Print function displays a temporary message on the screen for a given duration. Normally, user interface content like Print 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".

Intangible 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. To give players time to learn the controls, let's make the ship intangible until the player presses a key.

We will do this by adding a Property called IsReadyToPlay on the ship, which other parts of the code can respond to.

Adding the property

Add a IsReadyToPlay signal by selecting the ship.easel file and adding the following highlighted snippet at the very top of your file, before everything else:

prop ship.IsReadyToPlay = false

pub fn ship.Ship([owner]) {
// ...
}

Setting the property

Now we need to set IsReadyToPlay = true 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) {
IsReadyToPlay = true

Spawn projectile {
PlasmaBolt(ship=)
}
await Tick(0.1s)
}

// ...
}

Disabling collisions until ready

Now let's disable collisions on our PolygonCollider until IsReadyToPlay is true.

Select your ship.easel file. In your Ship function, find the PolygonCollider line and replace it with the following snippet:

pub fn ship.Ship([owner]) {
// ...

ImageSprite(@spaceshipBody.svg, ownerColor=true, shading=0.25, shadow=0.5)
ImageSprite(@spaceshipWindow.svg, color=#ffffff, shading=0.25)

with IsReadyToPlay {
PolygonCollider(
shape=Circle, category=Category:Ship, density=1,
collideWith = IsReadyToPlay ? Category:Tangible : Category:None,
)
}

LimitSpeed(maxSpeed=30)
DecayTurnRate

WrapOutsideBoundary

// ...
}

Click Preview. Resist the urge to fire your plasma bolts, and instead try intentionally flying into an asteroid. You won't die!

info

The with IsReadyToPlay block executes once, and then again every time IsReadyToPlay changes. This allows us to first setup the collider, then update it when conditions change. See Behaviors to learn more about with blocks.

The ? operator is called the ternary operator and allows you to choose between two values based on a condition.

Flashing when intangible

We don't want to confuse a new player into thinking they are intangible all the time. Let's add some visual signals to distinguish the initial intangible state from the normal state. This is commonly done in games by making the character flash.

Select your ship.easel file. Insert the following highlighted snippet just above the with IsReadyToPlay block that you just added previously:

// ...
pub fn ship.Ship([owner]) {
// ...

ImageSprite(@spaceshipBody.svg, ownerColor=true, shading=0.25, shadow=0.5)
ImageSprite(@spaceshipWindow.svg, color=#ffffff, shading=0.25)

behavior<flashing> on Tick(0.5s) {
Strobe(fade=0.5, dissipate=0.25s)
}
once IsReadyToPlay {
delete behavior<flashing>
}

with IsReadyToPlay {
PolygonCollider(
shape=Circle, category=Category:Ship, density=1,
collideWith = IsReadyToPlay ? Category:Tangible : Category:None,
)
}

LimitSpeed(maxSpeed=30)
DecayTurnRate

// ...
}

Click Preview. You should see your ship flashing when you start the game, indicating that you are intangible. Start shooting plasma bolts, and the shield will disappear, along with your invincibility. Now players can take their time to learn the controls before jumping into the action.

info

A once block executes its code exactly once when it receives a signal, in this case after IsReadyToPlay has been changed. See Behaviors to learn more.

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.

tip

If you are using Google Chrome, you will be asked to choose where to save your project. This is what we recommend:

  1. Go to your Documents folder
  2. Create a new folder called Easel Projects, and go into that folder.
  3. 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.