I'm currently writing a falling block puzzle game in Javascript (jsfiddle: http://jsfiddle.net/dr01d3k4/p26bh/15/). The way I store the grid is in a 2d array with many helper methods such as "getColourAt(x, y)", "setColourAt(x, y, colour)" or "isSolidAt(x, y)". The updating of the game is done through a state machine. At the top, I declared constants in a dictionary:
var GameState = {
NONE: 0,
INITIALIZING: 1,
ADDING_NEW_ROW: 2,
PLAYER_FALLING: 3,
LANDING_CELLS: 4,
PRE_CLEARING: 5,
CLEARING: 6,
GAP_FILL_FALL: 7,
LOST: 100
};
Then in the game.update(dt) method, I have a big switch that calls the correct function for each state the game could be in:
Game.prototype.update = function (dt) {
switch (this.state) {
case GameState.INITIALIZING: {
if (this.addedRows < this.startingRows) {
this.changeState(GameState.ADDING_NEW_ROW);
} else {
this.changeState(GameState.PLAYER_FALLING);
}
break;
}
case GameState.ADDING_NEW_ROW: {
this.updateStateAddingNewRow(dt);
break;
}
case GameState.PLAYER_FALLING: {
this.updateStatePlayerFalling(dt);
break;
}
case GameState.LANDING_CELLS: {
this.updateLandingCells();
break;
}
case GameState.PRE_CLEARING: {
this.updatePreClearing(dt);
break;
}
case GameState.CLEARING: {
this.updateClearing(dt);
break;
}
case GameState.GAP_FILL_FALL: {
this.updateGapFillFall(dt);
break;
}
case GameState.LOST: {
this.lose();
break;
}
case GameState.NONE:
default: {
break;
}
}
this.newRowCumulativeTime += dt;
if (this.newRowCumulativeTime > this.newRowTime) {
this.newRowCumulativeTime = this.newRowTime;
}
if (this.grid.isDirty) {
this.grid.calculateLessStateChange();
this.renderGrid();
}
};
By using a state machine, each of the separate parts of the code (player block falling and giving input, clearing out parts, other parts falling from gravity) into their own individual functions.