LESSON 6 - April 9, 2013

HTML5 GAME DEVELOPMENT

Operation C.A.N.T (Canvas Ain't No Thang) LESSON # 6

Ben W. Savage

Howdy! Looks like it's that time again - HTML5 game time! Today we'll be taking a look at how the canvas allows you to add text to your games. It's REALLY simple, so you shouldn't have any problems getting pretty words to flash all over your screen in no time!

So let's erase everything inside the <script> tags and replace it with this:

var theCanvas = document.getElementById("canvas");
var context = theCanvas.getContext("2d");

context.font = "20px Verdana";
context.strokeStyle = "#ff0000";
context.strokeText("I'm a goofy goofball!", 150,200);

And the highly intellectual message will then appear on your screen in funny bubble (I mean, strokeText) letters.

As you can observe, the message you want to display on the canvas is between quotation marks. Don't forget this! The other two numbers are the X and Y values which tell the computer where you want your text to be placed. By now after 5 tutorials of me ramming this stuff into your brain you should be expert thing-placers in HTML5, so this code should just roll off your fingers!

There are two types of text you can draw on the canvas: strokeText and fillText.

Of course you need a fillStyle if your'e going to fill stuff and a strokeStyle if you're going to make funny bubble letters.

As you can see, there are two arguments you need to specify in yout context.font:

and

Stick with the common ones for now like Arial, Tahoma, Verdana, Times New Roman, Monospace, etc. just to play it safe in this crazy cross-browser world.

So hey, try out this fillText, wont'cha?


var theCanvas = document.getElementById("canvas");
var context = theCanvas.getContext("2d");

context.font = "20px Verdana";
context.fillStyle = "#ff0000";
context.fillText("I'm a FILLED goofy goofball!", 150,200);

Sacre bleu! It's amazing!

The only other things you'll really need to know about text for now are how to align it on the canvas and how to set its baseline.

There are 3 main values for aligning text: left, center and right.

Let's take a minute to add the following line of code to our text right above where we defined the font:

context.textAlign = "center";

All this does is make the exact center of your text line up with the x and y coordinates you attributed to it.

Change the value to left, then right and you'll see it line up with the left and right, respectively.

Now let's add some code to change the baseline of the text:

context.textBaseLine = "top"

The other two main values are middle and bottom.

Take a second to try each of the values, understand how the text is positioned in relation to an imaginary baseline, then I'd say you're all set to work with text!

Easy, huh?

Keep in mind as we continue down the road with these tutorials, that we're adding tools to our mental toolkit. As with any course, all the extra work that you do outside the classroom will pay off in the end. My advice to you is that you spend a half hour or so every day in addition to these lessons, just messing around with all the features you've learned so far. No drudgery, just having fun and experimenting!

Think about it a sec:

We've learned how to use timers to move things across the screen, but timers don't have to serve just that purpose! What can you do to something over time? What about a drop shadow that grows on an object over time? What about a gradient that creeps across a rectangle? Why not a text that has an ever-increasing font size?

Just as an example, here was something silly I did the other day just for fun:

<!doctype html>
<title>HTML GOOFIN' 1 </title>
<canvas id = "canvas" width="1200" height="400"></canvas>
<script>

var theCanvas = document.getElementById("canvas");
var context = theCanvas.getContext("2d");

drawScreen();

function drawScreen() {

context.fillStyle = '#'+(0x1000000+(Math.random())*0xffffff).toString(16).substr(1,6);
context.fillText("I'm learning HTML5 Game Development - world beware!",Math.random() * canvas.width,Math.random() * canvas.height);
requestAnimationFrame(drawScreen);
}
</script>

Go ahead: run it and check it out.

Now some of it might look awful intimidating, but don't worry too much about the extra stuff. We're still learning, right?

One VEEERYY cool piece of code (which was MUCH easier in as3, unfortunately), is the weird code I've assigned to fillStyle. To make a long story short, this piece of code makes it so that the computer generates a new random color every iteration of the timer. Isn't that GREAT to look at??

Don't try to dissect it just yet (unless you're a Javascript whiz), but go ahead and assign this line of code to any fillStyle you want. You could make a rectangle switch colors randomly at every repetition, or make a line or curve flash a random color as it grows across the stage. See how this can be addicting?

Also, note in this code that I used a requestAnimationFrame which calls itself. We discussed that in the timer lesson. If that's still not clear, go ahead and refresh your memory. I'll wait here for ya. Promise.

Oh, and the window. before requestAnimationFrame is optional most of the time, so don't panic if you see it in one code example and not the next.

Keep this cool tip in mind as well: Javascript has some built-in Math functions that you can use to generate random numbers. We'll be going over the math stuff in later tutorials when we discuss physics, but remember this for the time being: if you multiply any positive number by Math.random() you get a random number between zero and that value. Look at this line in my code:

context.fillText("I'm learning HTML5 Game Development - world beware!",Math.random() * canvas.width,Math.random() * canvas.height);

We know already that this is a fillText method, but look at the x and y values for our text: they're appearing at random x and y coordinates! Like I said, multiply a positive number by Math.random() and you'll get a random number between 0 and that number. Here canvas.width is the number representing the width of our canvas and canvas.height is the height of our canvas. These are NUMBER values, so they can be set to random! And when the requestAnimationFrame repeats itself, a new random number is generated every time. So combine that with our random color in the fillStyle method and we've got ourselves a whole bunch of random stuff flying across the screen. Random!

Again, there are also a few other strange things in here, but we'll get to most of them throughout the course of the month. It's going to be a long journey, folks. Set a pace and don't make the mistake that so many people make by wasting all your energy in the beginning.

In fact, not to be a guru or anything, but dammit, having a personal pace is important for EVERYTHING you teach yourself in life. Look at all the folks who make resolutions every New Year, start off all Gung Ho, but forget all about them a couple weeks into the year. DON'T let yourself down like that! Aim to be one of the exceptions who sticks with it!

So now that I've got that soap box monologue out, let's move on to the second topic we said we'd discuss and that is adding images to our canvas. Now, the name of the method is drawImage() and if you go to the drawImage ice cream store there are three different flavors you can try:

Today we'll look at the first and second variety and tackle the last one when we talk about sprite sheets.

Let's roll up our sleeves and get started!

The important thing we need talk about here is attaching an event listener to image so that the canvas knows that the image has loaded.

An event listener, for those of you who don't know, is a piece of code that allows your code to communicate with all the neat stuff that can happen when people interact with their computers (and more!). Listeners are the CORE of interactivity. You can have listeners listen for the window loading, a key being pressed, a mouse click, a screen touch and a whole bunch of other stuff. Think about the whole scheme of things a minute:

How is the computer supposed to know what to do when an event takes place if you don't specify it?

Each listener is attached to its own function (event handler) which carries out the instructions you give it. You name the function, you attach the listener and you decide what gets carried out every time you call it. Pretty powerful stuff, huh?

With listeners I can:

...tell my character to move left when I hit the left key

...or I can have the start screen pop up after the window loads.

..or I can have the enemy ships explode when I put my greasy fingers on the touch screen of my mobile device.

etc. etc.

Now the structure of listeners is very simple. Let's walk through them step by step:

  1. You establish what it is that's doing the listening.
  2. you add the code: addEventListener preceded by a dot.
  3. You assign the type of event and stick it between quotes.
  4. You give a name to the function that will do the dirty work.
  5. You write false. Just trust me.

So take for example:

window.addEventListener("load",onLoad,false);

Step by step, we have:

  1. window
  2. addEventListener
  3. "load"
  4. onLoad <---- my made-up name
  5. false

Don't forget to put the dot after #1 and put #3,#4 + #5 in parenthesis, followed by a semicolon (we'll see everything together in a minute).

BUT we're not done yet! We still need to add the onLoad function we created. Otherwise, the computer listens for something and we never tell it what to listen to! It's like pretending to throw something, then watching your dog run off to catch it like an idiot.... it's just... WRONG!

So, right underneath we add our function called onLoad. And it goes a little something like this:

function onLoad()
{

}

That's it! And all the instructions that make the magic happen go inside the curly braces. So let's take theory out of the picture and make a practical example with it.

Now, as I mentioned before, if we slap an image onto the canvas, we should preload it. This is done by adding an event listener to it.

But before we need to do that, the computer needs to know WHICH image we want to load. Makes sense, right??

So we need to start off with these two lines of code:

var myImage = new Image();
myImage.src = "Like.png"; <-- for this exercise, save the image you want to import to canvas in the same directory as this html file.

Then we need to assign a listener to our image. We called it myImage, so let's go through the five event listener steps to get this image loaded, ok?

  1. myImage <------- the name we assigned our image.
  2. addEventListener <---- same old code as always
  3. "load" <---- because we're loading the image
  4. onLoad <----- a clever name we came up with for the function
  5. false <------- because... just don't worry about for now.

This 5-step process results in:

myImage.addEventListener("load",onLoad,false);

Got it? Now what do we need to add? That's right: our function!

so add the following line to the code right underneath the event listener:

function onLoad()
{
context.drawImage(myImage,0,0);
}

Making our final code:

<!doctype html>
<title>HTML GOOFIN' 1 </title>
<canvas id = "canvas" width="1200" height="400"></canvas>
<script>

var theCanvas = document.getElementById("canvas");
var context = theCanvas.getContext("2d");

var myImage = new Image();
myImage.src = "dragon.png";

myImage.addEventListener("load",onLoad,false);

function onLoad()
{
context.drawImage(myImage,0,0);
}
</script>

Save it, make sure that there's a pnj, gif, jpeg or whatever in the same directory as this file, substitute dragon.png with the name and extension of that file, then give it a run!

You should see whatever picture you specified appear in the top, left corner at the coordinates (0,0);

Work out for you? Have any problems? These can be tricky! Tweet me @benwhi for questions.

If everything was as smooth as butter, let's move on to the second species of drawImage(): the five argument variety.

Now, let's apply some common sense here:

If the first (3 argument) variety had image,x,y as values, what do you SUPPOSE the 5-value species has for values?

(Jeopardy theme)

Of course! The width and height values! Our second variety of drawImage lets us specify the dimensions of the image when we place it onto our canvas!

Try switching the old drawImage line with this slick, new variety:

context.drawImage(myImage,200,200,40,20);

and run it.

Whoa, it's a mini version of my image! How adorable!

You can take the steering wheel from here!

So now you know how to add images to your canvas. Neat, huh? Try some animations! Try some randomness! I want to see your experiments! Send over your code to Finnegan2100@gmail.com. I'd really LOVE to see what you guys come up with!

So that concludes another day of HTML5 gaming techniques. Feeling satisfied? A little perplexed as to how it all fits together? Tell ya what: seeing as tomorow marks my 7th tutorial, let's use every 7th day as a sort of workshop in which we do some experiments with the tools we've learned so far. If you've followed along from the start, you might not know how many cool things you've learned until you turn around and check out the view that was behind your back. Soak it up - you've worked hard!

Think about all the stuff we've gone over so far:

rectangles, lines, curves, drop shadows, gradients, timers, coordinates, arcs, event listeners, adding images, etc.

That's a LOT for 6 days! Pat yourselves on the back for following along and for your stickwithitness! If something's not clear, don't hesitate to go back and read up on it again.

So stay tuned! As always, thanks for following along! Code didn't work for you? Hate me? Are you my illegitimate child? Send input anytime!

Until tomorrow!

-Ben
@benwhi
Onward to Lesson Seven!
Back to Lesson Five
Back to Index