MelonJS Space Invaders

MelonJS is one of several HTML5/Javascript game engines available, and it’s actually not too difficult to work with. There’s some really good documentation at as well as two very good game tutorials. There’s a platformer tutorial here, but the retro gamer in me was really drawn to the space invaders tutorial. I was worked through the space invaders tutorial as part of a “coding carnival” at work – basically a coding challenge that had the goal to implement one of three classic video games. I wanted to do the space invaders type game, so I selected that option.

When you finish the MelonJs space invaders tutorial, you have barely playable game. The player can shoot at the ever-encroaching invaders, and rack up points for enemy kills, but there’s not much more than that. Obviously this is the point of the tutorial – get the game developer to a point where they have created a really basic game, and provide them with the basic building blocks to be able to take their game to the next level.

After completing the space invaders tutorial, the first thing I wanted to add was enemy fire. In the basic tutorial, invaders moved as an implacable force down the screen toward the player, but they didn’t actually shoot at the player. Before I could do that, I found that I needed to alter the player object so that it extended the me.Entity object rather than the me.Sprite object that’s provided in the tutorial. This would allow my new Enemy_Laser objects to be able to collide with the player.

In addition, I wanted to use some of the original imagery and sounds from the classic Taito Space Invaders game, so I Googled until I found the resources I wanted. Afterwards, I used Photoshop to create sprite images for the invaders as well as the player. I was able to add sound effects that were sampled from the original game, and I found that this was definitely taking me in the right direction.

Once I had the enemies shooting back at the player, I needed a way to throttle the enemy fire. While working through this, I introduced something that I’ll call the alien rain of death by virtue of using one equal sign in a conditional test rather than two. Remember kids, when you say something like this:

if (myVariable = someValue)

in Javascript, you’re doing an assignment of someValue to myVariable, and the return value is ALWAYS TRUE. So, if you do that in a while loop, it will never end. And if that loop is spawning enemy fire, well … you are completely screwed.

One of the things I found was that MelonJS provides audio features, but you have to be careful where/when you play a looping track.

For example, when I added the mothership, I wanted the audio file “ufo_highpitch” to play while the ship was on-screen. It turns out that you need to place the looping audio track following your animated sprite. For example:

Another thing I realized was that I would be easier to accumulate player shots and use this counter to trigger the spawning of the Mothership rather than using a timer. I created a MotherShipContainer class to manage spawning and reaping mothership instances, and I initially thought I could use a me.timer method to control when to spawn the Motherships. This approach was really wonky, and led to fantastically weird results. So instead, I decided to accumulate player shots, and use this as a way to spawn Mothership inastances.

The code for the accumulator and how it was used is below:

Here, notice the accumulate functuion. This is simply incrementing a counter every time the player shots. Then, in the update() method, the shotCount is compared to the randomly-selected threshold value. If we hit that value, then we spawn a MotherShip. Notice in the spawnMotherShip method, I reset the shot counter as well as the threshold value.

There’s plenty more to discuss about this game, so I’ll tackle these additional findings in future posts. For example, I had fun trying to figure out collision detection, and I’m sure there are things I can do to improve the HUD and UI.

Oh yeah, you can play my version of Space Invaders here. If you’re interested in the source code, you can find it here on GitHub.