Recently we (at Primal) were asked to create a game that had to run on iOS and Android, in the browser. We picked the new CreateJS framework by Grant Skinner and Adobe, which is designed to make javascript and canvas work more like Actionscript and Flash. The docs are a little light on examples, but apart from that, I’m extremely happy with the performance and features of CreateJS.
Anyway, this isn’t about CreateJS, this is about MVC in Javascript, without an MVC framework. Here’s a very stripped down version of how it worked. I’m not saying this is the right way to do it, or the best way to do it, but it worked really well for me.
Note that in Javascript, there are no classes, so we fake them with functions. It works pretty much the same way, and you don’t have to learn any standardized constructor/destructor stuff.
The HTML:
In the case of a javascript game, the HTML really only serves to load the JS files, and kick things off when everything is loaded.
<html> <head> </head> </html>
The Controller:
I had just one controller that represented the game’s main logic tree.
function GameController() {
var self = this;
this.toString = function() { return "GameController"; }
this.gameModel;
this.uiView;
this.avatarView;
this.hudView;
this.scoreView;
this.etcView;
this.create = function() {
self.gameModel = new GameModel();
self.uiView = new UiView();
self.uiView.create();
self.avatarView = new AvatarView();
self.avatarView.create();
self.hudView = new HudView();
self.hudView.create();
// and so on
self.initGame();
}
this.initGame = function() {
// now that we've created all the view elements,
// and the model, get the game started
}
}
The Model:
Note that this isn’t a singleton. I had just one controller, so I didn’t run the risk of duplicating the Model, but if I did, I would have made this a singleton.
function GameModel() {
var self = this;
this.toString = function() { return "GameModel"; }
this.something;
this.getSomething = function() {
return self.something;
}
this.setSomething = function(data) {
self.something = data;
}
}
The Views:
Views come and go, so they need to be created and destroyed. In the destroy, make sure you clean up everything.
function UiView() {
var self = this;
this.toString = function() { return "UiView"; }
this.someUiElement;
this.anotherUiElement;
this.create = function() {
// load and display bitmaps, or whatever
// fetch the URL for a bitmap from the model like this:
game.gameModel.getSomething();
}
this.destroy = function(data) {
// unload all assets and unset all variables.
}
}
And that’s about it. Every view and model is a variable in the main GameController, which itself is a global variable (I called it game), so you can find anything through that game variable.
Also note these lines that appear at the top of every class.
var self = this;
this.toString = function() { return "NameOfClass"; }
Defining a var called self as this lets you refer to self anywhere in that class, and not worry about scope. For example, if you used a setTimeout to delay something, this would be redefined to the setTimeout handler function, but self would still refer to the class.
Redefining toString to return the name of the class is optional, but it makes your console clearer if you want to console.log where something is coming from.


