add movement check, score addition
add movement check, score addition

--- a/js/game_manager.js
+++ b/js/game_manager.js
@@ -103,11 +103,15 @@
 
           // Update the score
           self.score += merged.value;
+
+          // Something's moved for sure
         } else {
           self.moveTile(tile, positions.farthest);
         }
 
-        moved = true;
+        if (!self.positionsEqual(cell, tile)) {
+          moved = true; // The tile moved from its original cell!
+        }
       }
     });
   });
@@ -202,3 +206,7 @@
   return false;
 };
 
+GameManager.prototype.positionsEqual = function (first, second) {
+  return first.x === second.x && first.y === second.y;
+};
+

--- a/js/html_actuator.js
+++ b/js/html_actuator.js
@@ -2,13 +2,15 @@
   this.tileContainer  = document.getElementsByClassName("tile-container")[0];
   this.gameContainer  = document.getElementsByClassName("game-container")[0];
   this.scoreContainer = document.getElementsByClassName("score-container")[0];
+
+  this.score = 0;
 }
 
 HTMLActuator.prototype.actuate = function (grid, metadata) {
   var self = this;
 
   window.requestAnimationFrame(function () {
-    self.clearContainer();
+    self.clearContainer(self.tileContainer);
 
     grid.cells.forEach(function (column) {
       column.forEach(function (cell) {
@@ -26,9 +28,9 @@
   });
 };
 
-HTMLActuator.prototype.clearContainer = function () {
-  while (this.tileContainer.firstChild) {
-    this.tileContainer.removeChild(this.tileContainer.firstChild);
+HTMLActuator.prototype.clearContainer = function (container) {
+  while (container.firstChild) {
+    container.removeChild(container.firstChild);
   }
 };
 
@@ -69,7 +71,20 @@
 };
 
 HTMLActuator.prototype.updateScore = function (score) {
-  this.scoreContainer.textContent = score;
+  this.clearContainer(this.scoreContainer);
+
+  var difference = score - this.score;
+  this.score = score;
+
+  this.scoreContainer.textContent = this.score;
+
+  if (difference) {
+    var addition = document.createElement("div");
+    addition.classList.add("score-addition");
+    addition.textContent = "+" + difference;
+
+    this.scoreContainer.appendChild(addition);
+  }
 };
 
 HTMLActuator.prototype.gameOver = function () {

--- a/style/main.css
+++ b/style/main.css
@@ -21,6 +21,33 @@
   margin: 0;
   display: block;
   float: left; }
+
+@-webkit-keyframes move-up {
+  0% {
+    top: 25px;
+    opacity: 1; }
+
+  100% {
+    top: -50px;
+    opacity: 0; } }
+
+@-moz-keyframes move-up {
+  0% {
+    top: 25px;
+    opacity: 1; }
+
+  100% {
+    top: -50px;
+    opacity: 0; } }
+
+@keyframes move-up {
+  0% {
+    top: 25px;
+    opacity: 1; }
+
+  100% {
+    top: -50px;
+    opacity: 0; } }
 
 .score-container {
   position: relative;
@@ -45,6 +72,19 @@
     line-height: 13px;
     text-align: center;
     color: #eee4da; }
+  .score-container .score-addition {
+    position: absolute;
+    right: 30px;
+    color: red;
+    font-size: 25px;
+    line-height: 25px;
+    font-weight: bold;
+    color: rgba(119, 110, 101, 0.9);
+    z-index: 100;
+    -webkit-animation: move-up 600ms ease-in;
+    -moz-animation: move-up 600ms ease-in;
+    -webkit-animation-fill-mode: both;
+    -moz-animation-fill-mode: both; }
 
 p {
   margin-top: 0;

--- a/style/main.scss
+++ b/style/main.scss
@@ -44,6 +44,18 @@
   margin: 0;
   display: block;
   float: left;
+}
+
+@include keyframes(move-up) {
+  0% {
+    top: 25px;
+    opacity: 1;
+  }
+
+  100% {
+    top: -50px;
+    opacity: 0;
+  }
 }
 
 .score-container {
@@ -72,6 +84,19 @@
     line-height: 13px;
     text-align: center;
     color: $tile-color;
+  }
+
+  .score-addition {
+    position: absolute;
+    right: 30px;
+    color: red;
+    font-size: $height;
+    line-height: $height;
+    font-weight: bold;
+    color: rgba($text-color, .9);
+    z-index: 100;
+    @include animation(move-up 600ms ease-in);
+    @include animation-fill-mode(both);
   }
 }
 

comments