_=document;$=_.body.children[0];$.width=640;$.height=480;$=$.getContext("2d");M=Math;P=M.PI;S=M.sin;C=M.cos;B="beginPath";Z="closePath";F="fill";R="fillRect";T="translate";Y="fillStyle";L="globalAlpha";v=[22,42,32,22,42,42,64,42,64,48,0,48,0,42];t=[{x:100,y:420,a:3*P/2},{x:540,y:420,a:3*P/2}];_.onkeydown=function(e){k=e.keyCode};_.onkeyup=function(){k=0};k=n=b=0;setInterval(function(){if(b){b[3]+=0.005;b[1]+=b[3];b[0]+=b[2];d=$.getImageData(b[0],b[1],1,1).data;if(d[0]==d[1]&&b[0]>3&&b[0]<637){$[Y]="#fff";$[R](b[0]-2,b[1]-2,3,3);$[L]=0.1}else{if(d[0]>0&&d[1]==0){alert("POW!")}b=0;n++}}with(t[n%2]){switch(k){case 65:a-=a>P?0.01:0;break;case 68:a+=a<2*P?0.01:0;break;case 32:if(!b){c=C(a);s=S(a);b=[x+20*c,y+20*s,1.7*c,1.7*s]}}}$[Y]="#000";$[R](0,0,640,480);$[L]=1;$[Y]="#0e0";$[B]();$.moveTo(0,420);i=0;while(i<14){$.lineTo(v[i++]*10,v[i++]*10)}$[Z]();$[F]();for(i=0;i<2;i++){with(t[i]){$[B]();$[Y]="#e00";$.arc(x,y,10,P,0,0);$.save();$[T](x,y-2);$.rotate(a);$[T](0,-2);$[R](0,0,16,4);$[Z]();$[F]();$.restore()}}},20);
          // What you will find here: with statments, one-letter globals, and shameless hacks to save
// a few bytes of space.
// What you will not find here: best practices, OOP, helpful comments, Nirvana.
// Enjoy :-) -- cm
// TESTED IN:
//	Browser		Win	Linux
//	Opera		[x]	[X]
//	Firefox		[X]	[X]
//	Chrome		[X]	[ ]
//	Safari		[X]	[ ]
//	Konqueror	[ ]	[X] (but man, KJS is sloooow...)
_=document;
$=_.body.children[0]; // canvas
$.width = 640;
$.height = 480;
$ = $.getContext("2d"); // render context
M = Math;
P = M.PI;
S = M.sin;
C = M.cos;
B = "beginPath";
Z = "closePath";
F = "fill";
R = "fillRect";
T = "translate";
Y = "fillStyle";
L = "globalAlpha";
	// all divided by 10 to save space
v = [ 	// terrain coords
	22,42, 32,22, 42,42,
	// finish off the box
	64,42, 64,48, 0,48, 0,42 ];
// tanks
t = [	{ x: 100, y: 420, a: 3*P/2 },
	{ x: 540, y: 420, a: 3*P/2 } ];
_.onkeydown = function(e) {
    k = e.keyCode;
};
_.onkeyup = function() {
    k=0;
};
// GAME LOOP
k=n=b=0;
setInterval(function() {   
    if (b) {
	// shell in flight
	b[3] += 0.005;
	b[1] += b[3];
	b[0] += b[2];
	d = $.getImageData(b[0],b[1],1,1).data;
	if (d[0] == d[1] && b[0] > 3 && b[0] < 637) {
	    $[Y] = "#fff";
	    $[R](b[0]-2,b[1]-2,3,3);
	    
	   // set global alpha for motion blur
	   // bug workaround: Opera leaves trails if we keep this set for every sky render, so
	   // only do this if there's actually a shell to blur
	    $[L] = 0.1;
	} else {
	    // is the pixel below us red? if so...
	    if (d[0] > 0 && d[1] == 0) {
		alert("POW!");
	    }
	    b=0;
	    n++;    
	}
    }
    // n is turn counter. n%2 gives the index of the current player.
    with(t[n%2]) {
    // handle keypresses	
	switch(k) {
		case 65:	// "a" - rotate left (counter-clockwise)
		    a -= a > P ? 0.01 : 0;
		    break;
		case 68:	// "d" - rotate right (clockwise)
		    a += a < 2*P ? 0.01 : 0;
		    break;
		case 32:	// space - fire
		    if(!b) {
			c = C(a);
			s = S(a);
			b = [ x + 20*c, y + 20*s,
				1.7*c, 1.7*s ];
		    }
	}
    }
    // draw sky
    $[Y] = "#000";
    $[R](0, 0, 640, 480);
    $[L] = 1;
    // draw terrain
    $[Y] = "#0e0";
    $[B]();
    $.moveTo(0,420);
    // saves 1 byte over a for loop(!)
    i=0;
    while(i<14) {
	$.lineTo(v[i++]*10,v[i++]*10);
    }
    $[Z]();
    $[F]();
    
    // draw tanks
    for (i=0;i<2;i++) {
	// draw tank sprite and barrel
	with(t[i]) {
	    $[B]();
	    $[Y]= "#e00";
	    $.arc(x, y, 10, P, 0, 0);
	    $.save();
	    $[T](x, y-2);
	    $.rotate(a);
	    $[T](0, -2);
	    //$.translate(0, -2);
	    $[R](0, 0, 16, 4);
	    $[Z]();
	    $[F]();
	    $.restore();
	}
    }
}, 20);