Chaser

by djwelsh

HTML

<canvas id="c" width="400" height="400"></canvas>

CSS

canvas {
    width: 400px;
    height: 400px;
    outline: 1px solid #ccc;
}

JavaScript

/*
 * Add a shuffle function to Array object prototype
 * Usage : 
 *  var tmpArray = ["a", "b", "c", "d", "e"];
 *  tmpArray.shuffle();
 * http://sroucheray.org/blog/2009/11/array-sort-should-not-be-used-to-shuffle-an-array/
 */

function shuffle (arr) {
    var i = arr.length, j, temp;
    if (i == 0) return;
    while (--i) {
        j = Math.floor(Math.random() * (i + 1));
        temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
};


//Array.prototype.shuffle = function () {
//    var i = this.length, j, temp;
//    if (i == 0) return;
//    while (--i) {
//        j = Math.floor(Math.random() * (i + 1));
//        temp = this[i];
//        this[i] = this[j];
//        this[j] = temp;
//    }
//};

var canvas = {
  width : 400,
  height : 400
};

var MAP_WIDTH = 20;
var MAP_HEIGHT = 20;
var CELL_SIZE = Math.max(canvas.width, canvas.height) / Math.max(MAP_WIDTH, MAP_HEIGHT); //px

var grid = [];
var rnd;

var fireballs = {};
var fireballsId = 0;
var fireballsTotal = 0;


function Cell (obj) {
    this.x = obj.x;
    this.y = obj.y;
    
    this.type = obj.type ? obj.type : 'empty';
    this.color = '#fff';
    switch (this.type) {
        case 'wall':
            this.color = '#999';
            break;
        case 'fence':
            this.color = '#ccc';
            break;
        default: 
            this.color = '#000';
    }
    return this;
}
Cell.prototype.changeType = function (newType) {
    this.type = newType;
    switch (this.type) {
        case 'wall':
            this.color = '#999';
            break;
        case 'fence':
            this.color = '#ccc';
            break;
        default: 
            this.color = '#000';
    }
}
Cell.prototype.draw = function (ctx) {
    ctx.fillStyle = this.color;
    ctx.strokeStyle = '#eee';
    ctx.strokeRect(this.x * CELL_SIZE, this.y * CELL_SIZE, CELL_SIZE, CELL_SIZE);
    ctx.fillRect(this.x * CELL_SIZE, this.y * CELL_SIZE, CELL_SIZE, CELL_SIZE);
}

for (var x = 0; x < MAP_WIDTH;...