Skip to main content

Triblast

Let's create a powerup that gives the player a triple shot for a limited duration. To do this, we are going to use a unique Easel feature called buffs. Buffs are a way for one entity to temporarily modify another, and are often used to create short-lived effects like speed boosts, temporary invincibility, or in this case, a triple shot.

Triblast effect

To create the triblast effect, we are going to add a buff that temporarily increases the number of plasma bolts that are fired when the player presses Spacebar.

Select your ship.easel file. Insert the following highlighted code at the very top, before your Ship function.

pub buff ship.NumPlasmaBolts = 1

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

We want the three bolts of triblast to spread out slightly. To achieve this, let's add a headingOffset parameter to the plasma bolt function so we can tell it to spread out.

Select your plasmaBolt.easel file. Go to your PlasmaBolt function, find the function signature (the first line) and add a headingOffset=0 parameter to the parameter list, just after your ship parameter. You will need to add a preceding comma because the parameter list is comma-separated. Once you are done, your line should look like the following:

pub fn projectile.PlasmaBolt(ship, headingOffset=0, [owner]) {
// ...
}

Now let's change the initial velocity of the plasma bolts to respect the new headingOffset parameter.

In plasmaBolt.easel, replace the velocity parameter of your Body function call with the following highlighted code:

pub fn projectile.PlasmaBolt(ship, headingOffset=0, [owner]) {
use body=projectile
use speed=50, radius=0.25
use color=#ffffff, ownerColor=true
use luminous=1, layer=-5

Body(
pos = ship.Pos,
velocity = speed * Direction(ship.Heading + headingOffset),
bullet=true,
)

// ...
}

Now let's make the ship fire multiple plasma bolts. We will do this by placing the plasma bolt spawning code inside a for loop, which is one way to make a block of code repeat multiple times.

Select your ship.easel file. Modify your Ship function as follows. You will need to replace the code that was previously there and replace it with the highlighted code.

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

on ButtonDown(KeySpacebar) {
CommenceGame

const AnglePerBolt = 0.03rev
let initialAngle = -(AnglePerBolt * (NumPlasmaBolts - 1)) / 2
for i in Range(0, NumPlasmaBolts) {
Spawn projectile {
PlasmaBolt(ship=, headingOffset = initialAngle + i*AnglePerBolt)
}
}
await Tick(0.1s)
}
}
info

The for loop allows us to repeat a block of code multiple times. It is common to combine a for loop with a Range or RangeInclusive to repeat a calculation over a range of numbers.

We haven't yet created the triblast powerup. We will do that next.

Triblast powerup

We will need a triblast powerup which the player can pickup to activate the upgrade. To create a short-lived effect in Easel, you spawn a short-lived entity, and so that is what we will do. We will create an entity that only lives for 5 seconds, and only while it is alive, it will give the player the triblast effect.

Create a new file called triblast.easel, and fill it with the following code:

pub fn powerup.TriblastPowerup {
use body=powerup
use radius=0.9, speed=10, luminous=1

Body(
pos = (BoundaryRadius + radius + 5) * RandomVector,
velocity = speed*RandomVector,
)

PolygonSprite(shape=Circle, color=#00ffaa, opacity=0.5, bloom=3, shadow=0.5)
ImageSprite(@triblast.svg, radius=0.85*radius)
PolygonCollider(shape=Circle, category=Category:Powerup, collideWith=Category:None, sense=Category:Ship, density=1)
RecoverSpeed
DecayTurnRate

WrapOutsideBoundary

on BeforeCollide that {
if that.Category.Overlaps(Category:Ship) {
use ship = that

ship.Subspawn effect {
once Tick(5s) { Expire }

NumPlasmaBolts(3)

BottomLeftContent {
HStack(padding=1) {
Pip(backgroundColor=#dd00ff) { Image(@triblast.svg, height=2, shadow=0.5) }
"You wield the mighty Triblast!"
}
}
}
Expire
break
}
}
}

Next we need to insert the image file used for the triblast powerup. Insert the following file into your project. Right click then Save link as..., then drag-drop it into the file list of your project.

Finally, we need to spawn the Triblast powerup. For testing, let's replace the Shield powerup with the Triblast powerup. We will add the Shield back later.

Select your main.easel file. In your Main function, replace the ShieldPowerup with TriblastPowerup with the highlighted code below.

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

once AfterGameCommenced {
// ...

behavior<spawnPowerups> with Tick(5s) {
if !QueryAny(filter=Category:Powerup) {
Spawn powerup {
TriblastPowerup
}
}
}
}

// ...
}

Click Preview. You should soon see a Triblast powerup appear. Catch the powerup and start firing your weapon to see the triple shot effect in action.

info

The NumPlasmaBolts buff controls how many plasma bolts are fired. The key problem is, we only want to temporarily set NumPlasmaBolts to 3, and then we want it to revert back to 1 after 5 seconds. How do we achieve this?

To answer this, let's look at this snippet from triblast.easel:

pub fn powerup.TriblastPowerup {
// ...

on BeforeCollide that {
if that.Category.Overlaps(Category:Ship) {
use ship = that

ship.Subspawn effect {
once Tick(5s) { Expire }

NumPlasmaBolts(3)

// ...
}
Expire
break
}
}
}

Take note of a few things:

  • ship.Subspawn effect spawns a new entity called effect
  • once Tick(5s) { Expire } causes effect to live for only 5 seconds
  • NumPlasmaBolts(3) sets the NumPlasmaBolts buff to 3. However, because NumPlasmaBolts is a buff, it only does this temporarily. NumPlasmaBolts(3) actually adds a component to the effect entity. That is why when effect despawns, NumPlasmaBolts(3) gets removed and the value of NumPlasmaBolts reverts back to 1.

This unique behavior happens only because NumPlasmaBolts was declared as a buff. This would not happen if it were declared as a field or prop.

Buffs are a powerful way to temporarily modify entities, and can often be used to implement temporary speed boosts, damage buffs, stuns, slows or other short-lived effects. These effects are so common in games that Easel has this feature built in. For more detail, see buffs.

Randomly choosing between powerups

Let's make it so that either a triblast or shield powerup appears randomly.

In main.easel, within your Main function, replace the code inside Spawn powerup with the highlighted code below:

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

once AfterGameCommenced {
// ...

behavior<spawnPowerups> with Tick(5s) {
if !QueryAny(filter=Category:Powerup) {
Spawn powerup {
surprise {
ShieldPowerup,
TriblastPowerup,
}
}
}
}
}

// ...
}
info

A surprise block is a way to randomly choose between multiple options. In this case, we are randomly choosing between a ShieldPowerup and a TriblastPowerup. You can even give different weights to each potential option - see surprise to learn more.

Click Preview and start playing. You should see either a Triblast or Shield powerup appear. Try exiting and re-entering the game a few times to see different powerups appear.