add https://github.com/mgarciaisaia mention to readme
[2048.git] / js / html_actuator.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
function HTMLActuator() {
  this.tileContainer    = document.getElementsByClassName("tile-container")[0];
  this.scoreContainer   = document.getElementsByClassName("score-container")[0];
  this.bestContainer    = document.getElementsByClassName("best-container")[0];
  this.messageContainer = document.getElementsByClassName("game-message")[0];
 
  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.over) self.message(false); // You lose
    if (metadata.won) self.message(true); // You win!
  });
};
 
HTMLActuator.prototype.restart = function () {
  this.clearMessage();
};
 
HTMLActuator.prototype.clearContainer = function (container) {
  while (container.firstChild) {
    container.removeChild(container.firstChild);
  }
};
 
HTMLActuator.prototype.addTile = function (tile) {
  var self = this;
 
  var element   = document.createElement("div");
  var position  = tile.previousPosition || { x: tile.x, y: tile.y };
  positionClass = this.positionClass(position);
 
  // We can't use classlist because it somehow glitches when replacing classes
  var classes = ["tile", "tile-" + tile.value, positionClass];
  this.applyClasses(element, classes);
 
  element.textContent = tile.value;
 
  if (tile.previousPosition) {
    // Make sure that the tile gets rendered in the previous position first
    window.requestAnimationFrame(function () {
      classes[2] = self.positionClass({ x: tile.x, y: tile.y });
      self.applyClasses(element, classes); // Update the position
    });
  } else if (tile.mergedFrom) {
    classes.push("tile-merged");
    this.applyClasses(element, classes);
 
    // Render the tiles that merged
    tile.mergedFrom.forEach(function (merged) {
      self.addTile(merged);
    });
  } else {
    classes.push("tile-new");
    this.applyClasses(element, classes);
  }
 
  // Put the tile on the board
  this.tileContainer.appendChild(element);
};
 
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!";
 
  if (typeof ga !== "undefined") {
    ga("send", "event", "game", "end", type, this.score);
  }
 
  this.messageContainer.classList.add(type);
  this.messageContainer.getElementsByTagName("p")[0].textContent = message;
};
 
HTMLActuator.prototype.clearMessage = function () {
  this.messageContainer.classList.remove("game-won", "game-over");
};
 
comments