Saturday 23 June 2012

HTML5 - 2D Game Graphics I

Recently, I started working with HTML5 a bit more. I'd used the canvas and audio elements months ago, but quickly went back to Game Maker after that. As I work with it more these days, I'm finding it incredibly easy to use for game design. I think I'd recommend it to anyone who wants to get some experience making 2D games. I don't know if it's the greatest medium for things like advanced lighting, but it's great otherwise.

You don't even have to stick to 2D games. Check out the official Wolfenstein remake: www.wolfenstein.com. As a ray caster, it's not technically "3D", but it's certainly not a 2D platformer. You can do actual 3D as well, but that requires extra APIs that seem to be browser specific as far as I've seen.

Anyway, on to what I want to talk about. I'm starting with canvases, since they seem to be the most basic part of an HTML5 game. This is assuming that you already have an understanding of HTML and JavaScript.


To add a canvas element to your page is simple:
<canvas id="someID" width="800" height="600">
If you see this, your browser is old.
</canvas>
I generally put width and height right into my HTML, as opposed to generating the canvas elements using JS code, to ensure that when the JavaScript runs, the elements it tries to reference will be set up. I believe you can change the dimensions in code at run-time if you need to, for example, adapt to the window size. The text between the opening and closing tags will be shown to any user whose browser can't interpret the HTML5 canvas tag properly.

The next thing you want to do is add some JavaScript. I don't always make my JS code external with normal sites, but I do for games. It just seems cleaner to categorize the functions in separate files.
Below, you can see a very basic drawing setup.
canvas = document.getElementById('someID');
if(canvas.getContext){
	ctx = canvas.getContext('2d');
	ctx.clearRect(0,0,width,height);
			
	ctx.drawImage(object.img,x*32,y*32);
}
Note: I've already set up objects and placed the canvas.width and canvas.height into global variables, so that I can refer to them in this code.

The first line sets up canvas to point to the actual HTML element we created earlier.

The second line is just to check if the browser understands what a canvas is.

Before doing anything with a canvas, you have to getContext(). The context, which I called ctx in this case, is what you do all your work with.

If you have moving objects to draw, you'll need to redraw your canvas every frame. To do it properly, you'll want to clear the canvas before drawing on it again. Otherwise, the canvas will quickly become overrun with old images overlapping one another. As you may have guessed, this is what the clearRect() function is for.

Finally, you get to draw the image. The simple version of drawImage() takes three arguments:
drawImage(image,xcoordinate,ycoordinate);
There is a longer version, with more arguments, but that's for another post.

Coordinates are relative to the top-left corner of the canvas. The image can be any image with an src value, or it can actually be a canvas. That's right, you can draw a canvas onto another canvas. I actually just found that out today, and I have big ideas about what to do with it.

There you have it, you've selected a canvas, prepared it, and drawn an image to it. It's simple, isn't it?

You can do more, though. Rotation, translation, mirroring, flipping, etc. are all possible. In another post, I may also discuss cropping and clipping masks. For now, I'll stick to the basics, though. I made a function earlier that should make things easier for some people.
function drawExt(ctx,img,x,y,side,flip,rot){
	ctx.setTransform(1, 0, 0, 1, 0, 0);
		
	ctx.translate(x+img.width/2,y+img.height/2);
	ctx.rotate(-(rot/360)*Math.PI*2);
	ctx.scale(side,flip);
	
	ctx.drawImage(img,-img.width/2,-img.height/2);

	ctx.setTransform(1, 0, 0, 1, 0, 0);
}
Here's how it goes:
  • Set the transformation values to default
  • Move the canvas so that the target drawing position is centered at (0,0)
  • Rotate the canvas if necessary
  • Mirror and flip the canvas if necessary
  • Draw the image
  • Reset the transformation values in case of future drawing calls
This function will draw a flipped, mirrored image anywhere on the canvas, rotated around its center point. By default, images are transformed around their top-left corner, but I find a center point more useful for these things.

One important thing to note is that the rotate() function takes an angle in radians, but my function takes rot as an angle in degrees and then converts it.

I tend to think that if you can make something easier for yourself by creating a function, you may as well do it.

Anyway, that's all for this post. Next time, I'll probably go into the more advanced features I mentioned earlier. In the future, I plan to talk about HTML5 audio and how I organize the underlying structure of my HTML5 games.

No comments:

Post a Comment