¶ GameLoopCopyright(c) 2012 Stefano Balietti MIT Licensed
|
(function (exports, node) {
|
¶ Global scope |
var GameState = node.GameState,
JSUS = node.JSUS;
exports.GameLoop = GameLoop; |
¶ GameLoop constructorCreates a new instance of GameLoop Takes as input parameter an object like { 1:
{
state: myFunc,
rounds: numRounds, // optional, defaults 1
},
2:
{
state: myNestedState,
rounds: numRounds, // optional, defaults 1
}, From the above example, the value of the myFunc = function() {}; myNestedState = { 1: { state: myFunc2, } 2: { state: myFunc3, } } Params
loop
object
Optional. An object containing the loop functions
|
function GameLoop (loop) { |
¶ Public variables |
|
¶ limitsArray containing the internal representation of the boundaries of each state inside the game-loop API
private
|
this.limits = [];
|
¶ GameLoop.loopThe transformed loop container |
this.loop = loop || {};
for (var key in this.loop) {
if (this.loop.hasOwnProperty(key)) {
|
Transform the loop obj if necessary. When a state executes only one step, it is allowed to pass directly the name of the function. So such function must be incapsulated in a obj here. |
var loop = this.loop[key].state;
if ('function' === typeof loop) {
var o = JSUS.clone(this.loop[key]);
this.loop[key].state = {1: o};
}
var steps = JSUS.size(this.loop[key].state)
var round = this.loop[key].rounds || 1;
this.limits.push({rounds: round, steps: steps});
}
}
|
¶ GameLoop.lengthThe total number of states + steps in the game-loop Warning: may not be working in old browsers. Use #size() instead See
GameLoop.size()
|
if (node.support.getter) {
Object.defineProperty(this, 'length', {
set: function(){},
get: this.size,
configurable: true
});
}
else {
this.length = null;
}
} |
¶ GameLoop methods |
|
¶ GameLoop.sizeReturns the total number of states + steps in the game-loop |
GameLoop.prototype.size = function() {
if (!this.limits.length) return 0;
return this.steps2Go(new GameState());
}; |
¶ GameLoop.existReturns TRUE, if a gameState exists in the game-loop Params
gameState
GameState
The game-state to check
|
GameLoop.prototype.exist = function (gameState) {
if (!gameState) return false;
gameState = new GameState(gameState);
if (typeof(this.loop[gameState.state]) === 'undefined') {
node.log('Unexisting state: ' + gameState.state, 'WARN');
return false;
}
if (typeof(this.loop[gameState.state]['state'][gameState.step]) === 'undefined'){
node.log('Unexisting step: ' + gameState.step, 'WARN');
return false;
} |
States are 1 based, arrays are 0-based => -1 |
if (gameState.round > this.limits[gameState.state-1]['rounds']) {
node.log('Unexisting round: ' + gameState.round + 'Max round: ' + this.limits[gameState.state]['rounds'], 'WARN');
return false;
}
return true;
}; |
¶ GameLoop.nextReturns the next state in the loop An optional input parameter can control the state from which to compute the next state Params
gameState
GameState
Optional. The reference game-state. Defaults, node.game.state
Returns
GameState
boolean
The next game-state, or FALSE if it does not exist
|
GameLoop.prototype.next = function (gameState) {
gameState = (gameState) ? new GameState(gameState) : node.game.state;
|
Game has not started yet, do it! |
if (gameState.state === 0) {
return new GameState({
state: 1,
step: 1,
round: 1
});
}
if (!this.exist(gameState)) {
node.log('No next state of non-existing state: ' + gameState, 'WARN');
return false;
}
var idxLimit = Number(gameState.state)-1; // 0 vs 1 based
if (this.limits[idxLimit]['steps'] > gameState.step){
var newStep = Number(gameState.step)+1;
return new GameState({
state: gameState.state,
step: newStep,
round: gameState.round
});
}
if (this.limits[idxLimit]['rounds'] > gameState.round){
var newRound = Number(gameState.round)+1;
return new GameState({
state: gameState.state,
step: 1,
round: newRound
});
}
if (this.limits.length > gameState.state){
var newState = Number(gameState.state)+1;
return new GameState({
state: newState,
step: 1,
round: 1
});
}
|
No next state: game over |
return false;
}; |
¶ GameLoop.previousReturns the previous state in the loop An optional input parameter can control the state from which to compute the previous state Params
gameState
GameState
Optional. The reference game-state. Defaults, node.game.state
Returns
GameState
boolean
The previous game-state, or FALSE if it does not exist
|
GameLoop.prototype.previous = function (gameState) {
gameState = (gameState) ? new GameState(gameState) : node.game.state;
if (!this.exist(gameState)) {
node.log('No previous state of non-existing state: ' + gameState, 'WARN');
}
var idxLimit = Number(gameState.state)-1; // 0 vs 1 based
if (gameState.step > 1){
var oldStep = Number(gameState.step)-1;
return new GameState({
state: gameState.state,
step: oldStep,
round: gameState.round
});
}
else if (gameState.round > 1){
var oldRound = Number(gameState.round)-1;
var oldStep = this.limits[idxLimit]['steps'];
return new GameState({
state: gameState.state,
step: oldStep,
round: oldRound
});
}
else if (gameState.state > 1){
var oldRound = this.limits[idxLimit-1]['rounds'];
var oldStep = this.limits[idxLimit-1]['steps'];
var oldState = idxLimit;
return new GameState({
state: oldState,
step: oldStep,
round: oldRound
});
}
|
game init |
return false;
}; |
¶ GameLoop.getNameReturns the name associated with a game-state Params
gameState
GameState
Optional. The reference game-state. Defaults, node.game.state
Returns
string
boolean
The name of the game-state, or FALSE if state does not exists
|
GameLoop.prototype.getName = function (gameState) {
gameState = (gameState) ? new GameState(gameState) : node.game.state;
if (!this.exist(gameState)) return false;
return this.loop[gameState.state]['state'][gameState.step]['name'];
}; |
¶ GameLoop.getFunctionReturns the function associated with a game-state Params
gameState
GameState
The reference game-state
Returns
object
boolean
The function of the game-state, or FALSE if state does not exists
|
GameLoop.prototype.getFunction = function (gameState) {
gameState = (gameState) ? new GameState(gameState) : node.game.state;
if (!this.exist(gameState)) return false;
return this.loop[gameState.state]['state'][gameState.step]['state'];
}; |
¶ GameLoop.getAllParamsReturns all the parameters associated with a game-state Params
gameState
GameState
The reference game-state
Returns
object
boolean
The state object, or FALSE if state does not exists
|
GameLoop.prototype.getAllParams = function (gameState) {
gameState = (gameState) ? new GameState(gameState) : node.game.state;
if (!this.exist(gameState)) return false;
return this.loop[gameState.state]['state'][gameState.step];
}; |
¶ GameLoop.jumpToReturns a state N steps away from the reference state A negative value for N jumps backward in the game-loop, and a positive one jumps forward in the game-loop Params
gameState
GameState
The reference game-state
N
number
The number of steps to jump
Returns
GameState
boolean
The "jumped-to" game-state, or FALSE if it does not exist
|
GameLoop.prototype.jumpTo = function (gameState, N) {
if (!this.exist(gameState)) return false;
if (!N) return gameState;
var func = (N > 0) ? this.next : this.previous;
for (var i=0; i < Math.abs(N); i++) {
gameState = func.call(this, gameState);
if (!gameState) return false;
}
return gameState;
}; |
¶ GameLoop.steps2GoComputes the total number steps left to the end of the game. An optional input parameter can control the starting state for the computation Params
gameState
GameState
Optional. The reference game-state. Defaults, node.game.state
Returns
number
The total number of steps left
|
GameLoop.prototype.steps2Go = function (gameState) {
gameState = (gameState) ? new GameState(gameState) : node.game.state;
var count = 0;
while (gameState) {
count++;
gameState = this.next(gameState);
}
return count;
};
GameLoop.prototype.toArray = function() {
var state = new GameState();
var out = [];
while (state) {
out.push(state.toString());
var state = this.next(state);
}
return out;
}; |
¶ GameLoop.indexOfReturns the ordinal position of a state in the game-loop All steps and rounds in between are counted. Params
gameState
GameState
The reference game-state
Returns
number
The state index in the loop, or -1 if it does not exist
@see GameLoop.diff
|
GameLoop.prototype.indexOf = function (state) {
if (!state) return -1;
return this.diff(state, new GameState());
}; |
¶ GameLoop.diffReturns the distance in steps between two states in the game-loop All steps and rounds in between are counted. It works under the assumption that state1 comes first than state2 in the game-loop. Params
state1
GameState
The reference game-state
state2
GameState
Optional. The second state for comparison. Defaults node.game.state
Returns
number
The state index in the loop, or -1 if it does not exist
|
GameLoop.prototype.diff = function (state1, state2) {
if (!state1) return false;
state1 = new GameState(state1) ;
if (!state2) {
if (!node.game.state) return false;
state2 = node.game.state
}
else {
state2 = new GameState(state2) ;
}
var idx = 0;
while (state2) {
if (GameState.compare(state1, state2) === 0){
return idx;
}
state2 = this.next(state2);
idx++;
}
return -1;
};
|
¶ Closure |
})(
'undefined' != typeof node ? node : module.exports
, 'undefined' != typeof node ? node : module.parent.exports
);
|