Kick some booty with invisible Flash!
JavaScript Games #2 - Solitaire
Writing a midi hifi system in JavaScript
You are here: irt.org | Articles | JavaScript | Miscellaneous | JavaScript Games [ previous next ]
Published on: Friday 12th December 1997 By: Keith Drakard
This article will take you through the various steps needed to make a JavaScript game. I'm going to use a "Simple Simon" game as the working example, but it's possible to create many different games with JavaScript.
The rules of this game are as simple as the name suggests. A random sequence of colours is shown to you, typically by highlighting or flashing the colour, and then you try to repeat this sequence. The sequence gets longer and longer until either you make a mistake or complete a certain number of rounds. Okay, so it's not quite up to the frantic action of multi-player Quake, but a JavaScript game can still be a nice touch to add to your webpage.
Notes: This game should work on all browsers that support JavaScript images - ie. Netscape 3+ and Explorer 4+
Images
The traditional variant has four colours arranged in a circle:
We'll also need four more images to act as the "highlighted" colour. So first of all, we'll need to preload these eight images. This is done, as normal, by checking to see if the browser supports the image property and then creating each image in turn:
// Preload the images if (document.images) { yellow0 = new Image(); yellow0.src = "images/yellow.gif"; yellow1 = new Image(); yellow1.src = "images/yellow_d.gif"; green0 = new Image(); green0.src = "images/green.gif"; green1 = new Image(); green1.src = "images/green_d.gif"; blue0 = new Image(); blue0.src = "images/blue.gif"; blue1 = new Image(); blue1.src = "images/blue_d.gif"; red0 = new Image(); red0.src = "images/red.gif"; red1 = new Image(); red1.src = "images/red_d.gif"; }
Now that we have the required images, let's do something useful with them. The flash_quarter function is just an ordinary image swapper in disguise - all it does is to change one of the circle quarters into its "pressed down" version and then set a timer to pop the quarter back up to normal. By having only a short delay for the timer, the quarter appears to flash.
// Flash one of the quarters function flash_quarter(n) { // convert number to name of colour: if (n==1) colour= "yellow"; if (n==2) colour= "green"; if (n==3) colour= "blue"; if (n==4) colour= "red"; document.images[colour].src = eval(colour + "1.src"); setTimeout('document.images[colour].src = eval(colour + "0.src")', 80); }
If you've used random numbers before, chances are you've used Paul Houle's random number generator. The only difference now is that it just produces integers in the range 1 to 4, which is, oddly enough, the exact number of quarters we randomly pick from to create the sequence.
// The Central Randomizer 1.3 (C) 1997 by Paul Houle (houle@msc.cornell.edu) // See: http://www.msc.cornell.edu/~houle/javascript/randomizer.html // NOTE:- this example is set up to produce integers between 1-4 rnd.today=new Date(); rnd.seed=rnd.today.getTime(); function rnd() { rnd.seed = (rnd.seed*9301+49297) % 233280; return rnd.seed/(233280.0); } function rand() { return Math.ceil(rnd()*4); }
It's time to get down to the functions that make the game actually work. We need to create a few global variables to hold the data used by the rest of the script -
// Initialize global variables var count; // how much we've completed of the current sequence var round_number; // how long the current sequence is var difficulty; // how long the maximum sequence can be var rounds= new Array; // the total sequence of colours var interval= 500; // the interval between flashes (lower is harder) var on; // are we playing the game at the moment?
- and a function to set (or reset) these variables before every game. This set_up function should also create the whole sequence of colours so that we don't need to make any more until the next game:
// Set up the game function set_up() { count= 0; round_number= 0; on= 0; // find out the current difficulty level: var index= document.diff.level.selectedIndex; difficulty= document.diff.level.options[index].value; // create the sequence: for (var i=0; i<difficulty; i++) { rounds[i]= rand(); } }
We've got the sequence, all we have to do now is to display it - but only up to the current step in the sequence:
// Show the sequence function start_round() { if (!document.images) { // if browser does not support JavaScript images then say so and end alert('Sorry, your browser does not support JavaScript Images'); return; } document.text.area.value= ""; count= 0; on= 1; // but only up to the current step: for (var i=0; i<=round_number; i++) { setTimeout("flash_quarter(" + rounds[i] + ")", i*interval); } }
That's the output of the game taken care of, but it's not going to be much of a game if the player can't respond to the sequence. The user_play function is called every time a colour is clicked on by the player:
// User input function user_play(button) { // check that we're playing the game: if (on) { // show the results of the click: flash_quarter(button); if (rounds[count]!= button) { // uh oh.. wrong colour: document.text.area.value= "Sorry, you lose."; set_up(); } else if (count==round_number) { // right colour *and* we've completed the current sequence: round_number++; if (round_number==difficulty) { // the sequence is at an end so that's all folks: document.text.area.value= "Wahey, you win!"; set_up(); } else { // right colour, but the sequence isn't completed yet: setTimeout("start_round()", 1000); } } // next step in the sequence: count++; } else { // we're not playing yet: document.text.area.value= "Click START to play"; setTimeout("document.text.area.value=''", 400); } }
We've finished our coding and just need to write the HTML to put the code into practice. As some of you will have known, the circle at the start of this article was formed by putting the coloured quarters into each cell of a 2x2 table. You now have a choice on how you call the user input function from a click on a quarter, depending on which browser you're using:
<!-- best in: Netscape 3 :: works with Netscape 4, Explorer 4 --> <A HREF="javascript:user_play(1)"> <IMG SRC="images/yellow.gif" WIDTH="102" HEIGHT="102" BORDER="0" NAME="yellow"> </A>
<!-- best in: Explorer 4 :: doesn't work with Netscape --> <IMG SRC="images/yellow.gif" WIDTH="102" HEIGHT="102" BORDER="0" NAME="yellow" onClick="user_play(1);">
In this article, I'll be using the first choice since that works with a wider range of browsers. Now our 2x2 table can start to take shape:
<TABLE width="400" border="0" cellspacing="0" cellpadding="0"> <TR><TD COLSPAN="4" ALIGN="center"><FONT FACE="Arial, Helvetica, sans-serif"> <H2>Simon Says... JavaScript</H2> </FONT></TD></TR> <!-- the 2x2 table (honest :) --> <TR><TD COLSPAN="2" ALIGN="right" VALIGN="bottom"> <A HREF="javascript:user_play(1)"><IMG SRC="images/yellow.gif" WIDTH="102" HEIGHT="102" BORDER="0" ALT="Yellow" NAME="yellow"></A></TD> <TD COLSPAN="2" ALIGN="left" VALIGN="bottom"> <A HREF="javascript:user_play(2)"><IMG SRC="images/green.gif" WIDTH="102" HEIGHT="102" BORDER="0" ALT="Green" NAME="green"></A></TD> </TR> <TR><TD COLSPAN="2" ALIGN="right" VALIGN="top"> <A HREF="javascript:user_play(4)"><IMG SRC="images/red.gif" WIDTH="102" HEIGHT="102" BORDER="0" ALT="Red" NAME="red"></A></TD> <TD COLSPAN="2" ALIGN="left" VALIGN="top"> <A HREF="javascript:user_play(3)"><IMG SRC="images/blue.gif" WIDTH="102" HEIGHT="102" BORDER="0" ALT="Blue" NAME="blue"></A></TD> </TR>
The final things we need are a start game button, a text area for any textual information we show the player and a menu to choose a difficulty level:
<TR><TD COLSPAN="4"> </TD></TR> <TR><TD ALIGN="right"> <!-- the start game button: --> <FORM><INPUT TYPE="button" VALUE="Start Game" onClick="set_up(); start_round();"> </FORM></TD> <TD ALIGN="center" COLSPAN="2"> <!-- the text area: --> <FORM NAME="text"><INPUT TYPE="text" NAME="area" SIZE="20"> </FORM></TD> <TD ALIGN="left"> <!-- the difficulty menu: --> <FORM NAME="diff"><SELECT NAME="level" SIZE="1"> <OPTION VALUE="5">Easy<OPTION VALUE="10">Medium<OPTION VALUE="15">Hard </SELECT></FORM></TD> </TR> <TR><TD COLSPAN="4" ALIGN="center"> <BR></TD></TR> <TR><TD> </TD> <TD COLSPAN="2" ALIGN="center"><FONT FACE="Arial, Helvetica, sans-serif" SIZE="1"> <B>Last updated: 5th December 1997<BR> Created by Keith Drakard</B> </FONT></TD> <TD> </TD> </TR> </TABLE>
If you want to make the game harder, then increase the option values from 5, 10 and 15 to whatever length of sequence you'd like. Or add something like:
<OPTION VALUE="100">Very Hard
The above snippets of code and HTML were brought together to make this working example. You can also view the JavaScript source code.
Homework
That's all it takes to make a simple JavaScript game, but you don't have to leave it there. You could:
Kick some booty with invisible Flash!
JavaScript Games #2 - Solitaire
Writing a midi hifi system in JavaScript
JavaScript Beginners Start Here