JSCreep

A baby tower defense framework in MooTools.

by dine

HTML

<div class="container">
<div class="field">
  <div class="row">
    <div class="cell" data-routes=""></div>
    <div class="cell" data-routes=""></div>
    <div class="cell" data-routes=""></div>
    <div class="cell entry" data-routes="5"></div>
    <div class="cell" data-routes=""></div>
    <div class="cell" data-routes=""></div>
    <div class="cell" data-routes=""></div>
  </div>
  <div class="row">
    <div class="cell" data-routes=""></div>
    <div class="cell" data-routes=""></div>
    <div class="cell" data-routes=""></div>
    <div class="cell" data-routes="3"></div>
    <div class="cell" data-routes="10"></div>
    <div class="cell" data-routes="12"></div>
    <div class="cell" data-routes=""></div>
  </div>
  <div class="row">
    <div class="cell" data-routes=""></div>
    <div class="cell" data-routes=""></div>
    <div class="cell" data-routes=""></div>
    <div class="cell" data-routes=""></div>
    <div class="cell" data-routes=""></div>
    <div class="cell" data-routes="5"></div>
    <div class="cell" data-routes=""></div>
  </div>
  <div class="row">
    <div class="cell" data-routes=""></div>
    <div class="cell" data-routes="6"></div>
    <div class="cell" data-routes="10"></div>
    <div class="cell" data-routes="12"></div>
    <div class="cell" data-routes=""></div>
    <div class="cell" data-routes="5"></div>
    <div class="cell" data-routes=""></div>
  </div>
  <div class="row">
    <div class="cell" data-routes=""></div>
    <div class="cell" data-routes="5"></div>
    <div class="cell" data-routes=""></div>
    <div class="cell" data-routes="5"></div>
    <div class="cell" data-routes=""></div>
    <div class="cell" data-routes="5"></div>
    <div class="cell" data-routes=""></div>
  </div>
  <div class="row">
    <div class="cell" data-routes=""></div>
    <div class="cell" data-routes="3"></div>
    <div class="cell" data-routes="10"></div>
    <div class="cell" data-routes="5,10"></div>
    <div class="cell"...

CSS

body {
  background: #222;
  padding: 32px;
  font: 14px "Helvetica Neue", Arial, Helvetica, sans-serif;
}

.container {
  background: #222;
  padding-right: 112px;
  position: relative;
}

.field {
  background: white;
  position: relative;
}

.field .track,
.field .effects {
  position: absolute;
  left: 0px;
  top: 0px;
  right: 0px;
  bottom: 0px;
  z-index: 0;
}

.row {
  height: 32px;
}

.cell {
  float: left;
  width: 32px;
  height: 32px;
  position: relative;
  z-index: 1;
}

.cell.good {
  background-color: rgba(141, 198, 63, 0.5);
}

.cell.bad {
  background-color: rgba(237, 28, 36, 0.5);
}

.cell.good,
.cell.bad {
  -webkit-box-shadow: inset rgba(0, 0, 0, 0.25) 0px 0px 2px;
  -moz-box-shadow: inset rgba(0, 0, 0, 0.25) 0px 0px 2px;
}

.creep {
  position: absolute;
  width: 6px;
  height: 6px;
  border: 3px solid #ed1c24;
  margin: -6px;
  background: #ed1c24;
  -webkit-border-radius: 6px;
  -moz-border-radius: 6px;
  -webkit-box-shadow: rgba(0, 0, 0, 0.25) 0px 1px 2px, inset rgba(0, 0, 0, 0.25) 0px 1px 2px;
  -moz-box-shadow: rgba(0, 0, 0, 0.25) 0px 1px 2px, inset rgba(0, 0, 0, 0.25) 0px 1px 2px;
}

.creep .effect {
  position: absolute;
  left: -5px;
  top: -5px;
  width: 16px;
  height: 16px;
  -webkit-border-radius: 6px;
  -moz-border-radius: 6px;
  -webkit-box-shadow: inset rgba(255, 255, 255, 0.5) 0px 7px 2px;
  -moz-box-shadow: inset rgba(255, 255, 255, 0.5) 0px 7px 2px;
}

.creep .IceEffect {
  background: #00aeef;
}

.creep .health {
  position: absolute;
  left: -6px;
  top: -6px;
  font-size: 8px;
  line-height: 1em;
  width: 24px;
  margin: -1em 0 0 -6px;
  text-align: center;
}

.tower {
  position: relative;
  width: 24px;
  height: 24px;
  padding: 4px;
}

.tower:focus { outline: none; }

.tower .tower {
  position: relative;
  padding: 0px;
  width: 0px;
  height: 0px;
  border: 12px solid #ccc;
  border-top-color: #ddd;
  border-bottom-color: #bbb;
  z-index: 2;
}

.RifleTower .tower {
  position: absolute;
  left: 8px;
  top: 8px;
 ...

JavaScript

var NORTH = 1, EAST = 2, SOUTH = 4, WEST = 8;
var TICK = 75;

var Field = new Class({
  initialize: function(element) {
    var self = this;
    var firstRow = element.getChildren('.row')[0];
    var wh = firstRow.getChildren('.cell')[0].getSize();
    this.cellWidth = wh.x;
    this.cellHeight = wh.y;
    var width = firstRow.getChildren('.cell').length * this.cellWidth;
    this.element = element.setStyle('width', width);
    this.element.instance = this;
    this.element.getParent().setStyle('width', width);
    this.rows = this.element.getChildren('.row').length;
    this.columns = this.element.getChildren('.row:first-child')[0].getChildren('.cell').length;
    this.cells = [];
    this.entries = [];
    this.exits = [];
    this.creeps = [];
    this.waves = [];
    
    this.element.getChildren('.row').each(function(row, j) {
      cellRow = [];
      row.getChildren('.cell').each(function(cell, i) {
        cell.row = j;
        cell.column = i;
        if (cell.hasClass('entry')) {
          cellRow.push(new Entry(self, i, j, cell));
        } else if (cell.hasClass('exit')) {
          cellRow.push(new Exit(self, i, j, cell));
        } else {
          cellRow.push(new Cell(self, i, j, cell));
        }
      });
      self.cells.push(cellRow);
    });

    this.towers = this.element.getElements('.tower').map(function(element) {
      var klass = (k = element.get('data-type')) ? Towers[k] : Tower;
      return new klass(self, element);
    });
    
    wh = this.element.getSize();
    this.track = new Element('canvas', {
      'class': 'track',
      width: wh.x,
      height: wh.y
    }).inject(this.element);
    this.drawTrack();

    this.effects = new Element('canvas', {
      'class': 'effects',
      width: wh.x,
      height: wh.y
    }).inject(this.element);
    
    this.createControls();
  },
  start: function() {
    var self = this;
    this.paused = false;
    (function(){
      self.update();
      self.ticker =...