Anyways. Today I propose the:
"One hour game" initiative
One hour game when you create a game in one hour. It's like the time limited version of 64k game. Back at the university I loved to create small games. They are perfect to learn structuring code and taking care of the right implementation design. Well, and then you just pile the code up to a huge mess so it works before you go to bed.
A one hour game can be written in any language and any environment. Genre and complexity doesn't matter. My silly one hour game a simple shooter game: AsciiShooter.
The base is html, we just create some containers:
<!doctype html> <html> <head> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="AsciiShooter.css" /> <script> </script> </head> <body> <div> <pre id="title">Ascii Shooter</pre> </div> <div> <pre id="map"></pre> <pre id="ship"></pre> </div> <div> <pre id="score"></pre> </div> <div> <small>Controls: navigation = left/right, shoot = space.</small> </div> </body> </html>
Nothing extraordinary. Let's define some key mapping constants:
const KEY_LEFT = 37; const KEY_RIGHT = 39; const KEY_SPACE = 32;
We will have a screen and we need to know the boundaries and some coordinates:
var screen_w = 12; var screen_h = 10; var screen_mx = new Array(screen_w * screen_h); var ship_x = Math.floor(screen_w >> 1);
Here screen_mx will contain the enemies on the map. We need some vars to define the rendering engine behavior:
var step_delay = 600; var render_frequency = 100;
Not the easiest if we define what happens with the enemy. That's basically the main step of the game. We have a matrix where enemies are appearing on the top and flowing down towards our ship.
function step() { for (var i = screen_h * screen_w - 1; i >= 0; i--) { screen_mx[i] = screen_mx[i - screen_w]; } for (var i = 0; i < screen_w; i++) { screen_mx[i] = Math.random() > 0.95 ? true : false; } setTimeout(step, step_delay); }
There we copied each line to the next line. Then we add enemies to the very first row randomly. At the end we call it again - that makes the game continuous. It would be great to count how many enemies got through our defense. Let's store it in:
var stat_survive = 0;
And count them in the stop function:
for (var i = 0; i < screen_w; i++) { if (screen_mx[screen_w * (screen_h - 1) + i]) { stat_survive++; } }
Each enemy that would go over the last line is a surviver. Now we can add the ship navigation and action handlers:
jQuery('body').keydown(function(event){ switch (event.keyCode) { case KEY_LEFT: ship_x > 0 ? ship_x-- : null; break; case KEY_RIGHT: ship_x < screen_w - 1 ? ship_x++ : null; break; case KEY_SPACE: shoot(); break; } });
With the key events we set the coord of the ship or do a shooting action. Shooting is very lame, just removes the enemy if it's in the way:
var stat_kill = 0; function shoot() { var row = screen_h - 1; var kill_flag = false; while (!kill_flag && row >= 0) { if (screen_mx[row * screen_w + ship_x]) { kill_flag = true; screen_mx[row * screen_w + ship_x] = false; stat_kill++; } row--; } }
And we need a last thing to care about - rendering the whole game out:
function render() { var output = ''; for (var i = 0; i < (screen_w * screen_h); i++) { output = output + (i && i % screen_w == 0 ? "\n" : ''); output = output + (screen_mx[i] ? 'O' : ' '); } var output_ship = ''; for (var i = 0; i < screen_w; i++) { output_ship = output_ship + (i == ship_x ? 'A' : ' '); } jQuery('#map').text(output); jQuery('#ship').text(output_ship); jQuery('#score').text('Killed: ' + stat_kill + ' Missed: ' + stat_survive); }
And to start the game I've put the ignition into the DOM-ready callback:
jQuery(function(){ step(); setInterval(render, render_frequency); });
Dead simple. And now I'm sleeping. Before my laptop falls down you can click on the GitHub repo of the game: AsciiShooter. Or try the demo.
---
What do you think about the "one hour game" initiative?
Peter
No comments:
Post a Comment
Note: only a member of this blog may post a comment.