<!DOCTYPE HTML>
<html lang="en">
<head>
<title>HTML5 Canvas Game Tutorial</title>
<meta charset="utf-8">
</head>
<body onload="init()" style="margin:0px; overflow:hidden;">
<canvas id="canvas"></canvas>
<script>

//Declare Global Variables
var can = document.getElementById("canvas");
var ctx = can.getContext("2d");
var cw = can.width = window.innerWidth;
var ch = can.height = window.innerHeight;

//Create a 2D array to spell out words and shoot at
var title = [
[0,0,0,0,0,0,1,0,0,1,0,2,2,2,2,2,0,3,0,0,0,3,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,1,0,0,1,0,0,0,2,0,0,0,3,3,0,3,3,0,4,0,0,0,0,0,5,0,0,0,6,6,0,0,7,0,0,0,0,0,0,8,8,0,0,9,9,9,0,0,0],
[0,0,0,0,0,0,1,0,0,1,0,0,0,2,0,0,0,3,0,3,0,3,0,4,0,0,0,0,5,0,5,0,6,0,6,0,0,7,7,7,7,7,0,8,0,0,8,0,9,0,0,0,0,0],
[0,0,0,0,0,0,1,1,1,1,0,0,0,2,0,0,0,3,0,0,0,3,0,4,0,0,0,0,5,0,5,0,6,0,6,0,0,7,0,7,0,7,0,8,8,8,0,0,0,9,9,0,0,0],
[0,0,0,0,0,0,1,0,0,1,0,0,0,2,0,0,0,3,0,0,0,3,0,4,0,0,0,0,0,5,5,0,6,0,6,0,0,7,0,7,0,7,0,8,0,0,0,0,0,0,9,0,0,0],
[0,0,0,0,0,0,1,0,0,1,0,0,0,2,0,0,0,3,0,0,0,3,0,4,0,0,0,0,0,0,5,0,0,6,0,6,0,7,0,7,0,7,0,0,8,8,0,0,9,9,9,0,0,0],
[0,0,0,0,0,0,1,0,0,1,0,0,0,2,0,0,0,3,0,0,0,3,0,4,4,4,4,0,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]];

//Colors array determines the colors used
var colors = ["#FF0000","#00FF00","#0000FF","#FFFF00", "#FF00FF", "#00FFFF"];
var bullets = [];
var mouse = {x:cw/2,y:0};

function init() {
  animate();
  draw();
  //This next line copies the title array so it displays twice
  for(var i=0, len=title.length; i<len; i++) title.push(title[i].slice());
  }

//The animate function gets called every frame and calls draw() and processBullets()
function animate() {
  window.requestAnimationFrame(animate);
  draw();
  if (bullets.length > 0) processBullets();
}

//This function determines if a bullet hit a square, It needs to determine
//the width and height of the squares. Then the for-loop starts to process
//each bullet. The bullet is first moved -y (towards the top). Then x and y
//are calculated which determines where the bullet is in the 2D array (title)
//Next, a check is done that will remove the bullet if it went above the screen
//Finally, the location in title is checked, if it isn't zero then its a hit
//When a bullet hits it makes the spot in the 2D array zero and removes the bullet
//Lastly, the bullet is drawn as a white circle
function processBullets() {
  var rWidth=cw/title[0].length;
  var rHeight=(ch-30)/title.length;
  for (var i=0, len=bullets.length; i<len; i++) {
    bullets[i].y -= 5;
    var y = Math.floor(bullets[i].y/rHeight);
    var x = Math.floor(bullets[i].x/rWidth);
    if (y < 0) {bullets.splice(i,1); i -= 1;}
    else if (title[y][x] != 0) {
      title[y][x] = 0;
      bullets.splice(i,1);
      i -= 1;
    }
    ctx.beginPath();
    ctx.fillStyle="white";
    ctx.arc(bullets[i].x,bullets[i].y,4,0,Math.PI*2);
    ctx.fill();
  }
}

//Draw is responsible for drawing the 2D array (title) on the screen
//It clears the screen and then finds the width and height for each block
//Then 2 for-loops go through the array and draw each rectangle
//The reason why there are so many commands is because a highlight line
//and a shadow line are drawn on each box so they stand out
//Lastly, drawShip is called
function draw() {
  ctx.fillStyle = "black";
  ctx.fillRect(0,0,cw,ch);
  var rWidth=cw/title[0].length;
  var rHeight=(ch-30)/title.length;
  ctx.lineWidth="4";

  for (var i=0, ilen=title[0].length; i<ilen; i++) {
    for (var j=0, jlen=title.length; j<jlen; j++) {
      if (title[j][i] == 0) continue;
      ctx.fillStyle=colors[title[j][i]%6];
      ctx.fillRect(i*rWidth, j*rHeight, rWidth-4, rHeight-4);
      //Highlight Lines (Right and Top sides);
      ctx.beginPath();
      ctx.strokeStyle="rgba(255,255,255,.5)";
      ctx.moveTo(i*rWidth+2, j*rHeight+rHeight-4);
      ctx.lineTo(i*rWidth+2, j*rHeight+2);
      ctx.lineTo(i*rWidth+rWidth-4, j*rHeight+2);
      ctx.stroke();
      //Shadow Lines (Left and Bottom sides)
      ctx.beginPath();
      ctx.strokeStyle="rgba(0,0,0,.5)";
      ctx.moveTo(i*rWidth+rWidth-6, j*rHeight+4);
      ctx.lineTo(i*rWidth+rWidth-6, j*rHeight+rHeight-6);
      ctx.lineTo(i*rWidth+4, j*rHeight+rHeight-6);
      ctx.stroke();
    }
  }
  drawShip();
}

//drawShip simply draws the ship at the bottom. It is just made
//from a bunch of jagged lines with its x position matched to mouse
function drawShip() {
  ctx.strokeStyle="white";
  ctx.lineWidth="2";
  ctx.beginPath();
  ctx.moveTo(mouse.x-30,ch);
  ctx.lineTo(mouse.x+30,ch);
  ctx.lineTo(mouse.x+25,ch-20);
  ctx.lineTo(mouse.x+20,ch-5);
  ctx.lineTo(mouse.x+10,ch-10);
  ctx.lineTo(mouse.x,ch-30);
  ctx.lineTo(mouse.x-10,ch-10);
  ctx.lineTo(mouse.x-20,ch-5);
  ctx.lineTo(mouse.x-25,ch-20);
  ctx.lineTo(mouse.x-30,ch);
  ctx.stroke();
}

//This event listener updates the mouse object with the latest mouse position
window.addEventListener("mousemove", function(e) {mouse={x:e.clientX,y:e.clientY}});

//This event listener fires a bullet by adding the bullet object to the bullets array
window.addEventListener("click", function(e) {bullets.push({x:mouse.x,y:ch-30})});


</script>
</body>
</html>