My entry for the js1k competition. Clocks in at 1018 bytes of JavaScript. Arrow keys move, space fires.
As per the competition rules, this won't work in IE, except perhaps version 9 (untested). The game gradually speeds up, so there's a degree of difficulty in getting a high score.
Version: 1.0
Feedback: joeri (at) sebrechts.net
View source for minified source code.
Documented source code:
w = 300; h = 100; m = Math; s = 0; // score q = 0; // if 1, game over, q = quit r = 53; // generate a fighter every this many frames, 1 frame per 40 ms c=document.getElementById('c'); c.style.border = '1px solid'; c.width = w; c.height = h; c=c.getContext('2d'); // fighters // s: delta x for drawing p = {x: 10, y: h/2, s: 8}; // player 1 f = []; // enemy fighters and bullets, bullets have b: 1 // key state k=[]; this.onkeydown = function(e) { // which is shorter than keyCode k[e.which] = 1; if (k[32] && !q) { // d: inverted x direction travelling speed f.push({x: p.x, y: p.y, s: 4, d: -3, b: 1}); }; }; this.onkeyup = function(e) { k[e.which] = 0; }; // di = draw item // p.s = scale factor for flipping rendering across the x axis function di(p) { c.beginPath(); c.moveTo(p.x, p.y); c.lineTo(p.x-p.s, p.y+(p.b?1:5)); c.lineTo(p.x-p.s, p.y-(p.b?1:5)); c.fill(); } g=0; gb=0; setInterval(function() { // speed up the rate enemy fighters are generated, up to 1 every 10 frames r=m.max(10, r-0.02); // update the position of the main fighter // no clipping because that takes too many bytes! if (k[39]) p.x += 2; // right if (k[37]) p.x -= 2; // left if (k[38]) p.y -= 2; // up if (k[40]) p.y += 2; // down // should we generate an enemy fighter and enemy bullets? // value is inverted: g=0 -> generate fighter, gb=0 -> generate bullet g = (g+1)%m.round(r); gb = (gb+1)%100; // generate enemy fighter if (!g) f.push({x: w, y: h*m.random(), s: -8, d: 1}); // draw everything c.clearRect(0, 0, w, h); i=f.length; while (i--) { o=f[i]; // animate enemy fighters and bullets o.x -= o.d; di(o); // if this is a player 1 bullet, // do collision detection against enemy fighters` // o.d < 0: player 1 object if (o.b && o.d<0) { // for every enemy fighter j=f.length; while (j--) { z=f[j]; // if collision, remove bullet and fighter and increase score // !z.b = not a bullet if (z && !z.b && (z.x-o.x)<1 && (z.x-o.x)>-7 && (m.abs(z.y-o.y) < 4)) { if (i>j) i--; f.splice(j, 1); f.splice(i, 1); s++; }; }; }; // do collision detection between player 1 and enemy objects // o.d>0 : enemy object if (!q && o.d>0 && (p.x-o.x)>2 && (p.x-o.x)<8 && m.abs(o.y-p.y)<5) { q=1; f.splice(i, 1); }; // if this is a fighter, and not a bullet, // and it's time to fire bullets, then fire a bullet if (!gb && !o.b) f.push({x: o.x, y: o.y, s: -4, d: 2, b: 1}); // remove them if they go out of the screen if ((o.x < -8) || (o.x > w+9)) { f.splice(i, 1); }; }; if (!q) di(p); c.fillText(s, 2, 10); }, 40);