Anila v0.04 - Devlog - Enemies Explosion

Hello Pico Devs,

Yes, the latest devlog entry is from more than 1 year and a half, and today I'll show you how I did the explosion on the enemies.

Now that Anila can shoot, she must have some enemies to defeat. So after defining a small collision area on her fireball and a larger one for the green enemies, I used a "simple" function to draw some geometry. In our case it's a colored circle.

I have created a tab dedicated to what I call "system functions". In this tab I wrote every game system related functions. The idea was to have a general tab for all general functions, or functions that will be reused by more than a single actor.
For instance, I put the fireball function in there, the animation formula as well as the explosion.

Create, Update, Draw... and repeat

This is the basic workflow in Pico8. So here is some code for a nice looking explosion:


function create_explosion(xpos,ypos,tmax)
     add (explosions,{x=xpos,

Notice that I use line returns. It's not mandatory, but I do so to keep it more organized and cleared. Keep in mind that at a certain level, coding in Pico8 becomes a game of optimization where every character counts in the limitation. Killers dev accepted the challenge and eventually created Celeste, the Classic version.
Yup, in case you didn't know, indie hit Celeste began as a Pico8 game. And maybe one (if not the) of the most optimized game of the fantasy console. I'm digressing so let's get back to our explosions:
- xpos and ypos will be passed when the function will be called: it will be the cller's coordinates, ie the monster's position.
- tmax is used to define the length of the explosion, and possibly have control over it.
- one way to improve this would be to also pass a radius variable, so for smaller enemies, we could have called a smaller explosion.


function update_explosions()
     for e in all (explosions) do
         if e.t>e.tmx then

Remember that update functions are called at each frame. So, at each frame, we'll add +1 to t (for time) and that will basically define the explosion's life time. We defined tmx as tmax or Time Max at 5 when creating the explosion. So the explosion will last for 5 frames.
It will delete itself if it's time is superior to the max time we defined.


I'm drawing two shapes: A filled disc for the core of the explosion and a larger circle for outlining a little more.

function draw_explosions()
     for e in all (explosions) do

The functions circ and circfill are ones of Pico8s built-in functions and work as follows:

circfill( x, y, [r,] [col]  )

x and y correspond the filled circle's position coordinates. I added an offset of +4 on the x and +8 on the y because the reference point of a sprite is the upmost left pixel (and not the center).

r = e.t/0.7

r is the radius of the circle. As this is an animation, the radius is getting bigger over time to makeit look like an explosion (kinda).
I used the time value of the circle, divided by 0.7 to have a result I deemed satisfying. I settled to 0.7 after testing various values.

col = 11+e.t%2

col is the color of the circle. In order to add a little more juice, I made the color change over time as well.
in my example, 11 is the starting color in Pico8 colors grid. Then I add time modulo 2 (+e.t%2) to adjust how long each color will last before switching to the next.

[NOTE]: Incrementing the color value by 1 will cycle the colors as they appear on the color grid. it means we don't have control on the colors display order. One way to fix that though would be to write another function with a variable incremented over time. That variable would not sync directly to the color palette index, but would assign the color we want instead. That way we could cycle the colors in any order we want.

Calling the explosion

Besides my System Functions tab, I made a Monster tab in which I write all monster's relative functions. Pretty obvious, huh?
I have a for loop for all monsters (or more precisely, for all actors belonging to the monster group) in which I call recurrents event like collisions, collisions with the fireball,  sprite index management for animation and most importantly, what happens upon death, when hp is equal or lower than 0.
It's there that I call the create_explosion function, assigning it the monster's x and y coordinates. I also play an explosion sfx then I delete the monster.

--destruction when death
         if n.hp<=0 then
             del (monsters,n)

Hopefully that helps! Share your ideas, improvements or your own tips in the comments!

Leave a comment

Log in with to leave a comment.