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.
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.
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.
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.