From 834daa915586ccbfe991bcb90d3b8cda3d7dde60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9fano?= Date: Thu, 26 Jun 2025 15:41:04 -0300 Subject: [PATCH] =?UTF-8?q?altera=C3=A7oes=20visuais?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- js/game_manager.js | 31 +++++++++++++------------------ js/html_actuator.js | 26 ++++++++++++++++++++++++++ style/main.css | 18 ++++++++++++++++++ 3 files changed, 57 insertions(+), 18 deletions(-) diff --git a/js/game_manager.js b/js/game_manager.js index 1c13d15bd6..3e0f06657a 100644 --- a/js/game_manager.js +++ b/js/game_manager.js @@ -76,7 +76,7 @@ GameManager.prototype.addRandomTile = function () { }; // Sends the updated grid to the actuator -GameManager.prototype.actuate = function () { +GameManager.prototype.actuate = function (achievement) { if (this.storageManager.getBestScore() < this.score) { this.storageManager.setBestScore(this.score); } @@ -93,7 +93,8 @@ GameManager.prototype.actuate = function () { over: this.over, won: this.won, bestScore: this.storageManager.getBestScore(), - terminated: this.isGameTerminated() + terminated: this.isGameTerminated(), + achievement: achievement // novo campo }); }; @@ -130,63 +131,57 @@ GameManager.prototype.moveTile = function (tile, cell) { GameManager.prototype.move = function (direction) { // 0: up, 1: right, 2: down, 3: left var self = this; - if (this.isGameTerminated()) return; // Don't do anything if the game's over - var cell, tile; - var vector = this.getVector(direction); var traversals = this.buildTraversals(vector); var moved = false; - + var achievementReached = null; // Save the current tile positions and remove merger information this.prepareTiles(); - // Traverse the grid in the right direction and move tiles traversals.x.forEach(function (x) { traversals.y.forEach(function (y) { cell = { x: x, y: y }; tile = self.grid.cellContent(cell); - if (tile) { var positions = self.findFarthestPosition(cell, vector); var next = self.grid.cellContent(positions.next); - // Only one merger per row traversal? if (next && next.value === tile.value && !next.mergedFrom) { var merged = new Tile(positions.next, tile.value * 2); merged.mergedFrom = [tile, next]; - self.grid.insertTile(merged); self.grid.removeTile(tile); - // Converge the two tiles' positions tile.updatePosition(positions.next); - // Update the score self.score += merged.value; - + // Checa conquistas + self.achievements.forEach(function(val) { + if (merged.value === val && self.achievementsUnlocked.indexOf(val) === -1) { + achievementReached = val; + self.achievementsUnlocked.push(val); + } + }); // The mighty 2048 tile if (merged.value === 2048) self.won = true; } else { self.moveTile(tile, positions.farthest); } - if (!self.positionsEqual(cell, tile)) { moved = true; // The tile moved from its original cell! } } }); }); - if (moved) { this.addRandomTile(); - if (!this.movesAvailable()) { this.over = true; // Game over! } - - this.actuate(); + // Passa info de conquista para o actuator + this.actuate(achievementReached); } }; diff --git a/js/html_actuator.js b/js/html_actuator.js index 6b31f2d107..719ac78057 100644 --- a/js/html_actuator.js +++ b/js/html_actuator.js @@ -5,6 +5,7 @@ function HTMLActuator() { this.messageContainer = document.querySelector(".game-message"); this.score = 0; + this.achievementContainer = null; } HTMLActuator.prototype.actuate = function (grid, metadata) { @@ -24,6 +25,11 @@ HTMLActuator.prototype.actuate = function (grid, metadata) { self.updateScore(metadata.score); self.updateBestScore(metadata.bestScore); + // Exibe conquista se houver + if (metadata.achievement) { + self.showAchievement(metadata.achievement); + } + if (metadata.terminated) { if (metadata.over) { self.message(false); // You lose @@ -137,3 +143,23 @@ HTMLActuator.prototype.clearMessage = function () { this.messageContainer.classList.remove("game-won"); this.messageContainer.classList.remove("game-over"); }; + +HTMLActuator.prototype.showAchievement = function (value) { + if (!this.achievementContainer) { + this.achievementContainer = document.createElement("div"); + this.achievementContainer.className = "achievement-message"; + document.body.appendChild(this.achievementContainer); + } + this.achievementContainer.textContent = "Conquista: tile " + value + "!"; + this.achievementContainer.style.display = "block"; + this.achievementContainer.style.opacity = 1; + // Fade out após 2 segundos + setTimeout(function() { + var el = document.querySelector('.achievement-message'); + if (el) { + el.style.transition = "opacity 1s"; + el.style.opacity = 0; + setTimeout(function() { el.style.display = "none"; }, 1000); + } + }, 2000); +}; diff --git a/style/main.css b/style/main.css index ea3cb19fca..8238abb367 100644 --- a/style/main.css +++ b/style/main.css @@ -533,6 +533,24 @@ hr { .game-explanation { margin-top: 50px; } +.achievement-message { + position: fixed; + top: 20px; + left: 50%; + transform: translateX(-50%); + background: #ffeb3b; + color: #333; + padding: 16px 32px; + border-radius: 8px; + font-size: 1.5em; + font-weight: bold; + box-shadow: 0 2px 8px rgba(0,0,0,0.2); + z-index: 9999; + display: none; + opacity: 1; + transition: opacity 1s; +} + @media screen and (max-width: 520px) { html, body { font-size: 15px; }