I’m creating a game engine, or more like a large library of useful classes and functions, for Javascript. I plan to use it both for some scientific simulations on the server side and on the client side, so the spectrum of functionality will be quite broad, but always it will revolve around a virtual world (a game, for example).
I’m not sure how to wrap it up, though. If I just provide all the classes, it would pollute the global namespace, which is quite bad. Can I just place everything inside one object, that acts as a namespace? Should the framework itself be a class that can be instanced?
If the later option is chosen, how do I handle classes inside classes (constructor functions)?
var Engine = function()
{
this.someVar = 4;
}
Engine.prototype.Scene = function()
{
this.entities = [];
//What if the scene object needs some classes that are in the engine? How does it get it's parent engine object?
}
Engine.prototype.Scene.prototype.render = function()
{
//"this" should now represent an instance of a scene. But how can I get someVar from the engine? How can I traverse up in the hierarchy of classes?
}
I prefer to use what’s sometimes called a “revealing module” (… pattern). It looks like:
This uses what’s called an immediately-invoked function expression (hereafter referred to as an IIFE) to form a closure within the Engine object. Due to JavaScript’s handling of scope,
someVaris accessible to any function defined within the IIFE. The implication, however, is that no function can define it’s ownsomeVarif it wants to refer to thesomeVaryou define in the IIFE.The magic comes from the return statement. You can see that an object is returned, and within this object you must define anything you want to be “public”.
The constructors, utility methods, etc. can then be accessed via
Engine.Scene, which nicely namespaces your code.As for the
$argument, this is so that you can passEngineto the function in each file, add some methods/properties/constructors (or create a new one if it doesn’t exist) and then pass the return value to another IIFE for further expansion.This is the method used in many popular JavaScript frameworks including jQuery, dojo and LimeJS
scene.js:
sprite.js:
You can then use them with something like:
You can substitute
$with whatever you like,$$is common, or you can be clever. It’s just a placeholder for the global object you’re adding on to.