diff --git a/index.html b/index.html index aae5e4305902d9ab4e223ab08acc8c97c0cfa6c3..1ed8ce7aa03112159005ff4ce76dcd8eb6d1eb8b 100644 --- a/index.html +++ b/index.html @@ -20,7 +20,10 @@

2048

-
0
+
+
0
+
0
+

Join the numbers and get to the 2048 tile!

@@ -89,6 +92,7 @@ + diff --git a/js/application.js b/js/application.js index 1ce870e5bff7500c331b743b53a3a1a8efa4c65b..a4d310a2579bf9940e3844e9e169d65b705865fe 100644 --- a/js/application.js +++ b/js/application.js @@ -1,4 +1,4 @@ // Wait till the browser is ready to render the game (avoids glitches) window.requestAnimationFrame(function () { - var manager = new GameManager(4, KeyboardInputManager, HTMLActuator); + new GameManager(4, KeyboardInputManager, HTMLActuator, LocalScoreManager); }); diff --git a/js/game_manager.js b/js/game_manager.js index 1880d48d09a3a67acb68939a4cfc38e0d823a297..01ce04c3bbec283e254f0c1e54d41a0b62b17b30 100644 --- a/js/game_manager.js +++ b/js/game_manager.js @@ -1,6 +1,7 @@ -function GameManager(size, InputManager, Actuator) { +function GameManager(size, InputManager, Actuator, ScoreManager) { this.size = size; // Size of the grid this.inputManager = new InputManager; + this.scoreManager = new ScoreManager; this.actuator = new Actuator; this.startTiles = 2; @@ -51,11 +52,17 @@ GameManager.prototype.addRandomTile = function () { // Sends the updated grid to the actuator GameManager.prototype.actuate = function () { + if (this.scoreManager.get() < this.score) { + this.scoreManager.set(this.score); + } + this.actuator.actuate(this.grid, { - score: this.score, - over: this.over, - won: this.won + score: this.score, + over: this.over, + won: this.won, + bestScore: this.scoreManager.get() }); + }; // Save all tile positions and remove merger info @@ -204,8 +211,6 @@ GameManager.prototype.tileMatchesAvailable = function () { var cell = { x: x + vector.x, y: y + vector.y }; var other = self.grid.cellContent(cell); - if (other) { - } if (other && other.value === tile.value) { return true; // These two tiles can be merged diff --git a/js/html_actuator.js b/js/html_actuator.js index 2da738b65add3d028567d5321bf0358739413cd7..189208732df26b134f69359e2dec87cf2c1029e8 100644 --- a/js/html_actuator.js +++ b/js/html_actuator.js @@ -1,8 +1,9 @@ function HTMLActuator() { - this.tileContainer = document.getElementsByClassName("tile-container")[0]; - this.scoreContainer = document.getElementsByClassName("score-container")[0]; - this.messageContainer = document.getElementsByClassName("game-message")[0]; - this.sharingContainer = document.getElementsByClassName("score-sharing")[0]; + 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.sharingContainer = document.querySelector(".score-sharing"); this.score = 0; } @@ -22,6 +23,7 @@ HTMLActuator.prototype.actuate = function (grid, metadata) { }); self.updateScore(metadata.score); + self.updateBestScore(metadata.bestScore); if (metadata.over) self.message(false); // You lose if (metadata.won) self.message(true); // You win! @@ -29,7 +31,9 @@ HTMLActuator.prototype.actuate = function (grid, metadata) { }; HTMLActuator.prototype.restart = function () { - if (ga) ga("send", "event", "game", "restart"); + if (typeof ga !== "undefined") { + ga("send", "event", "game", "restart"); + } this.clearMessage(); }; @@ -105,11 +109,17 @@ HTMLActuator.prototype.updateScore = function (score) { } }; +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!" + var message = won ? "You win!" : "Game over!"; - if (ga) ga("send", "event", "game", "end", type, this.score); + if (typeof ga !== "undefined") { + ga("send", "event", "game", "end", type, this.score); + } this.messageContainer.classList.add(type); this.messageContainer.getElementsByTagName("p")[0].textContent = message; diff --git a/js/keyboard_input_manager.js b/js/keyboard_input_manager.js index bcd6f199a0a5cc9389f9379e9a85a845de9b8f90..24dde7a1238e32dcf29b2f15d790450a42d6dce1 100644 --- a/js/keyboard_input_manager.js +++ b/js/keyboard_input_manager.js @@ -59,20 +59,22 @@ KeyboardInputManager.prototype.listen = function () { // Listen to swipe events var touchStartClientX, touchStartClientY; var gameContainer = document.getElementsByClassName("game-container")[0]; - gameContainer.addEventListener("touchstart", function(event) { + + gameContainer.addEventListener("touchstart", function (event) { if (event.touches.length > 1) return; touchStartClientX = event.touches[0].clientX; touchStartClientY = event.touches[0].clientY; event.preventDefault(); }); - gameContainer.addEventListener("touchmove", function(event) { + + gameContainer.addEventListener("touchmove", function (event) { event.preventDefault(); }); - gameContainer.addEventListener("touchend", function(event) { - if (event.touches.length > 0) { - return; - } + + gameContainer.addEventListener("touchend", function (event) { + if (event.touches.length > 0) return; + var dx = event.changedTouches[0].clientX - touchStartClientX; var absDx = Math.abs(dx); diff --git a/js/local_score_manager.js b/js/local_score_manager.js new file mode 100644 index 0000000000000000000000000000000000000000..7e35cd166e9467d30724612fe10b451852006781 --- /dev/null +++ b/js/local_score_manager.js @@ -0,0 +1,32 @@ +window.fakeStorage = { + _data : {}, + setItem : function (id, val) { + console.log("set"); + return this._data[id] = String(val); + }, + getItem : function (id) { + return this._data.hasOwnProperty(id) ? this._data[id] : undefined; + }, + removeItem : function (id) { return delete this._data[id]; }, + clear : function () { return this._data = {}; } +}; + +function LocalScoreManager() { + var localSupported = !!window.localStorage; + + this.key = "bestScore"; + this.storage = localSupported ? window.localStorage : window.fakeStorage; +} + +LocalScoreManager.prototype.get = function () { + var score = this.storage.getItem(this.key); + if (typeof score === "undefined" || score === null) { + score = 0; + } + return score; +}; + +LocalScoreManager.prototype.set = function (score) { + this.storage.setItem(this.key, score); +}; + diff --git a/style/main.css b/style/main.css index ca5137ef3a99382aa152c7a41660e425b5a76477..b9816bec8bafea61dd66b6b70f7711ea3ae95d41 100644 --- a/style/main.css +++ b/style/main.css @@ -49,9 +49,13 @@ h1.title { top: -50px; opacity: 0; } } -.score-container { - position: relative; +.scores-container { float: right; + text-align: right; } + +.score-container, .best-container { + position: relative; + display: inline-block; background: #bbada0; padding: 15px 25px; font-size: 25px; @@ -60,19 +64,19 @@ h1.title { font-weight: bold; border-radius: 3px; color: white; - margin-top: 8px; } - .score-container:after { + margin-top: 8px; + text-align: center; } + .score-container:after, .best-container:after { position: absolute; width: 100%; top: 10px; left: 0; - content: "Score"; text-transform: uppercase; font-size: 13px; line-height: 13px; text-align: center; color: #eee4da; } - .score-container .score-addition { + .score-container .score-addition, .best-container .score-addition { position: absolute; right: 30px; color: red; @@ -86,6 +90,12 @@ h1.title { -webkit-animation-fill-mode: both; -moz-animation-fill-mode: both; } +.score-container:after { + content: "Score"; } + +.best-container:after { + content: "Best"; } + p { margin-top: 0; margin-bottom: 10px; @@ -462,14 +472,17 @@ hr { padding: 0 20px; } h1.title { - font-size: 50px; } + font-size: 27px; + margin-top: 15px; } .container { width: 280px; margin: 0 auto; } - .score-container { - margin-top: 0; } + .score-container, .best-container { + margin-top: 0; + padding: 15px 10px; + min-width: 40px; } .heading { margin-bottom: 10px; } diff --git a/style/main.scss b/style/main.scss index f363be04c2c8eda59adebfd581113f28b5050e7d..d7b1e2dd528f4b71c56437052ccc7384aee8eda9 100644 --- a/style/main.scss +++ b/style/main.scss @@ -58,11 +58,16 @@ h1.title { } } -.score-container { +.scores-container { + float: right; + text-align: right; +} + +.score-container, .best-container { $height: 25px; position: relative; - float: right; + display: inline-block; background: $game-container-background; padding: 15px 25px; font-size: $height; @@ -72,13 +77,13 @@ h1.title { border-radius: 3px; color: white; margin-top: 8px; + text-align: center; &:after { position: absolute; width: 100%; top: 10px; left: 0; - content: "Score"; text-transform: uppercase; font-size: 13px; line-height: 13px; @@ -100,6 +105,14 @@ h1.title { } } +.score-container:after { + content: "Score"; +} + +.best-container:after { + content: "Best" +} + p { margin-top: 0; margin-bottom: 10px; @@ -449,7 +462,8 @@ hr { } h1.title { - font-size: 50px; + font-size: 27px; + margin-top: 15px; } .container { @@ -457,8 +471,15 @@ hr { margin: 0 auto; } - .score-container { + // .scores-container { + // float: left; + // clear: left; + // } + + .score-container, .best-container { margin-top: 0; + padding: 15px 10px; + min-width: 40px; } .heading {