move event send after type definition
move event send after type definition

function HTMLActuator() { function HTMLActuator() {
this.tileContainer = document.getElementsByClassName("tile-container")[0]; this.tileContainer = document.getElementsByClassName("tile-container")[0];
this.scoreContainer = document.getElementsByClassName("score-container")[0]; this.scoreContainer = document.getElementsByClassName("score-container")[0];
this.messageContainer = document.getElementsByClassName("game-message")[0]; this.messageContainer = document.getElementsByClassName("game-message")[0];
   
this.score = 0; this.score = 0;
} }
   
HTMLActuator.prototype.actuate = function (grid, metadata) { HTMLActuator.prototype.actuate = function (grid, metadata) {
var self = this; var self = this;
   
window.requestAnimationFrame(function () { window.requestAnimationFrame(function () {
self.clearContainer(self.tileContainer); self.clearContainer(self.tileContainer);
   
grid.cells.forEach(function (column) { grid.cells.forEach(function (column) {
column.forEach(function (cell) { column.forEach(function (cell) {
if (cell) { if (cell) {
self.addTile(cell); self.addTile(cell);
} }
}); });
}); });
   
self.updateScore(metadata.score); self.updateScore(metadata.score);
   
if (metadata.over) self.message(false); // You lose if (metadata.over) self.message(false); // You lose
if (metadata.won) self.message(true); // You win! if (metadata.won) self.message(true); // You win!
}); });
}; };
   
HTMLActuator.prototype.restart = function () { HTMLActuator.prototype.restart = function () {
this.clearMessage(); this.clearMessage();
}; };
   
HTMLActuator.prototype.clearContainer = function (container) { HTMLActuator.prototype.clearContainer = function (container) {
while (container.firstChild) { while (container.firstChild) {
container.removeChild(container.firstChild); container.removeChild(container.firstChild);
} }
}; };
   
HTMLActuator.prototype.addTile = function (tile) { HTMLActuator.prototype.addTile = function (tile) {
var self = this; var self = this;
   
var element = document.createElement("div"); var element = document.createElement("div");
var position = tile.previousPosition || { x: tile.x, y: tile.y }; var position = tile.previousPosition || { x: tile.x, y: tile.y };
positionClass = this.positionClass(position); positionClass = this.positionClass(position);
   
// We can't use classlist because it somehow glitches when replacing classes // We can't use classlist because it somehow glitches when replacing classes
var classes = ["tile", "tile-" + tile.value, positionClass]; var classes = ["tile", "tile-" + tile.value, positionClass];
this.applyClasses(element, classes); this.applyClasses(element, classes);
   
element.textContent = tile.value; element.textContent = tile.value;
   
if (tile.previousPosition) { if (tile.previousPosition) {
// Make sure that the tile gets rendered in the previous position first // Make sure that the tile gets rendered in the previous position first
window.requestAnimationFrame(function () { window.requestAnimationFrame(function () {
classes[2] = self.positionClass({ x: tile.x, y: tile.y }); classes[2] = self.positionClass({ x: tile.x, y: tile.y });
self.applyClasses(element, classes); // Update the position self.applyClasses(element, classes); // Update the position
}); });
} else if (tile.mergedFrom) { } else if (tile.mergedFrom) {
classes.push("tile-merged"); classes.push("tile-merged");
this.applyClasses(element, classes); this.applyClasses(element, classes);
   
// Render the tiles that merged // Render the tiles that merged
tile.mergedFrom.forEach(function (merged) { tile.mergedFrom.forEach(function (merged) {
self.addTile(merged); self.addTile(merged);
}); });
} else { } else {
classes.push("tile-new"); classes.push("tile-new");
this.applyClasses(element, classes); this.applyClasses(element, classes);
} }
   
// Put the tile on the board // Put the tile on the board
this.tileContainer.appendChild(element); this.tileContainer.appendChild(element);
}; };
   
HTMLActuator.prototype.applyClasses = function (element, classes) { HTMLActuator.prototype.applyClasses = function (element, classes) {
element.setAttribute("class", classes.join(" ")); element.setAttribute("class", classes.join(" "));
}; };
   
HTMLActuator.prototype.normalizePosition = function (position) { HTMLActuator.prototype.normalizePosition = function (position) {
return { x: position.x + 1, y: position.y + 1 }; return { x: position.x + 1, y: position.y + 1 };
}; };
   
HTMLActuator.prototype.positionClass = function (position) { HTMLActuator.prototype.positionClass = function (position) {
position = this.normalizePosition(position); position = this.normalizePosition(position);
return "tile-position-" + position.x + "-" + position.y; return "tile-position-" + position.x + "-" + position.y;
}; };
   
HTMLActuator.prototype.updateScore = function (score) { HTMLActuator.prototype.updateScore = function (score) {
this.clearContainer(this.scoreContainer); this.clearContainer(this.scoreContainer);
   
var difference = score - this.score; var difference = score - this.score;
this.score = score; this.score = score;
   
this.scoreContainer.textContent = this.score; this.scoreContainer.textContent = this.score;
   
if (difference > 0) { if (difference > 0) {
var addition = document.createElement("div"); var addition = document.createElement("div");
addition.classList.add("score-addition"); addition.classList.add("score-addition");
addition.textContent = "+" + difference; addition.textContent = "+" + difference;
   
this.scoreContainer.appendChild(addition); this.scoreContainer.appendChild(addition);
} }
}; };
   
HTMLActuator.prototype.message = function (won) { HTMLActuator.prototype.message = function (won) {
var type = won ? "game-won" : "game-over"; var type = won ? "game-won" : "game-over";
var message = won ? "You win!" : "Game over!" var message = won ? "You win!" : "Game over!"
   
  if (ga) ga("send", "event", "game", "end", type, this.score);
   
this.messageContainer.classList.add(type); this.messageContainer.classList.add(type);
this.messageContainer.getElementsByTagName("p")[0].textContent = message; this.messageContainer.getElementsByTagName("p")[0].textContent = message;
}; };
   
HTMLActuator.prototype.clearMessage = function () { HTMLActuator.prototype.clearMessage = function () {
this.messageContainer.classList.remove("game-won", "game-over"); this.messageContainer.classList.remove("game-won", "game-over");
}; };
   
comments