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.