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