Home Articles FAQs XREF Games Software Instant Books BBS About FOLDOC RFCs Feedback Sitemap
irt.Org

Related items

Kick some booty with invisible Flash!

JavaScripting Essentials

JavaScript Bookmarklets

Why bother with JavaScript?

JavaScript Games #2 - Solitaire

Writing a midi hifi system in JavaScript

JavaScript Beginners Start Here

Keeping Count of Downloads

Online JavaScript Resources

JavaScript Games

You are here: irt.org | Articles | JavaScript | Miscellaneous | JavaScript Games [ previous next ]

Published on: Friday 12th December 1997 By: Keith Drakard

Introduction

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:

YellowGreen
RedBlue

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);
}

Random Numbers

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);
}

Game Code

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);
  }
}

The HTML Wrapper

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">&nbsp;</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">&nbsp;<BR></TD></TR>

  <TR><TD>&nbsp;</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>&nbsp;</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

Working Example and Source Code

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:

Related items

Kick some booty with invisible Flash!

JavaScripting Essentials

JavaScript Bookmarklets

Why bother with JavaScript?

JavaScript Games #2 - Solitaire

Writing a midi hifi system in JavaScript

JavaScript Beginners Start Here

Keeping Count of Downloads

Online JavaScript Resources

Feedback on 'JavaScript Games'

©2018 Martin Webb