Tuesday, July 27, 2010

Anatomy of a Game

So with all of the small little quirks that were arising in my animation code, I'm going to do us all a favor and step back into the basics. This article is meant to provide you with an idea of what the framework of a game looks like, how it operates, and how to utilize these basics to get you started.

The Bare Minimum

To get us started, let's take a look at the HTML we'll use:

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Games in HTML5 - 20100728: Anatomy of a Game</title>

<script language="javascript" src="game.js"></script>

</head>

<body onload="init();">

<canvas id="gameCanvas" width="300" height="300"></canvas>

</body>
</html>


I'm assuming that most of you have seen this framework HTML document before, we're only adding a few things to get us started. First off, I've added a reference to game.js, which will contain all of the JavaScript code that this simple example will need. Also, the canvas element is in place with the id gameCanvas and a width/height of 300x300 pixels. The body tag's onload event will trigger init(), which is the only function in the game.js file:

function init() {

alert('loaded');

}


This will simply throw a message box 'loaded' when the body of the document has finished loading. With that in place, we can start to dissect the inner workings of a typical game.

Loop Crazy

In the simplest of computer programs, the machine is given a list of instructions to perform one after the other. A equals 5, add 5 to A, print A on the screen. This system would make for an incredibly short game, as you're spit out as soon as the program is finished with the last step. A typical game will run in a loop, updating its state as input is processed from the player(s). Let's use E.T. for the Atari 2600 to determine how a game operates at its most basic level.

Step 1: Game is started, display title screen - wait for input to start.
Step 2: Game begins, receive input until an end state is reached:
- Player dies, show game over screen.
- Player somehow figures out how to beat E.T., show whatever screen that results in.
Step 3: Go to step 1.

In our example, init() is the equivalent to powering on the Atari. It is where we will begin the game loop itself, allows us to perform any setup for the game ahead of time. Here is a basic init() function that will get us into our step 2:

var FPS = 30;
var canvas;
var ctx;

function init() {
canvas = document.getElementById("gameCanvas");

if (canvas.getContext) {
ctx = canvas.getContext("2d");
setInterval(gameLoop, 1000/FPS);
}
}


We set FPS as a global frame speed reference (not actually frames per second), and assign the canvas from our HTML document to a JavaScript variable. The if statement assigns the canvas' 2D drawing context to ctx, which allows us to use it to draw to the canvas itself. setInterval() initiates looping of gameLoop, and tells the function to fire at a set rate.

Step 2 is the actual gameLoop() function that will run our game.

function gameLoop() {

var r = g = b = Math.floor(Math.random()*255);

ctx.fillStyle = 'rgb('+r+','+g+','+b+')';
ctx.fillRect(0,0,300,300);

}


This loop only does one thing per render, assigns a random value from 0-255 to r, g, and b, and applies their values to the fill color of the context object. It then fills the entire canvas with the color given, which will be grayscale since each value is the same. Click here to see it in action.

If this was an actual game, this is an example of what our code would actually look like:

function gameLoop() {
// gameStart = false at start...

showTitleScreen(); // Waits for user to start game, sets gameStart to true

if (gameStart) {
checkPlayerInput();
movePlayer();
moveEnemies();
checkForCollisions();
updateHealth();

if (player.health == 0)
playerDied(); // If player.lives > 0, restart - else game over screen
}
}


A very basic example, but it's the idea that counts: the game loop allows for fast updates of the game state, and determines when an end state has been reached (I win, or I die).

Hopefully this is helpful to some beginners, as it may seem confusing at least to anyone coming from a very procedural background. My next article will flesh out the basic game.js we have created, and start to turn it into an example game in HTML5. Any questions, feel free to leave them below!

1 comment: