Merge branch 'resume-game' of github.com:mfrederiksen/2048 into mfrederiksen-resume-game

This commit is contained in:
Gabriele Cirulli
2014-03-22 15:35:51 +01:00
8 changed files with 125 additions and 28 deletions
+35 -12
View File
@@ -1,7 +1,7 @@
function GameManager(size, InputManager, Actuator, ScoreManager) {
function GameManager(size, InputManager, Actuator, StorageManager) {
this.size = size; // Size of the grid
this.inputManager = new InputManager;
this.scoreManager = new ScoreManager;
this.storageManager = new StorageManager;
this.actuator = new Actuator;
this.startTiles = 2;
@@ -15,6 +15,7 @@ function GameManager(size, InputManager, Actuator, ScoreManager) {
// Restart the game
GameManager.prototype.restart = function () {
this.storageManager.clearGameState();
this.actuator.continue();
this.setup();
};
@@ -35,15 +36,24 @@ GameManager.prototype.isGameTerminated = function () {
// Set up the game
GameManager.prototype.setup = function () {
this.grid = new Grid(this.size);
var previousGameState = this.storageManager.getGameState();
this.score = 0;
this.over = false;
this.won = false;
this.keepPlaying = false;
if (previousGameState) {
this.grid = new Grid(previousGameState.grid.size, previousGameState.grid.cells);
this.score = previousGameState.score;
this.over = previousGameState.over;
this.won = previousGameState.won;
this.keepPlaying = previousGameState.keepPlaying;
} else {
this.grid = new Grid(this.size);
this.score = 0;
this.over = false;
this.won = false;
this.keepPlaying = false;
// Add the initial tiles
this.addStartTiles();
// Add the initial tiles
this.addStartTiles();
}
// Update the actuator
this.actuate();
@@ -68,20 +78,33 @@ 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);
if (this.storageManager.getBestScore() < this.score) {
this.storageManager.setBestScore(this.score);
}
this.storageManager.setGameState(this.serializeGameState());
this.actuator.actuate(this.grid, {
score: this.score,
over: this.over,
won: this.won,
bestScore: this.scoreManager.get(),
bestScore: this.storageManager.getBestScore(),
terminated: this.isGameTerminated()
});
};
GameManager.prototype.serializeGameState = function () {
return {
size: this.size,
grid: this.grid.gridState(),
score: this.score,
over: this.over,
won: this.won,
keepPlaying: this.keepPlaying
};
}
// Save all tile positions and remove merger info
GameManager.prototype.prepareTiles = function () {
this.grid.eachCell(function (x, y, tile) {
+35 -7
View File
@@ -1,20 +1,32 @@
function Grid(size) {
function Grid(size, previousCellState) {
this.size = size;
this.cells = [];
this.build();
this.cells = previousCellState ? this.buildFromPreviousState(previousCellState) : this.buildNew();
}
// Build a grid of the specified size
Grid.prototype.build = function () {
Grid.prototype.buildNew = function () {
var cells = [];
for (var x = 0; x < this.size; x++) {
var row = this.cells[x] = [];
var row = cells[x] = [];
for (var y = 0; y < this.size; y++) {
row.push(null);
}
}
return cells;
};
Grid.prototype.buildFromPreviousState = function (state) {
var cells = [];
for (var x = 0; x < this.size; x++) {
var row = cells[x] = [];
for (var y = 0; y < this.size; y++) {
var tileState = state[x][y];
row.push(tileState ? new Tile(tileState.position, tileState.value) : null);
}
}
return cells;
};
// Find the first available random position
@@ -82,3 +94,19 @@ Grid.prototype.withinBounds = function (position) {
return position.x >= 0 && position.x < this.size &&
position.y >= 0 && position.y < this.size;
};
Grid.prototype.gridState = function () {
var cellState = [];
for (var x = 0; x < this.size; x++) {
var row = cellState[x] = [];
for (var y = 0; y < this.size; y++) {
row.push(this.cells[x][y] ? this.cells[x][y].tileState() : null);
}
}
return {
size: this.size,
cells: cellState
}
};
+4
View File
@@ -68,6 +68,10 @@ KeyboardInputManager.prototype.listen = function () {
retry.addEventListener("click", this.restart.bind(this));
retry.addEventListener(this.eventTouchend, this.restart.bind(this));
var restart = document.querySelector(".restart-button");
restart.addEventListener("click", this.restart.bind(this));
restart.addEventListener("touchend", this.restart.bind(this));
var keepPlaying = document.querySelector(".keep-playing-button");
keepPlaying.addEventListener("click", this.keepPlaying.bind(this));
keepPlaying.addEventListener("touchend", this.keepPlaying.bind(this));
+18 -5
View File
@@ -19,7 +19,8 @@ window.fakeStorage = {
};
function LocalScoreManager() {
this.key = "bestScore";
this.bestScoreKey = "bestScore";
this.gameStateKey = "gameState";
var supported = this.localStorageSupported();
this.storage = supported ? window.localStorage : window.fakeStorage;
@@ -38,11 +39,23 @@ LocalScoreManager.prototype.localStorageSupported = function () {
}
};
LocalScoreManager.prototype.get = function () {
return this.storage.getItem(this.key) || 0;
LocalScoreManager.prototype.getBestScore = function () {
return this.storage.getItem(this.bestScoreKey) || 0;
};
LocalScoreManager.prototype.set = function (score) {
this.storage.setItem(this.key, score);
LocalScoreManager.prototype.setBestScore = function (score) {
this.storage.setItem(this.bestScoreKey, score);
};
LocalScoreManager.prototype.getGameState = function () {
var stateJSON = this.storage.getItem(this.gameStateKey);
return stateJSON ? JSON.parse(stateJSON) : null;
};
LocalScoreManager.prototype.setGameState = function (gameState) {
this.storage.setItem(this.gameStateKey, JSON.stringify(gameState));
};
LocalScoreManager.prototype.clearGameState = function () {
this.storage.removeItem(this.gameStateKey);
};
+10
View File
@@ -15,3 +15,13 @@ Tile.prototype.updatePosition = function (position) {
this.x = position.x;
this.y = position.y;
};
Tile.prototype.tileState = function () {
return {
position: {
x: this.x,
y: this.y
},
value: this.value
};
}