Skip to main content

Aliens

Let's add some aliens to the game to make the game even more challenging. Aliens will be much stronger than our hero and will take multiple hits to destroy.

info

Games often need to store various values on each entity, for example the Health of an alien ship. Then, various things in the game need to respond to changes in these values, for example in this case we want the alien ship's graphic to change to show they are losing health. In this section, you will see how we can implement all of this using a prop.

Creating aliens

First, create a category for the aliens.

Select your categories.easel file and insert the highlighted code underneath your other categories:

pub tangible category Category:Ship
pub tangible category Category:Asteroid
pub tangible category Category:Projectile
pub tangible category Category:Shield
pub tangible category Category:Powerup
pub tangible category Category:Alien

Now let's create a function to define the behavior of an alien.

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

pub fn ship.Alien {
use body=ship
use radius=1.5, speed=8, turnRate=0.05rev

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

ImageSprite(@alienShipWindow.svg, color=#ccffcc, overlay=1)
PolygonCollider(shape=Circle, category=Category:Alien, density=1)
RecoverSpeed
RecoverTurnRate

WrapOutsideBoundary

PolygonSprite(shape=Circle(0), bloom=3, color=#66ff00)
ImageSprite(@alienShip.svg, color=#66ff00, shading=0.25, shadow=0.5)

once BeforeDespawn {
repeat 5 {
Spark(color=#ffffff, luminous=1, bloom=3, feather=1, dissipate=0.75s, splatter=1, speed=10)
}
}

on BeforeCollide that {
if that.Category.Overlaps(Category:Projectile) {
Expire
break
}
}
}

Next we need to insert the image file used for the aliens. Insert the following two files into your project. Right click then Save link as..., then drag-drop them both into the file list of your project.

Next let's make aliens spawn.

Select your main.easel file. Insert the following two snippets of highlighted code into your Main function:

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

once AfterGameCommenced {
// ...

behavior<spawnAliens> with Tick(10s) {
const MaxAliens = 2
if QueryCount(filter=Category:Alien) < MaxAliens {
Spawn ship {
Alien
}
}
}
}

once AfterGameConcluded {
delete behavior<spawnAsteroids>
delete behavior<spawnPowerups>
delete behavior<spawnAliens>
}

// ...
}

Click Preview to enter your game, and you should see an alien ship appear.

Alien interactions

If our ship crashes into an alien ship, our ship should explode.

Select your ship.easel file. Modify the following code in your Ship function:

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

on BeforeCollide that {
if that.Category.Overlaps(Category:Asteroid | Category:Alien) {
repeat 5 {
Spark(color=#ffffff, luminous=1, bloom=3, feather=1, dissipate=0.75s, splatter=1, speed=10)
}

// ...
}
}
}

Let's also give the player points each time they shoot an alien.

Select your plasmaBolt.easel file. Modify the following code in your PlasmaBolt function:

pub fn projectile.PlasmaBolt(ship, [owner]) {
// ...

once BeforeCollide that {
Strobe(shine=1, dissipate=0.5s)
repeat 5 { Spark(shine=0.5, splatter=1, dissipate=0.5s) }

if that.Category.Overlaps(Category:Asteroid | Category:Alien) {
Score += 10
}

Expire
}

// ...
}

Click Preview to enter your game. Try shooting at an alien - you should gain points. Crashing into an alien should destroy your ship.

Eratic movement

Aliens should move in an erratic manner to make them somewhat unpredictable. We could do this by making them suddenly change direction every 5 seconds.

Select your alien.easel file. Insert the highlighted lines at the bottom of your Alien function:

pub fn ship.Alien {
// ...

on BeforeCollide that {
// ...
}

on Tick(5s) {
Velocity = Speed * RandomVector // change the alien's direction
}
}

Click Preview and enter the game. You should see the alien suddenly changing direction every 5 seconds.

info

You will see we added a short comment here - // change the alien's direction. Any line or part of a line starting with // is a comment and is ignored by Easel. Comments are good practice to help you remember what your code does, and why you wrote it that way.

Taking multiple hits

Alien ships are much stronger than those of our hero and so we want the aliens to be able to take multiple hits before they are destroyed. To do this, we are going to add a Health property to the alien ships.

Select your alien.easel file. Insert the highlighted code at the very top of your file:

prop ship.Health

pub fn ship.Alien {
// ...
}

Next, let's make the alien ship start with a health of 5,

In alien.easel, insert the highlighted lines into your Alien function:

pub fn ship.Alien {
use body=ship
use radius=1.5, speed=8, turnRate=0.05rev
use maxHealth=5

Health = maxHealth

// ...
}

Now let's reduce the alien's health each time it is hit, until it finally is destroyed.

In alien.easel, within your Alien function, replace contents of your on BeforeCollide block with the highlighted code below:

pub fn ship.Alien {
// ...

on BeforeCollide that {
if that.Category.Overlaps(Category:Projectile) {
Health -= 1
if Health <= 0 {
Expire
break
}
}
}

// ...
}

Click Preview and enter the game. You should find that you need to shoot an alien 5 times before it is destroyed.

Indicating health

We should provide some visual indication that the alien is taking damage so the player knows what is happening. We will do this by changing the color of the alien ship as it loses health.

In alien.easel, modify your Alien function as follows - you will need to remove the ImageSprite and PolygonSprite lines and replace them with the new lines:

pub fn ship.Alien {
// ...

WrapOutsideBoundary

with Health {
await Paint
let proportion = Health / maxHealth
let color = proportion.BlendHue(#ff6600, #66ff00)
PolygonSprite(shape=Circle(0), bloom=3, color=)
ImageSprite(@alienShip.svg, color=, shading=0.25, shadow=0.5)
}

once BeforeDespawn {
// ...
}

// ...
}

Click Preview and enter the game. You should see the alien ship change color as it takes damage.

info

Our with block defines some code that should run each time a prop changes. In this case, each time Health changes we replace the sprites with new ones that are a slightly different color depending on the alien's health. You will often find yourself using with blocks to respond to changes in props.

You might be wondering what the difference is between a field and a prop. The key difference is that you cannot use constructs like a with or on block on a field, as changes to fields are not tracked. Because of this, fields are more efficient than props, so you should opt to use fields whenever you don't need to react to changes.