In this recipe, we will focus our attention on the creation of a basic 2D game framework through means of JavaScript and which will be added to throughout the remainder of the book. This framework will be responsible for declaring the size of the canvas as well as handling the loading, updating, and rendering of game assets.
In order to create a 2D game framework that will handle the initialization, updating, and rendering of assets, we must first of all start by creating a new blank HTML5 canvas by following the steps previously mentioned. Once you have created a blank canvas, we can then move onto creating the main JavaScript object responsible for initializing the application. Begin by creating a new JavaScript object entitled
Main
then input the following code into theMain
object:var frameTime = 0.0333; var objectManager = null; window.onload = function() { new ObjectManager().InitObjectManager(); } function Main() { this.Initialise = function() { return this; }; }
The
main
object is responsible for kick-starting the application as well as determining the desired frame rate, which will be fundamental to the application.Next we create a new object, which will be responsible for handling each of the objects within the game, that is, initializing and disposing of objects. Go ahead and insert the following code:
function Object() { this.x = 0; this.y = 0; this.z = 0; this.InitObject = function(x, y, z) { this.x = x; this.y = y; this.z = z; objectManager.AddObject(this); return this; } this.DisposeObject = function() { objectManager.RemoveObject(this); } }
However, in order to make use of these objects and render them to the canvas, we will require an object that handles the drawing of game objects. For this we will create an object called
DrawableObject
. Once the object has been created, we can then move on to writing the contents of the object as follows:function DrawableObject() { this.texture = null; this.InitDrawableObject = function(texture, x, y, z) { this.InitObject(x, y, z); this.texture = texture; return this; } this.Draw = function(deltaTime, context, deltaX, deltaY) { context.drawImage(this.texture, this.x - deltaX, this.y - deltaY); } this.DisposeDrawableObject = function() { this.DisposeObject(); } } DrawableObject.prototype = new Object;
We must now create the final object for our framework, which will be responsible for pulling together each of the previously created objects in a manageable way. By taking this approach, we are able to manage the loading and rendering of assets to the canvas. As we did earlier, we must create a new object called
ObjectManager.js
, which will first of all contain a number of variable declarations as well as initialize a new instance ofMain.js
and our canvas element.function ObjectManager() { this.objects = new Array(); this.terminalFrame = new Date().getTime(); this.deltaX = 0; this.deltaY = 0; this.main = null; this.canvas = null; this.context = null; this.InitObjectManager = function() { objectManager = this; this.canvas = document.getElementById('canvas'); this.context = this.canvas.getContext('2d'); this.main = new Main().Initialise(); setInterval(function() {objectManager.Draw();}, frameTime); return this; }
With the canvas element initialized, we can then move on to adding objects to the application. This is achieved by pushing a number of items to the previously declared array of objects, which can be seen in the preceding code. We will also look at how to remove these objects once we are finished with them.
this.AddObject = function(Object) { this.objects.push(Object); this.objects.sort(function(a,b){return a.z - b.z;}) }; this.RemoveObject = function(object) { for (var i = 0; i < this.length; ++i) { if (this[i] === object) { this.remove(i); break; } } }
You can see that we are attempting to remove an item from our objects array. However, to do this, we must first add a new function to JavaScript's built-in array object.
Array.prototype.remove = function (a, b) { var rest = this.slice((b || a) + 1 || this.length); if(a < 0) this.length + a; else this.length = a; return this.push.apply(this, rest); };
Now that we can add and remove objects to our framework, we can move on to our final part of the framework, drawing objects to our canvas. This is done by clearing the canvas and then drawing each object to it every time the
Draw
function is called.this.Draw = function () { var frame = new Date().getTime(); var deltaTime = (frame - this.terminalFrame) / 1000; this.terminalFrame = frame; this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); for (obj in this.objects) { if (this.objects[obj].Draw) { this.objects[obj].Draw(deltaTime, this.context, this.deltaX, this.deltaY); } this.context.drawImage(this.canvas, 0, 0); };
Tip
Downloading the example code
You can download the example code files for all Packt books you have purchased from your account at http://www.PacktPub.com. If you purchased this book elsewhere, you can visit http://www.PacktPub.com/support and register to have the files e-mailed directly to you.
The first object we created is responsible for executing the application. Within this object, a number of variables are declared that are responsible for creating a new instance of the object manager as well as the time it takes to update each frame per second. The execution of the application is done firstly by loading the HTML file. Once loaded, the onload
function within Main
is called, and as a result a new object manager is initialized.
The object script within the framework is responsible for initializing a new game object such as a player sprite, or level tile. These objects consist of a series of components that represent the x, y, and z positions of an object on the screen. As we are creating a 2D game the z coordinate represents the draw order of objects, for example, if an object has a z value of zero then that object would be drawn in front of all others thus giving the illusion of depth.
The last object within our game framework is used to load a texture that will represent a game object and then draw that texture to the canvas. This object also has access to the methods and properties of the object and as a result each drawable object is drawn to the positions passed to it via the object script.
Drawing objects to the canvas is achieved through means of the Draw
function within the object manager. This function begins by clearing all objects from the canvas and then updating the next frame and drawing this frame to the canvas. This is done at a rate of 30 frames per second.
Scope then jumps to the object manager constructor, which firstly begins by initializing a number of variables related to the canvas and its context. It also gives a call to update the Draw
function of the application at 30 frames per second. The constructor then makes a call to the Main
constructor, which initializes and draws all game objects to the screen. However, in this instance we do not have any game objects to draw to the canvas.
The remainder of the object manager is responsible for adding and removing game objects to an array of objects that are later updated and drawn to the canvas.