So we have the basics in place for but the code is not very pretty.
The idea is to write a framework which can be included and used to write a game so thats what we shall do next.
First take our html page and write the javascript as we would expect it would look if we had the framework written. This will give a good indication of the sort of methods the framework needs to expose to the client code.
Below is what I think the client should look like :

<html>
<head>
    <title>8 Bit Game Framework</title>
    <style>
#myCanvas
{
    border: 1px solid black;
}
    </style>
</head>
<body>
    <h1>8 Bit Game Framework</h1>
        <p id="counter">counter</p>
    <canvas id="myCanvas">Sorry... your browser does not support he canvas element.</canvas>
</body>
<script>
// Constants
var SCREEN_WIDTH=640;
var SCREEN_HEIGHT=480;

// Global Variable
var dwFrames=0;
var dwCurrentTime=0;
var dwLastUpdateTime=0;
var dwElapsedTime=0;
var fpsText;
var GE;

init = function()
{
    var canvas = document.getElementById('myCanvas');
    if (canvas.getContext)
    {
        canvas.style.width = SCREEN_WIDTH;
        canvas.style.height = SCREEN_HEIGHT;

        GE = new GameEngine16Colour(canvas,main);
    }
}

main = function()
{
     for (var pixel = 0; pixel <= GE.CanvasWidth*GE.CanvasHeight; pixel+= 1)
     {
        GE.DrawPixelRandomColour(pixel)
     }

    dwFrames++;
    dwCurrentTime = (new Date).getTime();    
    dwElapsedTime = dwCurrentTime - dwLastUpdateTime;
    if(dwElapsedTime >= 1000)
    {        
        fpsText = "FPS " + dwFrames;
        dwLastUpdateTime = dwCurrentTime;
        dwFrames = 0;
    }
    var l = document.getElementById('counter');
    l.textContent = fpsText;
}

init();
</script>
</html>

As you can see the code is now quite small. Let me first explain that I have changed the overall layout of the page. The script is now the last thing on the page. I also removed the call to Init() in the body tag and instead init(); is the last thing in the javascript. Personnal preference. You can chose to keep this new layout or stick with the old way. Up to you.

So now. The constants are just the size we wish the canvas to appear on the page. The framework from our original requirements was to always have a pixel resolution of 320×240.
The next set of global variables are what we are using to calculate the FPS. This is not something I expect the framwwork to handle so this remains here as user code. The only new global varaible we have is DE which will be explained later.

The Init function now just finds the canvas element and if it can get the context it will set the physical size of the canvas and then here is the new code :

GE = new GameEngine16Colour(canvas,main);

This is what our framework will be. I have finally given the framework a name. Woot. Its not catchy but it does describe what it does pretty well. So we call our framework and we must pass it two things. First it needs to know what canvas element it should use and second it needs to know the name of the function that it will need to call ( 30 times a second ) which will contain the game logic. Thats it. At this point I expect the DisplayEngine to intiialise the canvas and set interval timer to call our main function.

The main function is now also simpler. The loop now gets the dimensions of the canvas from the DisplayEngine ( as it is always 320×240 I could have hard coded these but I still get these values from the DE just in case in the future these values change ).
To draw the pixel the DE exposes a DrawPixelRandomColour method which takes a single parameter of pixel number. NOTE : At this point it is important to note that this DrawPixel method is very much a custom method specific for this test and will be removed or changed in the final DE. For now it can remain.
Thats all we need. The last bit of code is our code to calculate and display the FPS.

So.. for now.. I’m happy with that. Its all very simple and clear.

Now we create a new file called GameEngine16Colour.js and we can set to work writing the first iteration of our GameEngine.

So we need to create a GameEngine object and we want to initialise the canvas when we create it.
Below is the base code for our GameEngine.

GameEngine16Colour = function(canvas,mainFunction)
{
var obj = {}

var CANVAS_WIDTH = 320;
var CANVAS_HEIGHT = 240;
var FPS = 30;

var canvas = canvas;
var userMainFunction = mainFunction;

obj.CanvasWidth = CANVAS_WIDTH;
obj.CanvasHeight = CANVAS_HEIGHT;

canvas.width = CANVAS_WIDTH;
canvas.height = CANVAS_HEIGHT;

var ctx = canvas.getContext('2d');

var screenImageData = ctx.getImageData(0,0,CANVAS_WIDTH,CANVAS_HEIGHT);

return obj;
}

This may look quite daunting to some of you but it really is quite simple. In javascript a function is just an object which you can assign to a variable like numbers and strings. It just so happens it contains code. Another thing to note is that a function can contain functions.
The first line
GameEngine16Colour = function(canvas,mainFunction)
may look like it is doing something different but it is just the same as writing
function GameEngine16Colour (canvas,mainFunction)
Both are the same but I prefer the first version when defining objects. Its more a personal preference again.
Within that it looks just like a function which takes two parameters and defines some internal variables. within this function what we are doing is creating a custom object called obj. This is the object that we will be returning at the end of the function.
Once the obj variable is defined the two lines

	obj.CanvasWidth = CANVAS_WIDTH;
	obj.CanvasHeight = CANVAS_HEIGHT;

simply create variables in the object which store the canvas width and height. These are what we are able to acces in our game code.

GE.CanvasWidth

The reason we created these in obj rather than a vars is that the vars or not visible outside the function.
Now we want to implement the code to write pixels and to put our image data back into the canvas.
Add the following just before the return statement in the GameEngine.

obj.Draw = function()
{
ctx.putImageData(screenImageData,0,0);
}

obj.DrawPixelRandomColour = function(pixelOffset)
{
var offset = pixelOffset * 4;
screenImageData.data[offset] = Math.floor(Math.random()*255);
screenImageData.data[offset+1] = Math.floor(Math.random()*255);
screenImageData.data[offset+2] = Math.floor(Math.random()*255);
screenImageData.data[offset+3] = 255;
}

So what we have done here is added two functions into the obj object. The Draw function copies the imagedata back into the canvas and the DrawPixel will take a pixel number and updates the appropriate pixel data in the imagedata. As you can see these are just the same code we had in our previous tutorial. All we have done is split them out into seperate methods.

So what is missing. Well… we dont have a main function and we dont set an interval timer to call it.
The Timer code is fairly specific and stand alone piece of code so we will make an object to handle that too.
Below is the timer code.

Timer = function(fps,callFunction)
{
    var obj = {}

    var fps = fps;
    var callFunction = callFunction

    var timerId = setInterval ( callFunction, 1000/fps);

    return obj;
}

Add this code after the GameEngine. This could be placed in a seperate file but for now this file will be containing all our obejcts.
This is a very simple object. It takes 2 paramters. The first specifies the interval rate as a fps and the second is the function it should call.
Great. So we have a timer so lets finish off coding the GameEngine.
From our game code we can see that the main function doesnt call the Draw method to update the canvas. Thats because that should be a resonsibility of the GameEngine. So we will create a Main function in the obj which will call the game main function and then the Draw function. Add the following afer the line where we difine the screenImageData.

    obj.Main = function()
    {
        userMainFunction();
        obj.Draw();
    }

Almost done. All that is left to do is to create an instance of the Timer to wire it all together.

var timer = Timer(FPS, obj.Main)

Save the file.
Now all that is left is for our html file to include this new code.
Add the following just above the <script> line.

<script language="javascript" src="./GameEngine16Colour.js">Javascript not supported!</script>

Now view the html and you should now see a page that looks exactly the same as the one we started with.
Not impressive from a users view but you know that we have now got a GameEngine that is updating that canvas.

Below is a link to the final code
8BitGameTutorial3

Leave a reply

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> 

required