Wednesday, April 20, 2011

Making Thwack!! Fill Up Your Screen

One of the design decisions we made with Entanglement was to use up as much of the screen real estate as the browser would give us. This gives the game a more conventional, installed application atmosphere, especially if you hit F11 while playing. We're heading in a similar direction with Thwack!!, but have run into a few hiccups with the fast nature of the game-play and the slow nature of drawing to an HTML5 canvas element. Here's what we have found so far to keep things moving on a full-screen game:

Here only one disc needs to be re-rendered.
The first and most important take-away we found with our testing was to not draw to canvas unless we have to. The easiest way to keep the animation rendering short is to not draw anything. With a full-screen game, we have only a few parts of the game animating at any given time and have structured our canvases so that only the active parts of the game are being updated graphically.

To render as little as necessary, the game area is composed of several layers of canvases, similar to the layers you might work with in a paint application. Each disc and active game element has its own canvas, and its canvas is only redrawn if the game element has changed in some way. In the example at right, the yellow disc's canvas is erased and the disc is rendered in its new position while the background and the other discs remain static on the screen and no rendering calls are made.

The second drawing optimization we made was in clearing the canvas. We found that the above method works well for drawing itself, but clearing an entire canvas (or multiple canvases depending on how much action was occurring) proved to be expensive. I tried several different methods to clear a canvas before settling on using ctx.clearRect on the immediate area of the disc's last position. Using "ctx.globalCompositeOperation = 'destination-out'" and then rendering the disc at its last position would have been an elegant way to remove the last frame, but I found it's a bit more time-consuming than the ever-ready ctx.clearRect.

Are you a developer and have some wisdom to share? Let us know! Are you not a developer and just read through this post because you want to be? Awesome! You rock.