forked from EndMove/EndG-2048
MultiPlayer V1, its a pure 1 vs 1
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
// Wait till the browser is ready to render the game (avoids glitches)
|
||||
window.requestAnimationFrame(function () {
|
||||
new GameManager(4, KeyboardInputManager, HTMLActuator, LocalStorageManager);
|
||||
window.requestAnimationFrame(function (){
|
||||
let storage = new RemoteStorageManager;
|
||||
new GameManager(4, new KeyboardInputManager, new HTMLActuator("game1"), storage, "game1");
|
||||
new GameManager(4, undefined, new HTMLActuator("game2"), storage, "game2");
|
||||
});
|
||||
|
||||
@@ -1,21 +1,24 @@
|
||||
function GameManager(size, InputManager, Actuator, StorageManager) {
|
||||
function GameManager(size, InputManager, Actuator, StorageManager, game){
|
||||
this.size = size; // Size of the grid
|
||||
this.inputManager = new InputManager;
|
||||
this.storageManager = new StorageManager;
|
||||
this.actuator = new Actuator;
|
||||
this.inputManager = InputManager;
|
||||
this.storageManager = StorageManager;
|
||||
this.actuator = Actuator;
|
||||
this.game = game;
|
||||
|
||||
this.startTiles = 2;
|
||||
|
||||
this.inputManager.on("move", this.move.bind(this));
|
||||
this.inputManager.on("restart", this.restart.bind(this));
|
||||
this.inputManager.on("keepPlaying", this.keepPlaying.bind(this));
|
||||
if(this.inputManager){
|
||||
this.inputManager.on("move", this.move.bind(this));
|
||||
this.inputManager.on("restart", this.restart.bind(this));
|
||||
this.inputManager.on("keepPlaying", this.keepPlaying.bind(this));
|
||||
}
|
||||
|
||||
this.setup();
|
||||
}
|
||||
|
||||
// Restart the game
|
||||
GameManager.prototype.restart = function () {
|
||||
this.storageManager.clearGameState();
|
||||
this.storageManager.sendAction("restart");
|
||||
this.actuator.continueGame(); // Clear the game won/lost message
|
||||
this.setup();
|
||||
};
|
||||
@@ -32,30 +35,33 @@ GameManager.prototype.isGameTerminated = function () {
|
||||
};
|
||||
|
||||
// Set up the game
|
||||
GameManager.prototype.setup = function () {
|
||||
var previousState = this.storageManager.getGameState();
|
||||
|
||||
// Reload the game from a previous game if present
|
||||
if (previousState) {
|
||||
this.grid = new Grid(previousState.grid.size,
|
||||
previousState.grid.cells); // Reload grid
|
||||
this.score = previousState.score;
|
||||
this.over = previousState.over;
|
||||
this.won = previousState.won;
|
||||
this.keepPlaying = previousState.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();
|
||||
}
|
||||
|
||||
// Update the actuator
|
||||
this.actuate();
|
||||
GameManager.prototype.setup = function (){
|
||||
this.storageManager.onData((data) => {
|
||||
if(data.action === "state"){
|
||||
// Reload the game from a previous game if present
|
||||
if (data.value) {
|
||||
var previousState = JSON.parse(data.value);
|
||||
this.grid = new Grid(previousState.grid.size,
|
||||
previousState.grid.cells); // Reload grid
|
||||
this.score = previousState.score;
|
||||
this.over = previousState.over;
|
||||
this.won = previousState.won;
|
||||
this.keepPlaying = previousState.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();
|
||||
}
|
||||
|
||||
// Update the actuator
|
||||
this.actuate();
|
||||
}
|
||||
}, this.game);
|
||||
};
|
||||
|
||||
// Set up the initial tiles to start the game with
|
||||
@@ -77,17 +83,6 @@ GameManager.prototype.addRandomTile = function () {
|
||||
|
||||
// Sends the updated grid to the actuator
|
||||
GameManager.prototype.actuate = function () {
|
||||
if (this.storageManager.getBestScore() < this.score) {
|
||||
this.storageManager.setBestScore(this.score);
|
||||
}
|
||||
|
||||
// Clear the state when the game is over (game over only, not win)
|
||||
if (this.over) {
|
||||
console.log("over "+this.score);
|
||||
this.storageManager.clearGameState();
|
||||
} else {
|
||||
this.storageManager.setGameState(this.serialize());
|
||||
}
|
||||
|
||||
this.actuator.actuate(this.grid, {
|
||||
score: this.score,
|
||||
@@ -96,6 +91,8 @@ GameManager.prototype.actuate = function () {
|
||||
bestScore: this.storageManager.getBestScore(),
|
||||
terminated: this.isGameTerminated()
|
||||
});
|
||||
|
||||
this.storageManager.sendAction("state", JSON.stringify(this.serialize()));
|
||||
|
||||
};
|
||||
|
||||
@@ -111,7 +108,7 @@ GameManager.prototype.serialize = function () {
|
||||
};
|
||||
|
||||
// Save all tile positions and remove merger info
|
||||
GameManager.prototype.prepareTiles = function () {
|
||||
GameManager.prototype.prepareTiles = function (){
|
||||
this.grid.eachCell(function (x, y, tile) {
|
||||
if (tile) {
|
||||
tile.mergedFrom = null;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
function HTMLActuator() {
|
||||
this.tileContainer = document.querySelector(".tile-container");
|
||||
this.scoreContainer = document.querySelector(".score-container");
|
||||
this.bestContainer = document.querySelector(".best-container");
|
||||
this.messageContainer = document.querySelector(".game-message");
|
||||
function HTMLActuator(id) {
|
||||
this.tileContainer = document.querySelector(".tile-container-"+id);
|
||||
this.scoreContainer = document.querySelector(".score-container-"+id);
|
||||
this.bestContainer = document.querySelector(".best-container-"+id);
|
||||
this.messageContainer = document.querySelector(".game-message-"+id);
|
||||
|
||||
this.score = 0;
|
||||
}
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
window.fakeStorage = {
|
||||
_data: {},
|
||||
|
||||
setItem: function (id, val) {
|
||||
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 LocalStorageManager() {
|
||||
this.bestScoreKey = "bestScore";
|
||||
this.gameStateKey = "gameState";
|
||||
|
||||
var supported = this.localStorageSupported();
|
||||
this.storage = supported ? window.localStorage : window.fakeStorage;
|
||||
}
|
||||
|
||||
LocalStorageManager.prototype.localStorageSupported = function () {
|
||||
var testKey = "test";
|
||||
|
||||
try {
|
||||
var storage = window.localStorage;
|
||||
storage.setItem(testKey, "1");
|
||||
storage.removeItem(testKey);
|
||||
return true;
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// Best score getters/setters
|
||||
LocalStorageManager.prototype.getBestScore = function () {
|
||||
return this.storage.getItem(this.bestScoreKey) || 0;
|
||||
};
|
||||
|
||||
LocalStorageManager.prototype.setBestScore = function (score) {
|
||||
this.storage.setItem(this.bestScoreKey, score);
|
||||
};
|
||||
|
||||
// Game state getters/setters and clearing
|
||||
LocalStorageManager.prototype.getGameState = function () {
|
||||
var stateJSON = this.storage.getItem(this.gameStateKey);
|
||||
return stateJSON ? JSON.parse(stateJSON) : null;
|
||||
};
|
||||
|
||||
LocalStorageManager.prototype.setGameState = function (gameState) {
|
||||
this.storage.setItem(this.gameStateKey, JSON.stringify(gameState));
|
||||
};
|
||||
|
||||
LocalStorageManager.prototype.clearGameState = function () {
|
||||
this.storage.removeItem(this.gameStateKey);
|
||||
};
|
||||
51
assets/js/remote_storage_manager.js
Normal file
51
assets/js/remote_storage_manager.js
Normal file
@@ -0,0 +1,51 @@
|
||||
function RemoteStorageManager() {
|
||||
this.storage = new WebSocket("ws://localhost/");
|
||||
openListeners = [];
|
||||
dataListeners = [];
|
||||
|
||||
this.bestScore = 0;
|
||||
|
||||
this.storage.onopen = function(){
|
||||
this.connected = true;
|
||||
openListeners.forEach(listener => listener());
|
||||
}
|
||||
|
||||
this.storage.onmessage = function(e){
|
||||
let data = JSON.parse(e.data);
|
||||
let list = dataListeners[data.game];
|
||||
if(list !== undefined) list.forEach(listener => listener(data));
|
||||
console.log(data);
|
||||
|
||||
if(data.action === "bestScore"){
|
||||
this.bestScore = data.value;
|
||||
}
|
||||
}
|
||||
|
||||
this.openListeners = openListeners;
|
||||
this.dataListeners = dataListeners;
|
||||
}
|
||||
|
||||
RemoteStorageManager.prototype.onConnected = function(func){
|
||||
if(this.connected){
|
||||
func();
|
||||
return;
|
||||
}
|
||||
this.openListeners.push(func);
|
||||
}
|
||||
|
||||
RemoteStorageManager.prototype.onData = function(func, game){
|
||||
let listeners = this.dataListeners[game];
|
||||
if(listeners == undefined){
|
||||
listeners = [];
|
||||
this.dataListeners[game] = listeners;
|
||||
}
|
||||
listeners.push(func);
|
||||
}
|
||||
|
||||
RemoteStorageManager.prototype.sendAction = function(action, value){
|
||||
this.storage.send(JSON.stringify(value === undefined ? {action:action} : {action:action,value:value}));
|
||||
}
|
||||
|
||||
RemoteStorageManager.prototype.getBestScore = function(){
|
||||
return this.bestScore;
|
||||
}
|
||||
@@ -116,8 +116,10 @@ hr {
|
||||
margin-bottom: 30px; }
|
||||
|
||||
.container {
|
||||
width: 500px;
|
||||
margin: 0 auto; }
|
||||
width: 40%;
|
||||
margin: 0 auto;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
@-webkit-keyframes fade-in {
|
||||
0% {
|
||||
|
||||
Reference in New Issue
Block a user