Holidays are for spending time with family which in my family means playing games. This winter my brothers found an HTML5 adaptation of one of our favorite games, Dominion. I was impressed by the look and feel of the game, since it had a level of polish I expected from a native client. Instead, here was a game that was implemented once and yet can be enjoyed by anyone with a web browser (unlike the considerable effort that can go into platform-specific versions). I was impressed so I looked into the basics of HTML5 game development, learning that it’s a far cry from the kind of development I do on a regular basis. There also aren’t as many online resources as I thought there would be on how to get started, so I decided to capture my lessons in hopes that it can give someone else a bit of a head start.
Basics of Game Development
There are a few basic concepts to this world of HTML5 gaming, and gaming in general. At its core, digital gaming (of the non-text-based variety anyway) is based on the idea of having shapes move around the screen, allowing them to react based on user input and interact with one another according to the rules programmed into the game itself. The user input can come from a variety of sources (keyboard, mouse, touch, etc.), and the shapes, can vary in complexity (think Pong vs. Final Fantasy), but the overall ideas stay the same. Shapes interact with one another based on collision detection, which basically determines whether one shape is touching another, and that determination is based on loops, with the game repeatedly responding to questions like, “Should the position of anything be different now?” (movement/animation), “Are any shapes “touching” and if so, what do I do about that?” (collision detection), and “Has the user done something impacts what should be displaying on the screen?” (user input/reaction). Yes, this is an incredibly simplified description for the sake of brevity.
In traditional game development there are mature tools and practices that make handling these non-trivial problems much easier, but the world of HTML5 gaming is a bit of a new beast, even though the concepts aren’t new. This means that I determined rather quickly that making a game of any sophistication is harder than I thought, even coming from a developer background.
I first found canvas documentation and within minutes I was drawing boxes and circles all over the place, a basic necessity. The next step was to start animating these shapes, which required a game loop to update the state of the game (meaning the location of the shapes). I also knew that I’d want to determine when shapes are touching and react appropriately (collision detection). After spending some time going through the mental exercise of how I would go about implementing a game loop and collision detection on my own, I decided that my free time would be better spent learning how the big kids do it.
I used Core HTML5 Canvas: Graphics, Animation, and Game Development as my general primer. It only took a quick skim to realize that game loops and collision detection are more complicated than I would have imagined.
One of the first lessons was that
setInterval() (two of the most obvious methods to use here) are irregular and not trustworthy, making them not ideal for a game loop. Instead, the game loop should be based on
requestAnimationFrame() which allows the canvas to be updated at the browser’s convenience. This then means you don’t have to worry as much that everything has been updated before the next the next game loop, or ‘tick’. You can find more detail here. Alright, good to know.
Things get even trickier when it comes to detecting when objects collide, with each varying in difficulty based on requirements for/constraints on object shapes, collision accuracy and hardware. There are two fundamental approaches: you can try and predict collisions before they occur or deal with them afterward. The simplest method is to give every object a bounding box and check if any boxes overlap. While simple, it isn’t ideal for accuracy, since not all shapes fit nicely into boxes (here’s a page describing how this can be crucial to getting your game right). Also, because ‘ticks’ aren’t guaranteed to be timed consistently, detecting collisions before they occur becomes more difficult. For simplicity, many implement Separating Axis Theorem (SAT), an approach that detects collisions after they’ve occurred and addresses the general case for convex polygons. The summary: this isn’t the easiest problem to solve. But when solved well, the results can be amazing. For example, this is Ikaruga, known as one of the most difficult games ever made and en example of collision detection gone wild (note that the video describes this as "forgiving").
After reading up on SAT, I decided that implementing collision detection wasn’t how I wanted to spend my spare time. Instead I would use an existing HTML5 game development framework to help me make a simple game and then later I could come back and appreciate what the framework was doing for me. Makes sense, right?
So where does all of this leave me? I’m a few weeks in and I have a strong appreciation for those who have come before me. These problems aren’t easy and the problem space is fascinating, even moreso because of how much potential there is. I hope that someone comes up with the unifying framework that can help dabblers like myself, but until then I’ll stick with the development I know, where I’m not simultaneously reinventing the wheel and entering new territory. If anyone has any framework suggestions, please point me in the right direction and let the games begin!
- http://www.propulsionjs.com/ - Uses
setInterval()in game loop
- A Rubyist's Guide to the Canvas API by H. Dean Hudson