Saturday, January 26, 2013

And the Winner IS... building an Array


In the last posting, we discovered that, using random numbers, we could shift part of our image to the right and make it appear that our dogs were trotting across the screen towards a finish line. 

Today, let's ask our JavaScript to actually tell us who the winner is.
We need a way to store the names of our six dogs and then print the correct name on the screen when the first one reaches the finish line. 


If you already know about arrays, skip down to the horizontal bar. The rest of us will take a minute to go over this topic quickly.

Coding languages give us a way to store values that we can call up later and manipulate when needed. These are called variables. Sometimes they contain numbers, and sometimes they store text. When they contain text we call them strings because we can think of them as a string of characters. Take a look at this line:



var thisDog = "Spot";

 
This creates a variable or a container that stores the characters S, p, o, and t in memory. That is simple enough if we had only one dog. 



An Array is a way of storing a collection of strings that share a common variable. We can create a list of names like this:

var thisDog = new Array();

thisDog[0] = "Arlo";
thisDog[1] = "O'Yeller";
thisDog[2] = "Brownie";
thisDog[3] = "Red Rover";
thisDog[4] = "Bo";
thisDog[5] = "Max";

Each of these values is the name of a different dog, but they all share the same variable: thisDog followed by a value in the square brackets which is an index to each item in our list. The cool thing about this is that our index can be a variable itself! That means we can write code like this: thisDog[dog]. It is no coincidence that I put the variable dog in the brackets. That's the variable that we used in our random number. It will be the one that just reached the finish line.
Let's write a new function to display the winner's name.

function showWinner(dog){
   ctx.fillStyle='White';
   ctx.font="24px Arial";
   ctx.textAlign="left";
   ctx.fillText(thisDog[dog] + " is the Winner!",canvasLeft + 20,150);
    }
 

We will also need to add a line to scooter() that will call this function at the end of the race. It is highlighted below:

     if (testSpot.data[0] > 0){
         clearInterval(delayLoop);
         showWinner(dog);
         }

Many of the lines in the new function will look familiar. They are like ones that we used to draw our dogs earlier. ctx.fillStyle= 'White'; sets the color of our text. This time we are using one of the HTML5 colors that all browsers will recognize. 

ctx.font="24px Arial"; sets both the size and font of the text. Notice that sometimes I have used 'single quotes' around my code and other times I have used "double quotes." It doesn't matter which ones you use, they both do the same thing. But if you want to include either of those characters in your string, make sure you package it between two of the other. We did this when we named or yellow dog: thisDog[1] = "O'Yeller";

ctx.fillText( ... ); is the line that puts the text on the canvas. It needs three values. The first is the text that you want to print. And the next two are the X,Y coordinates of a location on the canvas where you want the text to appear. These last two values can be expressions like: canvasLeft + 20 or absolute numbers like: 150. But look at how we have set up the text: thisDog[dog] + " is the Winner!" 

We are going to pull the name of the winner our of our array using the variable dog that we passed into this function. And then we use the + to add the string " is the Winner!" after it.

I skipped one line: ctx.textAlign="left"; This tells your computer how to place the text in relation to the X,Y coordinates in ctx.fillText(); Other choices are: right and center.

In the next post we will explore an alternate way of moving the dogs. In our first version the dogs stand still while they wait for their random number to come up and then scoot forward. Let's see if we can smooth this out by having each dog move in turn but make their step forward a random distance.

As always, you can copy the full script from this session below and paste it into your own editor. Experiment with it, and make it your own. C U next time.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="generator" content="CoffeeCup HTML Editor (www.coffeecup.com)">
    <meta name="description" content="">
    <meta name="keywords" content="">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="viewport" content="width=device-width; initial-scale=1.0; user-scalable=1;">
    <title>Dog Race</title>
    <style>body{color:#FFFFFF}</style>
    <script type="text/javascript">
    var canvasLeft = 120;
   
    var myRed = "#FE0000";         //red - first value is 254
    var myBlue = "#0200DD";        //blue - first value is 2
    var myYellow = "#FCFF00";      //yellow - first value is 252
    var myMagenta = "#660066";     //magenta - first value is 253
    var myOrange = "#FF6600";      //orange is - first value is 255
    var myGreen = "#06FF00";       //green is - first value is 6
    var myBrown = "#993300";       //brown is - first value is 153
    var myBackground = "#007777";  //background -- first value is 0
   
function canvasDogRaces(){

    // Get the canvas element.
    canvas = document.getElementById("myCanvas");

    // Make sure you got it.
    if (canvas.getContext){
        ctx = canvas.getContext("2d");
       
        clearCanvas(myBackground);
       
        drawDog(myGreen, canvasLeft + 20, 10);
        drawDog(myYellow, canvasLeft + 20, 70);
        drawDog(myBrown, canvasLeft + 20, 130);
        drawDog(myRed, canvasLeft + 20, 190);
        drawDog(myBlue, canvasLeft + 20, 250);
        drawDog(myMagenta, canvasLeft + 20, 310);

        ctx.strokeStyle = 'black'
        ctx.beginPath();
        ctx.lineWidth = 1;
        ctx.moveTo(canvasLeft + 580,15);
        ctx.lineTo(canvasLeft + 580,380);
        ctx.closePath();
        ctx.stroke();
        delayLoop=self.setInterval(function(){scooter(15)},2);

    }else{

       alert("Your browser does not\n support 'Canvas'");

    }

 }

 var dogImage = 0;
 var delayLoop = 0;
 var runningDogX = canvasLeft;
 var testSpot = 0;


 function scooter(){
     var dog = Math.floor(Math.random() * 6);
     dogCatcher(dog);
     myDogSpot(canvasLeft+2, dog * 60 + 15);
   
     testSpot = ctx.getImageData(canvasLeft+575,dog* 60 + 31,10,10);
     ctx.putImageData(testSpot,20,dog * 60 + 30);
     if (testSpot.data[0] > 0){
         clearInterval(delayLoop);
         showWinner(dog);
         }
     }
   
 var thisDog = new Array();
 thisDog[0] = "Arlo";
 thisDog[1] = "O'Yeller";
 thisDog[2] = "Brownie";
 thisDog[3] = "Red Rover";
 thisDog[4] = "Bo";
 thisDog[5] = "Max";

 function showWinner(dog){
     ctx.fillStyle='White';
    ctx.font="24px Arial";
    ctx.textAlign="left";
    ctx.fillText(thisDog[dog] + " is the Winner!",canvasLeft + 20,150);
    }
   
 function goAgain(){
     location.reload();
     }

 function dogCatcher(dog){
     dogImage = ctx.getImageData(canvasLeft, dog * 60 + 15, 577, 55);
     }
   
function myDogSpot(x,y){
    ctx.putImageData(dogImage,x, y);
    }

 function drawDog(thisColor,dogX,dogY){
      // draw tail
     ctx.beginPath();
     ctx.lineWidth = 3;
     ctx.strokeStyle = 'black';
     ctx.moveTo(dogX + 5,dogY+32);
     ctx.lineTo(dogX-10,dogY + 25);
     ctx.closePath();
     ctx.stroke();
   
     // draw body
     ctx.fillStyle = thisColor;
     ctx.beginPath();    
     ctx.rect(dogX+8,dogY + 30,24,16);
     ctx.rect (dogX,dogY + 35, 10, 25);
     ctx.rect (dogX + 30,dogY + 35, 10, 25);
     ctx.fill();
     ctx.arc(dogX + 8, dogY + 38, 8,  0, 2*Math.PI, true);
     ctx.arc(dogX + 32, dogY + 38, 8, 0, 2*Math.PI, true);
     ctx.closePath();
     ctx.fill();
   
     // draw head
     ctx.beginPath();
     ctx.arc(dogX + 36, dogY + 22, 8,  0, 2*Math.PI, true);
     ctx.closePath();
     ctx.fill();
     ctx.beginPath();
     ctx.arc(dogX + 40, dogY + 22, 8, 0, Math.PI, false);
     ctx.closePath();
     ctx.fill();
   
     // draw nose
     ctx.fillStyle = 'black';
     ctx.beginPath();
     ctx.rect(dogX +46,dogY +22,3,3);
     ctx.closePath();
     ctx.fill();
   
     // draw eye
     ctx.beginPath();
     ctx.rect(dogX +40,dogY +20,3,3);
     ctx.closePath();
     ctx.fill();
   
     // draw ear
     ctx.beginPath();
     ctx.arc(dogX + 30, dogY + 18, 4, Math.PI, 0.2 *Math.PI, false);
     ctx.closePath();
     ctx.fill();

 }
   

 function clearCanvas(thisColor){          
       ctx.fillStyle = thisColor;
       ctx.rect(canvasLeft,0,600,400);
       ctx.fill();
 }

 </script>
 </head>
 <body onload="canvasDogRaces()" bgcolor="#339999">    

    <h3>     

        <div id="rowOne_text">Welcome to the Races</div>     

        <div id="rowTwo_text">Pick Your Dog</div>   

    </h3>

 

    <canvas id="myCanvas" width="840" height="400" ;">  

    </canvas>

</body>
</html>

No comments:

Post a Comment