Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
FogNetwork
GitHub Repository: FogNetwork/Tsunami
Path: blob/main/public/games/files/2048/js/html_actuator.js
1036 views
1
function HTMLActuator() {
2
this.tileContainer = document.querySelector(".tile-container");
3
this.scoreContainer = document.querySelector(".score-container");
4
this.bestContainer = document.querySelector(".best-container");
5
this.messageContainer = document.querySelector(".game-message");
6
7
this.score = 0;
8
}
9
10
HTMLActuator.prototype.actuate = function (grid, metadata) {
11
var self = this;
12
13
window.requestAnimationFrame(function () {
14
self.clearContainer(self.tileContainer);
15
16
grid.cells.forEach(function (column) {
17
column.forEach(function (cell) {
18
if (cell) {
19
self.addTile(cell);
20
}
21
});
22
});
23
24
self.updateScore(metadata.score);
25
self.updateBestScore(metadata.bestScore);
26
27
if (metadata.terminated) {
28
if (metadata.over) {
29
self.message(false); // You lose
30
} else if (metadata.won) {
31
self.message(true); // You win!
32
}
33
}
34
35
});
36
};
37
38
// Continues the game (both restart and keep playing)
39
HTMLActuator.prototype.continueGame = function () {
40
this.clearMessage();
41
};
42
43
HTMLActuator.prototype.clearContainer = function (container) {
44
while (container.firstChild) {
45
container.removeChild(container.firstChild);
46
}
47
};
48
49
HTMLActuator.prototype.addTile = function (tile) {
50
var self = this;
51
52
var wrapper = document.createElement("div");
53
var inner = document.createElement("div");
54
var position = tile.previousPosition || { x: tile.x, y: tile.y };
55
var positionClass = this.positionClass(position);
56
57
// We can't use classlist because it somehow glitches when replacing classes
58
var classes = ["tile", "tile-" + tile.value, positionClass];
59
60
if (tile.value > 2048) classes.push("tile-super");
61
62
this.applyClasses(wrapper, classes);
63
64
inner.classList.add("tile-inner");
65
inner.textContent = tile.value;
66
67
if (tile.previousPosition) {
68
// Make sure that the tile gets rendered in the previous position first
69
window.requestAnimationFrame(function () {
70
classes[2] = self.positionClass({ x: tile.x, y: tile.y });
71
self.applyClasses(wrapper, classes); // Update the position
72
});
73
} else if (tile.mergedFrom) {
74
classes.push("tile-merged");
75
this.applyClasses(wrapper, classes);
76
77
// Render the tiles that merged
78
tile.mergedFrom.forEach(function (merged) {
79
self.addTile(merged);
80
});
81
} else {
82
classes.push("tile-new");
83
this.applyClasses(wrapper, classes);
84
}
85
86
// Add the inner part of the tile to the wrapper
87
wrapper.appendChild(inner);
88
89
// Put the tile on the board
90
this.tileContainer.appendChild(wrapper);
91
};
92
93
HTMLActuator.prototype.applyClasses = function (element, classes) {
94
element.setAttribute("class", classes.join(" "));
95
};
96
97
HTMLActuator.prototype.normalizePosition = function (position) {
98
return { x: position.x + 1, y: position.y + 1 };
99
};
100
101
HTMLActuator.prototype.positionClass = function (position) {
102
position = this.normalizePosition(position);
103
return "tile-position-" + position.x + "-" + position.y;
104
};
105
106
HTMLActuator.prototype.updateScore = function (score) {
107
this.clearContainer(this.scoreContainer);
108
109
var difference = score - this.score;
110
this.score = score;
111
112
this.scoreContainer.textContent = this.score;
113
114
if (difference > 0) {
115
var addition = document.createElement("div");
116
addition.classList.add("score-addition");
117
addition.textContent = "+" + difference;
118
119
this.scoreContainer.appendChild(addition);
120
}
121
};
122
123
HTMLActuator.prototype.updateBestScore = function (bestScore) {
124
this.bestContainer.textContent = bestScore;
125
};
126
127
HTMLActuator.prototype.message = function (won) {
128
var type = won ? "game-won" : "game-over";
129
var message = won ? "You win!" : "Game over!";
130
131
this.messageContainer.classList.add(type);
132
this.messageContainer.getElementsByTagName("p")[0].textContent = message;
133
};
134
135
HTMLActuator.prototype.clearMessage = function () {
136
// IE only takes one value to remove at a time.
137
this.messageContainer.classList.remove("game-won");
138
this.messageContainer.classList.remove("game-over");
139
};
140
141