Ugly Code for Hidden Pictures

In some ways, this has been an extremely productive week and it’s only Monday, although when you work every day, it’s hard to say when your week starts. Sort of a zen-like question of where the circle begins, isn’t it?

I’m not complaining. I love my work so much it is hard for some people to understand. In another life (well, when I was so much younger that I looked like a different person, anyway), I was the world judo champion. I teach and coach judo now, when I can. Recently, I have tried to explain to some people that I could not come to tournaments because they take all day. They did not seem able to grasp the idea that I don’t WANT to drag myself away from work for an entire day.

Today, I was doing a “hidden pictures” game. You know, where you find things like a tomahawk , buffalo robe etc. Our main games are 3-d virtual worlds but they also have several casual games with them – tic-tac-toe with snares and rabbits instead of X’s and O’s , a memory game that includes both math problems and pictures from the game, and some random games I did when I planned to go in one direction and then ended up solving a problem another way. That’s how I ended up with a game that is like memory but you match three cards instead of two. It has nice graphics but it’s just hanging out there.

ANYWAY …. so, today, I got a lot done on the hidden pictures game but it was ugly code.

I used the HTML5 canvas element. One thing I did that was clever (if I do say so myself) is have the bottom layer be all of the objects that aren’t clicked on.

This is clever because it makes it harder for the player to find the objects on top that they are searching for, and it also makes it super-easy to create new games by simply swapping out the background layer underneath by changing one line:

bkgd.src =”new-background3.png”;

The rest of it, well, some of it, goes like this …. the drawAll function draws the two layers.

function drawAll() {
draw1();
draw2();

}

This draws the first layer

function draw1() {
ctx1.clearRect(0, 0, width, height);
ctx1.drawImage(bkgd, 0, 0);
}

Then I draw the objects that are hidden, in the second layer. The benefit of using canvas is since we don’t know what types of computers, screen sizes, etc. the students will be using for the game, and in fact, it varies greatly, I can define the canvas size and make sure the canoe is in the lake and not on top of a buffalo.

This draws the second layer

function draw2() {
ctx2.clearRect(0, 0, width, height);
ctx2.drawImage(arrows, 750,280);
ctx2.drawImage(arrows, 150,560);
ctx2.drawImage(knife, 0,360);
ctx2.drawImage(cup, 330,370);
ctx2.drawImage(cup, 730,470);
ctx2.drawImage(canoe, 30,380);
ctx2.drawImage(tomahawk, 650,300);
ctx2.drawImage(knifeh, 880,340);
ctx2.drawImage(knife, 340,580);
ctx2.drawImage(robe, 440,480);
ctx2.drawImage(robe, 790,520);
}

There is more code to this and as I was writing it I thought I should be making an array – but I didn’t because this way was quicker. It’s not that I didn’t know how to do it – in fact, I had it partially done but then realized I was talking less than 15 IF statements and I would be done in under half an hour. (Yes, I know, 15 IF statements – ew — but each of them came up with different clever sayings that I thought would amuse the kids – and then I changed that, too.) I also did another really sloppy thing. To make the item disappear I replace it with an empty image. There’s probably a better way, but this worked.

There is a method to my madness. No child playing it is going to be able to tell whether I made an array for the images or if I just drew them like this. Once we have students playing the game, we can decide whether we even want to retain it in the game. We may replace this with something where they actually wander around the 3-D world and look for objects, but we were running short on time to have two games completed by February.

On twitter, @davrs commented that every programmer ever had those interim solutions that became permanent. While mine don’t usually become permanent, they become semi-permanent more often than I would like. I wrote my first website using Netscape Composer, then, after a length of time I would be embarrassed to admit, I switched to frames with Adobe GoLive, which seemed like a pretty neat idea at the time, then to templates using Dreamweaver then to jQuery, javascript, HTML5 and co.

I guess that’s why I love my job so much – I’m always learning new things, even if the old ones DO hang around longer than iI had planned