| function HTMLActuator() { | |
| this.tileContainer = document.querySelector(".tile-container"); | |
| this.scoreContainer = document.querySelector(".score-container"); | |
| this.bestContainer = document.querySelector(".best-container"); | |
| this.messageContainer = document.querySelector(".game-message"); | |
| this.score = 0; | |
| } | |
| HTMLActuator.prototype.actuate = function (grid, metadata) { | |
| var self = this; | |
| window.requestAnimationFrame(function () { | |
| self.clearContainer(self.tileContainer); | |
| grid.cells.forEach(function (column) { | |
| column.forEach(function (cell) { | |
| if (cell) { | |
| self.addTile(cell); | |
| } | |
| }); | |
| }); | |
| self.updateScore(metadata.score); | |
| self.updateBestScore(metadata.bestScore); | |
| if (metadata.terminated) { | |
| if (metadata.over) { | |
| self.message(false); | |
| } else if (metadata.won) { | |
| self.message(true); | |
| } | |
| } | |
| }); | |
| }; | |
| HTMLActuator.prototype.continueGame = function () { | |
| this.clearMessage(); | |
| }; | |
| HTMLActuator.prototype.clearContainer = function (container) { | |
| while (container.firstChild) { | |
| container.removeChild(container.firstChild); | |
| } | |
| }; | |
| HTMLActuator.prototype.addTile = function (tile) { | |
| var self = this; | |
| var wrapper = document.createElement("div"); | |
| var inner = document.createElement("div"); | |
| var position = tile.previousPosition || { x: tile.x, y: tile.y }; | |
| var positionClass = this.positionClass(position); | |
| var classes = ["tile", "tile-" + tile.value, positionClass]; | |
| if (tile.value > 2048) classes.push("tile-super"); | |
| this.applyClasses(wrapper, classes); | |
| inner.classList.add("tile-inner"); | |
| inner.textContent = tile.value; | |
| if (tile.previousPosition) { | |
| window.requestAnimationFrame(function () { | |
| classes[2] = self.positionClass({ x: tile.x, y: tile.y }); | |
| self.applyClasses(wrapper, classes); | |
| }); | |
| } else if (tile.mergedFrom) { | |
| classes.push("tile-merged"); | |
| this.applyClasses(wrapper, classes); | |
| tile.mergedFrom.forEach(function (merged) { | |
| self.addTile(merged); | |
| }); | |
| } else { | |
| classes.push("tile-new"); | |
| this.applyClasses(wrapper, classes); | |
| } | |
| wrapper.appendChild(inner); | |
| this.tileContainer.appendChild(wrapper); | |
| }; | |
| HTMLActuator.prototype.applyClasses = function (element, classes) { | |
| element.setAttribute("class", classes.join(" ")); | |
| }; | |
| HTMLActuator.prototype.normalizePosition = function (position) { | |
| return { x: position.x + 1, y: position.y + 1 }; | |
| }; | |
| HTMLActuator.prototype.positionClass = function (position) { | |
| position = this.normalizePosition(position); | |
| return "tile-position-" + position.x + "-" + position.y; | |
| }; | |
| HTMLActuator.prototype.updateScore = function (score) { | |
| this.clearContainer(this.scoreContainer); | |
| var difference = score - this.score; | |
| this.score = score; | |
| this.scoreContainer.textContent = this.score; | |
| if (difference > 0) { | |
| var addition = document.createElement("div"); | |
| addition.classList.add("score-addition"); | |
| addition.textContent = "+" + difference; | |
| this.scoreContainer.appendChild(addition); | |
| } | |
| }; | |
| HTMLActuator.prototype.updateBestScore = function (bestScore) { | |
| this.bestContainer.textContent = bestScore; | |
| }; | |
| HTMLActuator.prototype.message = function (won) { | |
| var type = won ? "game-won" : "game-over"; | |
| var message = won ? "You win!" : "Game over!"; | |
| this.messageContainer.classList.add(type); | |
| this.messageContainer.getElementsByTagName("p")[0].textContent = message; | |
| }; | |
| HTMLActuator.prototype.clearMessage = function () { | |
| this.messageContainer.classList.remove("game-won"); | |
| this.messageContainer.classList.remove("game-over"); | |
| }; | |