Path: blob/main/public/games/files/2048/js/html_actuator.js
1036 views
function HTMLActuator() {1this.tileContainer = document.querySelector(".tile-container");2this.scoreContainer = document.querySelector(".score-container");3this.bestContainer = document.querySelector(".best-container");4this.messageContainer = document.querySelector(".game-message");56this.score = 0;7}89HTMLActuator.prototype.actuate = function (grid, metadata) {10var self = this;1112window.requestAnimationFrame(function () {13self.clearContainer(self.tileContainer);1415grid.cells.forEach(function (column) {16column.forEach(function (cell) {17if (cell) {18self.addTile(cell);19}20});21});2223self.updateScore(metadata.score);24self.updateBestScore(metadata.bestScore);2526if (metadata.terminated) {27if (metadata.over) {28self.message(false); // You lose29} else if (metadata.won) {30self.message(true); // You win!31}32}3334});35};3637// Continues the game (both restart and keep playing)38HTMLActuator.prototype.continueGame = function () {39this.clearMessage();40};4142HTMLActuator.prototype.clearContainer = function (container) {43while (container.firstChild) {44container.removeChild(container.firstChild);45}46};4748HTMLActuator.prototype.addTile = function (tile) {49var self = this;5051var wrapper = document.createElement("div");52var inner = document.createElement("div");53var position = tile.previousPosition || { x: tile.x, y: tile.y };54var positionClass = this.positionClass(position);5556// We can't use classlist because it somehow glitches when replacing classes57var classes = ["tile", "tile-" + tile.value, positionClass];5859if (tile.value > 2048) classes.push("tile-super");6061this.applyClasses(wrapper, classes);6263inner.classList.add("tile-inner");64inner.textContent = tile.value;6566if (tile.previousPosition) {67// Make sure that the tile gets rendered in the previous position first68window.requestAnimationFrame(function () {69classes[2] = self.positionClass({ x: tile.x, y: tile.y });70self.applyClasses(wrapper, classes); // Update the position71});72} else if (tile.mergedFrom) {73classes.push("tile-merged");74this.applyClasses(wrapper, classes);7576// Render the tiles that merged77tile.mergedFrom.forEach(function (merged) {78self.addTile(merged);79});80} else {81classes.push("tile-new");82this.applyClasses(wrapper, classes);83}8485// Add the inner part of the tile to the wrapper86wrapper.appendChild(inner);8788// Put the tile on the board89this.tileContainer.appendChild(wrapper);90};9192HTMLActuator.prototype.applyClasses = function (element, classes) {93element.setAttribute("class", classes.join(" "));94};9596HTMLActuator.prototype.normalizePosition = function (position) {97return { x: position.x + 1, y: position.y + 1 };98};99100HTMLActuator.prototype.positionClass = function (position) {101position = this.normalizePosition(position);102return "tile-position-" + position.x + "-" + position.y;103};104105HTMLActuator.prototype.updateScore = function (score) {106this.clearContainer(this.scoreContainer);107108var difference = score - this.score;109this.score = score;110111this.scoreContainer.textContent = this.score;112113if (difference > 0) {114var addition = document.createElement("div");115addition.classList.add("score-addition");116addition.textContent = "+" + difference;117118this.scoreContainer.appendChild(addition);119}120};121122HTMLActuator.prototype.updateBestScore = function (bestScore) {123this.bestContainer.textContent = bestScore;124};125126HTMLActuator.prototype.message = function (won) {127var type = won ? "game-won" : "game-over";128var message = won ? "You win!" : "Game over!";129130this.messageContainer.classList.add(type);131this.messageContainer.getElementsByTagName("p")[0].textContent = message;132};133134HTMLActuator.prototype.clearMessage = function () {135// IE only takes one value to remove at a time.136this.messageContainer.classList.remove("game-won");137this.messageContainer.classList.remove("game-over");138};139140141