HTML Canvas: Going Ninja with .Net Magazine's Processing.js tutorial
Getting it working in Google Chrome (or not)
Getting started, I fired up a text editor and did step one only to find that nothing appeared in Google Chrome but Firefox was working perfectly. I was certain Google Chrome supported canvas, Wikipedia said so, this awesome visualisation of HTML5 readiness said so, hell even the Processing.js homepage said so, so it wasn't even that Processing JS was the problem. After pouring over the code and a bit of Googling I stumbled across this ticket on the Processing JS website, which basically points to a bug in Google Chrome as a the source of the problem, but only in certain versions.It turns out that processing adds a data-src attribute to the Canvas element, which is then used to pull in the Processing JS code via ajax. Some bug in Google Chrome means the ajax call fails, and therefore nothing happens. The work around is to include all your processing code on the page inside script tags, and use the processing.init.js script to load it in:
[cc lang="html"]
...
Playing with some crazy eyes
The problem with coding tutorials, I always find, is that you end up just copying and pasting without truly understanding the nuances of what you are doing: What does that function do? Which argument is which and what are they for? Why' is the code in that order? This was especially true with this Processing tutorial with it's smattering of trigonometry & use of functions like ellipse or arc with no description of the arguments.The only cure is to get stuck in.The first thing I decided I wanted to do, was change the way the eyes move. It seems wrong to me that they remain equi-distant even when they are to the far left and right, I wanted to make them get closer together. The ninja's head, body and eyes are all fixed on the y axis - they only move left-to-right so I figured I could do this quite easily.
The arc function used to draw the eyes takes 6 arguments: x position, y position, width, height, start angle, stop angle. Therefore to change the distance between the eyes I needed to change the first argument so that the way the x position of the left and right eye relate to each other is different based on the mouse's position.
I changed this:
[cc lang="javascript"]
arc(-10-sin(trackAngle)*7,8,6,6,TWO_PI,0); // Draw left eye
arc(10-sin(trackAngle)*7,8,6,6,TWO_PI,0); // Draw right eye
[/cc]
To this:
[cc lang="javascript"]
arc(-10-sin(trackAngle)(10-2trackAngle),8,6,6,TWO_PI,0); // Draw left eye
arc(10-sin(trackAngle)(10+2trackAngle),8,6,6,TWO_PI,0); // Draw right eye
[/cc]
The first part of the x position -10-sin(trackAngle) placed the eyes and makes them move with the head. The modifying value (originally 7) is what makes the eyes move further than the head - so they move further left or right relative to the heads position. trackAngle is measured in radians and therefore ranges between -1.2 and 1.2. I multiplied this by 2 to make it more significant, and used it to change what the modifying value is. Now the eyes not only move further relative to the head, but also relative to each other.
This is quite a weird effect - but I'm pretty pleased with it :)
Making a mini game
Once I was happy with the eyes, and had gotten a good grasp of the math going on, I decided to make it even more interactive, and turn it into a little game. The little ninja's arms flying all over the place seemed to want something to hit, so I introduced a dot which appears randomly somewhere on the screen, stays put for just over a second, and then disappears and reappears somewhere else. The dot disappears and reappears faster and faster as time goes on.I added some code to the mouseMoved function to test if the mouse's new position matches the dot's position, and if so adds one to the score and forces the dot to move again. Finally I added a box and some text to display the score in the top right corner, which was interesting as the tutorial doesn't cover text:
[cc lang="javascript"]
void drawScore()
{
PFont fontA = loadFont("Arial");
textFont(fontA, 36);
ninjaStyle(function(){ rect(width-50, height-(height-20), 30, 16) });
fill(#CD3700);
text(score, width-57, height-(height-41));
}
[/cc]
So there we have it, a mini ninja fighting game. You'll need to visit the demo page to play the game as this blog isn't (quite) yet running HTML5.
It doesn't really do any of the things I'd expect a real game to (yet), like have a start / pause button, a sound track, or a leader board. It could probably do with a samurai sword whizzing around and splitting the dots in half... obviously with plenty of blood and gore. It does however get progressively more difficult, the most I've scored is 92. The test is to see if anyone can show me a screenshot with a score of 100 and a broken scorebox ;)
Please note: the original code, imagery & styles were all published in .Net Magazine and were created by Alistair MacDonald of Bocoup.com