Friday, 15 November 2013

My games - Choplifter

Note: scroll down to the end of the post to find the link to play the game

After playing one great HTML5 game called Mutant Zombie Monsters, I was left with the desire to experiment with those technologies. However, acknowledging my limited capability in Javascript, I knew I should start with some simple idea, perhaps porting some old game long forgotten, that could benefit from a rebirth in the new world of canvas.

Then one day I was looking for some abandonware to play on DosBox, when I found this lovely game: Airlift Rescue.

You are the pilot of a rescue helicopter. Your mission is to fly to a mid-eastern terrorist compound and rescue 64 hostages that are being held in four separate buildings (16 in each building) and fly them back to American embassy. The terrorists have a seemingly endless supply of tanks, jet fighters and chopper-seeking drones to hinder your success.
I found Airlift Rescue's gameplay to be amazingly original. I knew I had found the game I was looking for!

Armed with my barely sufficing Javascript skills and many W3CSchools tutorials to enlighten my path, I started my quest. This would be my first HTML5 game and my first port of an old game.

One of the first, and most interesting, design decisions I made was to use only vector graphics. And by this I do not mean .svg files or anything of the like. Oh no. This wouldn't be hardcore enough. By this I mean every single graphic in the game is created on real time with nothing but code. Example:

function DrawBomb()
 if(bomb.ready) return;
 var bombX = bomb.x - scrollX;
 var gradient = context.createLinearGradient(0, bomb.y - 5, 0, bomb.y + 5);
 gradient.addColorStop(0, "rgb(128, 0, 0)");
 gradient.addColorStop(0.5, "rgb(202, 64, 96)");
 gradient.addColorStop(1, "rgb(128, 0, 0)");
 context.fillStyle = gradient;
 context.moveTo(bombX - 12, bomb.y);
 context.lineTo(bombX - 12 + 4, bomb.y - 4);
 context.lineTo(bombX + 2, bomb.y - 4);
 context.lineTo(bombX + 5, bomb.y - 1);
 context.lineTo(bombX + 8, bomb.y - 4);
 context.lineTo(bombX + 9, bomb.y - 4);
 context.lineTo(bombX + 9, bomb.y + 4);
 context.lineTo(bombX + 8, bomb.y + 4);
 context.lineTo(bombX + 5, bomb.y + 1);
 context.lineTo(bombX + 2, bomb.y + 4);
 context.lineTo(bombX - 12 + 4, bomb.y + 4);

And this is actually the smallest drawing piece. I manually entered every single context.lineTo, every single coordinate of the graphics. Since I was learning to use canvas as I coded, every function is slightly different in it's intricacies.

In fact, in part I decided to create the graphics in this manner specifically because I was learning while I was coding the game. For a beginner to HTML5 like me, it would be complicated to use raster graphics/sprites.

Also, I did this deliberately to upset my friend Vander, who does pixel art and hates gradients.

This decision did have an interesting consequence: nearly half of the code is for drawing things.

Since I was entering each coordinate manually, and also making small subtle changes to the design, I did a mock-up of the game in Kolourpaint (like MS-Paint but for Linux and better), to aid me in the implementation.

As you can see, one of the alterations I introduced was to exchange the "chopper-seeking droids" for balloons. This droid-thing does not make any sense anyway. In the image below you can see the helicopter being chased by the balloon (and also by some tanks):

So the final game mirrors my ideas very closely, even through it was developed in the "quick & dirt", "workaround-oriented programming" style. The code is a mess. Among other things, every variable is global:

var state; // 0 - Hasn't started yet; 1 - Start new game; 2 - Playng; 3 - Game over
var context;
var frame;
var stars = new Array(50);
var copter = {};
var scrollX = 0;
var house = new Array(4);
var people = new Array(64);
var tank = new Array(4);
var aliveTanks = 0;
var tankIndex = 0;
var plane = {};
var balloon = {};
var pressed = {};
var rescuedPeople = 0;
var peopleAboard = 0;
var deadPeople = 0;
var peopleOnGround = 0;
var lives = 0;
var copterBullets = Array(50);
var cBIndex = 0;
var particle = Array(200);
var pIndex = 0;
var bomb = {};
var gameOverFrame = -1;
var wasSPressed = false;
var missile = {};
var gameOverCause = 0;
var finalRescueFrame = -1;

I had some other ideas for this game that didn't make it, because I am lazy and it wouldn't be worth it anyway. Some of those are:
  • High scores, based on time taken and hostages killed
  • Statistics (like enemies killed, etc)
  • Tank bullets (the tanks do not shoot, only follow you, through you can still destroy them with bombs)
  • A fence between the houses and the embassy grounds
  • Machine gun heating (sou you would need to wait for the machine gun to cool down before shooting again, instead of being able to shoot continuously)
  • Ammo
  • Day-night cycle
  • Sound (jet passing, explosions, machine gun, etc)
One of the ideas I had that is actually present in the game is the particles system. Explosions, fireworks and missile exhaust are created with it. Also, I am very proud of the difficulty progression, less frustrating than the original.

You can play the game on your browser here. Tested on Firefox and Chrome, but should work on any browser with canvas support. You can look at the source-code by pressing Ctrl-U on Firefox, or the equivalent combination on Chrome.

No comments:

Post a Comment