c=document.body.children[0];w=c.width=800;h=c.height=300;C=c.getContext("2d");C.t=C.fillText;C.lineWidth=3;M=Math;R=M.random;O='';e=[];t=[];l=1;W=C.strokeStyle='#fff';X=[];Y=[];for(K=i=Q=0;i<99;i++)X[i]=R()*w,Y[i]=R()*h,i<3&&(b=i*99+60,t[i]={X:400,Y:b,a:400,b:b});setInterval("J=++Q%40;R()<(K+60)/2e3&&e.push({x:0,y:R()*280+20,J:J?1:40,s:J?Q%7?Q%2:3:2});C.font='25px a';C[F='fillStyle']='#000';C.fillRect(0,0,w,h);C[F]=W;for(i in X)C.fillRect((X[i]+Q)%w,Y[i],1+i%2,2);for(i in t)with(t[i]){X+=X-a<-1?2:X-a>1?-2:0;Y+=Y-b<-1?2:Y-b>1?-2:0;C[F]=i^l?'#66f':'#e33';C.t('◉[',X,Y);for(j in e)with(e[j]){+i||(x+=s<3?2:3,C[F]='#ef1',C.t('⤘⇴▶✈'[s],x,y));x>w&&(O=' GAME OVER',e.splice(j,1))||M.abs(X-x)<28&&M.abs(Y-y)<28&&(C.beginPath(),C.moveTo(x+7,y-7),C.lineTo(X+7,Y-7),C.stroke(),--J||(e.splice(j,1),O||K++))}}C[F]=W;C.font='16px courier';C.t('Deep Space Defense [z,x,c=select ship m1=move] Score:'+K+O,6,h-9)",50);onclick=function(e){t[l].a=e.pageX-9;t[l].b=e.pageY+8};onkeydown=function(e){u=e.keyCode;l=u^90?u^67?1:2:0}
          // .body.children[0] is shorter than .getElementById('c')
var canvas = document.body.children[0],
    width = c.width = 800,
    height = c.height = 300,
    context = canvas.getContext("2d");
context.lineWidth = 3;
context.strokeStyle = "#fff";
var gameOver = "",
    enemies = [],
    ships = [],
    selected = 1,
    score = 0,
    time = 0;
for (var i = 0; i < 3; i++) {
  var y = i * 100 + 60;
  // x,y are current coordinates, gx,gy are goal coordinates (when moving)
  ships[i] = {x: width / 2, y: y, gx: width / 2, gy: y};
}
var starsX = [],
    starsY = [];
for (var i = 0; i < 99; i++) {
  starsX[i] = Math.random() * width;
  starsY[i] = Math.random() * height;
}
function timeStep() {
  time++;
  // depending on the score, there is a chance a new enemy is spawned
  if (Math.random() < (score + 60) / 2000) {
    var bigEnemy = time % 40 == 0;
    enemies.push({
      x: 0,
      y: Math.random() * 280 + 20,
      // hit points
      hp: bigEnemy ? 40 : 1,
      // 0,1=grunt 2=shielded 3=fast
      type: bigEnemy ? 2 : (time % 7 == 0) ? 3 : time % 2
    });
  }
  // Clear the screen
  context.fillStyle = "#000";
  context.fillRect(0, 0, width, height);
  // Draw the stars
  context.fillStyle = "#fff";
  // the modulo in the first argument (x) causes the scrolling.
  // the modulo in the third argument (width) causes some stars to look brigher.
  for(var i in starsX)
    context.fillRect((starsX[i] + time) % width, starsY[i], 1 + i % 2, 2);
  context.font = "25px arial";
  // Go over the ships
  for (var i in ships) {
    var ship = ships[i], dx = ship.x - ship.gx, dy = ship.y - ship.gy;
    // Move the ship
    if (dx < -1) ship.x += 2;
    else if (dx > 1) ship.x -= 2;
    if (dy < -1) ship.y += 2;
    else if (dy > 1) ship.y -= 2;
    // Draw the ship
    context.fillStyle = i == selected ? "#e33" : "#66f";
    context.fillText("◉[", ship.x, ship.y);
    
    // Go over the enemies
    for (var j in enemies) {
      var enemy = enemies[j];
      // Move and draw (only once per turn)
      if (i == 0) {
        enemy.x += enemy.type == 3 ? 3 : 2;
        context.fillStyle = "#ef1";
        context.fillText("⤘⇴▶✈".charAt(enemy.type), enemy.x, enemy.y);
      }
      // Reached the other side
      if (enemy.x > width) {
        gameOver = " GAME OVER";
        enemies.splice(j, 1);
      }
      // Close to this ship
      else if (Math.abs(ship.x - enemy.x) < 28 &&
               Math.abs(ship.y - enemy.y) < 28) {
        context.beginPath();
        context.moveTo(enemy.x + 7, enemy.y - 7);
        context.lineTo(ship.x + 7, ship.y - 7);
        context.stroke();
        // When dead, remove enemy, update score
        if (--enemy.hp == 0) {
          enemies.splice(j, 1);
          if (!gameOver) score++;
        }
      }
    }
  }
  // Draw status text
  context.fillStyle = "#fff";
  context.font = "16px courier";
  context.fillText("Deep Space Defense [z,x,c=select ship m1=move] Score:"
                   + score + gameOver, 6, height - 9);
}
setInterval(timeStep, 50);
window.onclick = function(event) {
  ships[selected].gx = event.pageX - 9;
  ships[selected].gy = event.pageY + 8;
};
window.onkeydown = function(event) {
  if (event.keyCode == 90) selected = 0;
  else if (event.keyCode == 67) selected = 2;
  else selected = 1;
};