¶ GameCopyright(c) 2012 Stefano Balietti MIT Licensed Wrapper class for a Defines a number of event listeners, diveded in
|
(function (exports, node) {
|
¶ Global scope |
var GameState = node.GameState,
GameMsg = node.GameMsg,
GameDB = node.GameDB,
PlayerList = node.PlayerList,
Player = node.Player,
GameLoop = node.GameLoop,
JSUS = node.JSUS;
var action = node.action;
exports.Game = Game;
var name,
description,
gameLoop,
pl,
ml;
|
¶ Game constructorCreates a new instance of Game Params
settings
object
Optional. A configuration object
|
function Game (settings) {
settings = settings || {}; |
¶ Private properties |
|
name = settings.name || 'A nodeGame game';
if (node.support.defineProperty) {
Object.defineProperty(this, 'name', {
value: name,
enumerable: true
});
}
else {
this.name = name;
} |
|
description = settings.description || 'No Description';
if (node.support.defineProperty) {
Object.defineProperty(this, 'description', {
value: description,
enumerable: true
});
}
else {
this.description = description;
} |
|
gameLoop = new GameLoop(settings.loop || settings.loops);
if (node.support.defineProperty) {
Object.defineProperty(this, 'gameLoop', {
value: gameLoop,
enumerable: true
});
}
else {
this.gameLoop = gameLoop;
}
|
|
¶ Game.plThe list of players connected to the game The list may be empty, depending on the server settings API
private
|
pl = new PlayerList();
if (node.support.defineProperty) {
Object.defineProperty(this, 'pl', {
value: pl,
enumerable: true,
configurable: true,
writable: true
});
}
else {
this.pl = pl;
} |
¶ Game.plThe list of monitor clients connected to the game The list may be empty, depending on the server settings API
private
|
ml = new PlayerList();
if (node.support.defineProperty) {
Object.defineProperty(this, 'ml', {
value: ml,
enumerable: true,
configurable: true,
writable: true
});
}
else {
this.ml = ml;
}
|
¶ Game.readyIf TRUE, the nodeGame engine is fully loaded Shortcut to game.isReady If the browser does not support the method object setters, this property is disabled, and Game.isReady() should be used instead. See
Game.isReady();
API
private
|
if (node.support.getter) {
Object.defineProperty(this, 'ready', {
set: function(){},
get: this.isReady,
enumerable: true
});
}
else {
this.ready = null;
} |
¶ Public properties |
|
¶ Game.observerIf TRUE, silently observes the game. Defaults FALSE An nodeGame observer will not send any automatic notification to the server, but it will just observe the game played by other clients. |
this.observer = ('undefined' !== typeof settings.observer) ? settings.observer
: false; |
¶ Game.auto_stepIf TRUE, automatically advances to the next state if all the players have completed the same state After a successful STATEDONE event is fired, the client will automatically goes to the next function in the game-loop without waiting for a STATE message from the server. Depending on the configuration settings, it can still perform additional checkings (e.g.wheter the mininum number of players is connected) before stepping to the next state. Defaults: true |
this.auto_step = ('undefined' !== typeof settings.auto_step) ? settings.auto_step
: true; |
¶ Game.auto_waitIf TRUE, fires a WAITING... event immediately after a successful DONE event Under default settings, the WAITING... event temporarily prevents the user to access the screen and displays a message to the player. Defaults: FALSE |
this.auto_wait = ('undefined' !== typeof settings.auto_wait) ? settings.auto_wait
: false; |
¶ Game.solo_modeIf TRUE, automatically advances to the next state upon completion of a state After a successful DONE event is fired, the client will automatically goes to the next function in the game-loop without waiting for a STATE message from the server, or checking the STATE of the other players. Defaults: FALSE |
this.solo_mode = ('undefined' !== typeof settings.solo_mode) ? settings.solo_mode
: false; |
TODO: check this |
this.minPlayers = settings.minPlayers || 1;
this.maxPlayers = settings.maxPlayers || 1000;
if (settings.init) {
this.init = settings.init;
} |
¶ Game.memoryA storage database for the game In the server logic the content of SET messages are automatically inserted in this object @see node.set |
this.memory = new GameDB();
this.player = null;
this.state = new GameState();
} // <!-- ends constructor --> |
¶ Game methods |
|
¶ Game.initInitialization function This function is called as soon as the game is instantiated, i.e. at state 0.0.0. All event listeners declared here will stay valid throughout the game. |
Game.prototype.init = function () {}; |
¶ Game.startStarts the game Calls the init function, sets the state as Important: it does not use See
node.play
See
Game.publishState
|
Game.prototype.start = function() { |
INIT the game |
this.init();
this.updateState(new GameState("1.1.1"));
|
this.state.is = node.is.LOADED; node.socket.sendSTATE(node.action.SAY, node.game.state); |
node.log('game started');
}; |
Game.prototype.pause = function () {
this.state.paused = true;
}; |
|
Game.prototype.resume = function () {
this.state.paused = false;
}; |
|
¶ Game.nextFetches a state from the game-loop N steps ahead Optionally, a parameter can control the number of steps to take in the game-loop before returning the state Params
N
number
Optional. The number of steps to take in the game-loop. Defaults 1
Returns
boolean
GameState
The next state, or FALSE if it does not exist
@see GameState
@see Game.gameLoop
|
Game.prototype.next = function (N) {
if (!N) return this.gameLoop.next(this.state);
return this.gameLoop.jumpTo(this.state, Math.abs(N));
}; |
¶ Game.previousFetches a state from the game-loop N steps back Optionally, a parameter can control the number of steps to take backward in the game-loop before returning the state Params
times
number
Optional. The number of steps to take in the game-loop. Defaults 1
Returns
boolean
GameState
The previous state, or FALSE if it does not exist
@see GameState
@see Game.gameLoop
|
Game.prototype.previous = function (N) {
if (!N) return this.gameLoop.previous(this.state);
return this.gameLoop.jumpTo(this.state, -Math.abs(N));
}; |
¶ Game.jumpToMoves the game forward or backward in the game-loop Optionally, a parameter can control the number of steps to take in the game-loop before executing the next function. A negative value jumps backward in the game-loop, and a positive one jumps forward in the game-loop Params
jump
number
The number of steps to take in the game-loop
Returns
boolean
TRUE, if the game succesfully jumped to the desired state
@see GameState
@see Game.gameLoop
|
Game.prototype.jumpTo = function (jump) {
if (!jump) return false;
var gs = this.gameLoop.jumpTo(this.state, jump);
if (!gs) return false;
return this.updateState(gs);
}; |
¶ Game.publishStateNotifies internal listeners, the server and other connected clients of the current game-state If the observer flag is set, external notification is inhibited, but the STATECHANGE event is emitted anyway See
GameState
See
Game.observer
|
Game.prototype.publishState = function() { |
if (!this.observer) {
var stateEvent = node.OUT + action.SAY + '.STATE';
node.emit(stateEvent, this.state, 'ALL');
}
node.emit('STATECHANGE');
node.log('New State = ' + new GameState(this.state), 'DEBUG');
}; |
|
¶ Game.updateStateUpdates the game to the specified game-state Params
state
GameState
The state to load and run
|
Game.prototype.updateState = function (state) {
console.log('New state is going to be ' + new GameState(state), 'DEBUG');
if (this.step(state) !== false) {
this.paused = false;
this.state.is = node.is.LOADED;
if (this.isReady()) {
node.emit('LOADED');
}
}
else {
console.log('Error in stepping', 'ERR'); |
TODO: implement sendERR |
node.emit('TXT','State was not updated');
}
}; |
¶ Game.stepRetrieves from the game-loop and executes the function for the specified game-state Params
gameState
GameState
Optional. The GameState to run
Returns
Boolean
FALSE, if the execution encountered an error
@see Game.gameLoop
@see GameState
|
Game.prototype.step = function (gameState) {
gameState = gameState || this.next();
if (gameState) {
var func = this.gameLoop.getFunction(gameState);
console.log('func found');
console.log(func.toString());
|
Experimental: node.window should load the func as well if (node.window) { var frame = this.gameLoop.getAllParams(gameState).frame; node.window.loadFrame(frame); } |
if (func) { |
Local Listeners from previous state are erased before proceeding to next one |
node.events.clearState(this.state);
gameState.is = node.is.LOADING;
this.state = gameState;
|
This could speed up the loading in other client, but now causes problems of multiple update |
this.publishState();
return func.call(node.game);
}
}
return false;
}; |
¶ Game.isReadyReturns TRUE if the nodeGame engine is fully loaded As soon as the nodegame-client library is loaded
During stepping between functions in the game-loop the flag is temporarily turned to FALSE, and all events are queued and fired only after nodeGame is ready to handle them again. If the browser does not support the method object setters, this property is disabled, and Game.isReady() should be used instead. See
Game.ready;
|
Game.prototype.isReady = function() {
if (this.state.state !== 0 && this.state.is < node.is.LOADED) return false;
|
Check if there is a gameWindow obj and whether it is loading |
if (node.window) {
return (node.window.state >= node.is.LOADED) ? true : false;
}
return true;
}; |
¶ Closure |
})(
'undefined' != typeof node ? node : module.exports
, 'undefined' != typeof node ? node : module.parent.exports
);
|