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);