Tutorial: How to make a top-down shooter in JavaScript

Lesson 2) Drawing on the canvas

Experimenting with form and colour... aka drawing rectangles and stuff

For the main canvas area, we can make some basic changes to the CSS just as with any other HTML element. Let's add some colour by adding:
background: green;
This creates a nice grassy area in which our epic battle will take place. Now let's try drawing some stuff on the canvas. To do so, we need to add JavaScript code between our script tags, but first we need to link the main body of the HTML to the code within these tags.

We do this by creating a function. A function is simply a snippet of code that we've put aside and given a name. At any point in our program we can call the function by invoking its name, and the browser will go off and run that bit of code, and then come back to where it was before. So in the script tags, add this code:
function init() { }
Then edit the body tag to look like this:
<body onload="init()">
When the browser reads the body tag, it will go run the init() function, which will contain our game.

Now that we've told the HTML about the JavaScript code, we need to tell the JavaScript which bit of the document we want the code to run in - i.e., our canvas. So add the following inside the init() function:
var canvas = document.getElementById("canvas");
canvas.width = 800;
canvas.height = 600;
var c = canvas.getContext("2d");
var WIDTH = canvas.width;
var HEIGHT = canvas.height;
This creates a variable called "canvas" linked to the element we created in the previous lesson. We set the width and height to what we want them to be, and I like to create new variables called WIDTH and HEIGHT with the same values, to save time typing them later on and so they jump out at me when I'm scanning the code.

Next we create a variable called "c", also known as the "context," and you need to use this object anytime you draw anything on the canvas. Think of it as your brush, if you like.

With a real canvas, you need to dab your brush in some paint and then decide what you are going to do before you actually do it. So it is with a digital canvas.

Let's draw a rectangle with one of the context's built in functions, "rect":
c.fillStyle="red";
c.strokeStyle="blue";
c.rect(10,10,10,100);
c.lineWidth=4;
c.stroke();
c.fill();
With fillStyle you're choosing what color you want to fill the rectangle with (dipping the brush in the red paint pot, in this case), but you don't put your brush to the canvas, as it were, until you use fill(). The other two commands, strokeStyle and stroke() do the same thing for the border around the rectangle. Remember to add the parentheses after fill() and stroke(), and remember your semi-colons. One character out of place will mess up your whole program.

As for the c.rect command itself, the numbers represent the x and y coordinates of the upper-left corner of the rectangle (important note: on the canvas the coordinates 0,0 are in the upper-left corner. So as y coordinates increase, elements move further down the the screen). The last two numbers are its width and height in pixels relative to its coordinates - again its height goes DOWN the canvas.

The canvas has many functions to draw things - rectangles, lines, arcs (and therefore circles), text; and it can even import images. If you can get some good sprites you'll want to use them in your game, but for this tutorial we're going retro, and drawing simple shapes with these built in methods.

Look up these methods online and have a play around, see if you can make some nice patterns on the canvas. I'll do the same, then we'll reconvene for lesson 3.

(Behold my artistic ability. This is why I don't draw my own sprites.)

A note on scale

You may have noticed we've got two sets of width and height variables for the canvas: one in the JavaScript code (this bit: canvas.width = 800;), and one in the HTML tag (this bit: <canvas id="canvas" width="800" height="600" tabindex='1'>). This is actually redundant. Try removing one of these, and reload the page. No effect. Now put it back, and remove the other one. No effect again. (Note: the JavaScript one takes precedence if both are present.)

Now, remove both. The canvas shrinks down to 300 x 150 pixels - this is the default size that gets used if you don't define it yourself. But notice that you can only see the elements that exist within this 300 x 150 pixel window - in my case, the top of the red box and a bit of that weird yellow shape thingy:

Setting the canvas size directly

So if you draw something outside of this area (say, at x=1000, y=1000), it won't appear.

However, if you set the canvas back to 800 by 600, and then go to the CSS code for the canvas and add the following:
canvas {
display:block;
border: solid 1px black;
position:relative;
margin: 0 auto 0 auto;
background: url('background.png');
width: 300px;
height: 150px;
}
The result looks like this:

Setting the canvas size by CSS

Here everything within the canvas has been scaled to fit the 300 x 150 pixel size that you specified. This method works just the same as if you had a JPEG image which was 800px by 600px, and you told the browser to display it as 300px by 150px. The browser doesn't just crop the image to that size - it resizes it. Only in this case you have a canvas instead of a JPEG.

If you've used both an actual width and a CSS width, remember to refer to the actual width when you're creating and positioning things within the canvas, and the CSS width when positionint things around it (that is, the other things on the web page besides the canvas). Thanks VeryAngryBeaver for the suggestion to add this section on scale!

Go to Lesson 3 - Creating a game loop