Friday, March 11, 2011

Canvas 2d Context and Frame Swapping

While it may be a consequence of the programming languages of which I was reading, every game programming tutorial I have ever read introduces the concept of a buffer frame and frame swapping fairly early on.  The idea is conceptually simple:

You establish two frames, the first you are currently showing to the player, the second you are actively drawing on.  Once you are finished drawing the second frame, you swap the first frame with the second such that the second frame is now the one being shown to the user and the first is free to be used for the drawing of the next frame.

When I first started down the path of learning the 2d drawing context on the canvas,  I spent a good couple hours searching for the HTML5 canvas equivalent of frame swapping and buffering.  I came up empty handed.  That being the case, as is my way, I decided to just start coding, leaving the buffering problem as one to be solved later.  What I found out, much to my happy surprise, is that there is no need for this practice within the 2d context.  

As you draw to the canvas using the 2d drawing context, what you draw does not appear on the canvas immediately.  This is opposed to drawing in, let's say, Java.  Consider the following bit of pseudo code:

function drawStuff() {
  c = get Canvas;
  c.drawImage( something-great.png, 20, 250 );
  c.drawImage( something-else-amazing.png, 52, 17 );
  c.drawImage( a-so-so-image.png, 189, 442 );

If you were to code this in Java and watch it render, you would see something-great.png drawn to the screen first, followed by something-else-amazing.png, and then a-so-so-image.png.  There would be a delay between the appearance of each of these.  And even thought said delay might be barely perceptible, it would be there, and if you are drawing a hundred images to the screen each frame, you would start to notice it and it would become quite irritating.  This is why some form of frame swapping is needed in this case.  You don't want to show the user your frame until all the things you are going to place on it are rendered.

Contrast this to the 2d drawing context.  The way Javascript interacts with the 2d drawing context is such that nothings is actually visibly drawn to the canvas until the scrip doing the drawing has finished executing.  That is to say, looking at the example above, nothing new will be drawn to the canvas until the Javascript interpreter has reached the end of the function (assuming there are not other functions to run after that which are going to do more drawing).  You could argue that this in and of itself is an implementation of frame swapping however the implementation is baked into the browser itself so even if you are making a game engine you don't need to think about it. 

Additional Note of Potential Ignorance
I admit there may very well be a way to achieve the same result in Java without frame swapping.  I haven't done a lot of game programming in Java so I don't know all the magic secrets.  And certainly, many Java game engines hide this detail, however if you are MAKING the game engine you need to worry about it.

Tuesday, March 1, 2011

Game Engine Design - A Free-For-All

If you Google "game engine design best practices" or "game engine design techniques," you get a real melange of results, few of which provide much immediate value outside the satisfaction of personal curiosity, on the off chance that you are curious about the design of a particular game engine.  Since the engine I'm building / have built is my first one (well, probably third or fourth, but first to progress to the point of actually being able to run a game) I'm no expert on the subject, but I've learned enough to find that a game engine is a very single purpose beast.

This singularity of purpose leads to the lack of "best practice" in the domain.  While I'm sure if I took a series of classes on game design and game engine design I would be fed some "best practices," or at least, design patterns, the creation of a cookie cutter game engine, while theoretically possible, would be such a boondoggle it would rival if not trump the practice of low-level-design in traditional software programming.

Simply put, what works for Final Fantasy is not going to work for Angry Birds, and the effort of trying to make a one size fits all game engine, and coding to the engine, would be considerably greater than coding two game engines. Since I write all this as a personal opinion from the perspective of someone who has minimal experience in the field of game development,  I will be providing no hard evidence to support my rambling, so take my statements for what you will, however the direct correlation between the complexity of usage of a framework / engine and the level of flexibility afforded by said framework / engine has been demonstrated time and again (and I'm sure if you enter a magic series of keywords into Google you'll find some evidence to that effect).

And now for something actually interesting, another demo sprite.  Enjoy

a Panda, standing, in a v-neck