Sunday, July 15, 2018
One hour game initiative
One hour game initiative
Anyways. Today I propose the:
"One hour game" initiative
One hour game when you create a game in one hour. Its 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 doesnt 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. Lets 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. Thats 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. Lets 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 its 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 ? " " : );
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 Ive put the ignition into the DOM-ready callback:
jQuery(function(){
step();
setInterval(render, render_frequency);
});
Dead simple. And now Im 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