Categories
Technology

Save Dr. Dotty from the Quicksand

Copy from the Wayback Machine Archive.

Dr. Dotty is exploring in the jungle and accidently walks into quicksand. The object of the game is, of course, to save Dr. Dotty.

The Save Dr. Dotty from the Quicksand games are a variation of the old paper game “Hangmans’s Bluff”. The object of the game is to fill in all the missing letters from one or more words within a phrase and save Dr. Dotty from DOOM.

Playing the Game

-The playing board for each of the Quicksand games is 800 x 600 pixels.
-Each game has an opening animation, and an ending animation if you correctly find all the missing letters.
-Pressing the “ENTER” key after the opening animation stops will start the game.
-Type a letter into your keyboard and every place that the letter exists gets filled in.
-If you type in an incorrect letter, poor Dr. Dotty sinks a little further into the quicksand.
-Close the playing window at any time by clicking the space bar.

The Dr. Dotty games work with Navigator 4.x, Netscape 6.x, IE 4.x, IE 5.x, and IE 6.x, and Mozilla.

 

  • Game 1 If you know about hurricanes, you know the answer to the question in this game. However, you can find the answer in the How the Game Works section, below.
  • Game 2 If you know about minerals and mineral identifications, you know the answer to this game. However, you can find the answer in the How the Game Works section, below.

 

How the Game Works

The Dr. Dotty games use DHTML for all interactive effects. This includes the use of CSS to position elements as well as alter their presentation; and JavaScript to perform all actions, interactive or otherwise.

The elements of the game page are positioned using CSS2 absolute positioning. Doing this I can control the layout of the page at any time. Using absolute positioning also exposes all of the elements to script access once the page is loaded for a browser such as Navigator 4.x. All elements are exposed as part of a Document Object Model (DOM), and hence exposed to interactive scripting access for the IE 4.x and IE 5.x, Mozilla, and the upcoming Navigator 5.x browsers, but to ensure cross-browser and cross- version compatibility, I code to Navigator 4.x, which requires that the elements be positioned absolutely:

   <DIV id="dotty1" style="position:absolute; left: 20px; top: 20px">
   ...
   </DIV>

To ensure that the games work with both IE, Mozilla, and Netscape I used the Burning Bird X-Objects to hide most DHTML implementation techniques. Because of this, when I want to move an object to an absolute position of 100 pixels from the left, I can use the method exposed on the cross-browser objects:

   theobjs["dotty1"].objSetLeft(100);

I’ve also created a set of higher-level animation objects that use the cross-browser scripting objects and JavaScript timers to manage all animation effects. These Animation objects, are basically arrays of animations, with each step in the animation synchronized with matching steps in the other associated animations.

So, to show an element that both moves and clips, I create a new animation sequence (co-ordinated animations that are all performed sequentially in the order they are added to the sequence), and then attach one animation object to the sequence. The animation object is defined with a set number of animation steps, each played out after a specified number of microseconds. After the animation object is created, I then crate new Animator objects, one for the clipping animation and one for the move animation:

   var seq = new animatorSequence();
	
   anim = seq.newAnimator(10,100);
   anim.addAnimator(theobjs["dotty4"],"M",180,160);
   anim.addAnimator(theobjs["dotty4"],"C",0,0,330,200);

When the animation sequence is played, each successive steps of the animations contained in the sequence is synchronized and played:

    seq.play();

So, when Dr. Dotty moves across the screen in the opening sequence, one Animation Sequence is created for the entire opening animation; several Animations are created to handle such things as moving Dr. Dotty, showing the different word bubbles and words that he says, and even changing Dr. Dotty’s expression. Different types of Animators objects are created for each animation effect, and the Animators are added to Animation objects to provide for the synchronization for multiple-animator effects.

Want to see the code creating the animation sequence, animations, and animators for the opening animation? Well, it’s a bit long, but here you go:

function setup_start(){
   seq = new animatorSequence();

   // add animation objects to sequence
   // this animation plays for 200 microsecond, with each
   // step in the animation sequence timed at 20 microseconds --
   // 10 animation steps in all
   var anim = seq.newAnimator(20,200);

   // add animators
   anim.addAnimator(theobjs["dotty1"],"M",180,160);
   anim.addAnimator(theobjs["bubble1"],"M",180,400);
   anim.addAnimator(theobjs["bubble1"],"Z",4);
   anim.addAnimator(theobjs["words1"],"M",230,460);
   anim.addAnimator(theobjs["words1"],"Z",5);

   // second animation, this time one step at 100 microseconds 
   anim = seq.newAnimator(1, 100);
   anim.addAnimator(theobjs["words1"],"H");

   // third animation, 1 step, 1500 ms
   anim = seq.newAnimator(1, 1500);
   anim.addAnimator(theobjs["dotty2"],"S");
   anim.addAnimator(theobjs["words2"],"S");
   anim.addAnimator(theobjs["words2"],"Z",5);

   // fourth animation, 1 step 200 ms
   anim = seq.newAnimator(1, 300);
   anim.addAnimator(theobjs["dotty3"],"S");
   anim.addAnimator(theobjs["dotty2"],"H");
   anim.addAnimator(theobjs["words2"],"H");
   anim.addAnimator(theobjs["words3"],"S");

   // fifth animation, 1 step 2000 ms
   anim = seq.newAnimator(1, 2000);
   anim.addAnimator(theobjs["dotty1"],"H");
   anim.addAnimator(theobjs["words3"],"S");
   anim.addAnimator(theobjs["words3"],"Z",5);

   // sixth animation, 1 step, 100 ms
   anim = seq.newAnimator(1, 100);
   anim.addAnimator(theobjs["words3"],"H");
   anim.addAnimator(theobjs["dotty3"],"H");
   anim.addAnimator(theobjs["dotty4"],"S");
   anim.addAnimator(theobjs["words4"],"Z",5);

   // seventh animation, 1 step, 1000 ms
   anim = seq.newAnimator(1, 1000);
   anim.addAnimator(theobjs["words4"],"S");

   // eighth animation, 1 step, 1000 ms
   anim = seq.newAnimator(1, 1000);
   anim.addAnimator(theobjs["words4"],"H");
   anim.addAnimator(theobjs["words4"],"Z",5);

   // ninth animation, 1 step, 3000 ms
   anim = seq.newAnimator(1, 3000);
   anim.addAnimator(theobjs["words4"],"H");
   anim.addAnimator(theobjs["words5"],"S");
   anim.addAnimator(theobjs["words5"],"Z",5);

   // tenth animation, 1 step, 1000 ms
   anim = seq.newAnimator(1, 1000);
   anim.addAnimator(theobjs["words5"],"H");

   // eleventh animation, 1 step, 3000 ms
   anim = seq.newAnimator(1, 3000);
   anim.addAnimator(theobjs["bubble1"],"H");
   anim.addAnimator(theobjs["dotty5"],"S");
   anim.addAnimator(theobjs["bubble2"],"S");
   anim.addAnimator(theobjs["bubble2"],"Z",4);
   anim.addAnimator(theobjs["words6"],"S");
   anim.addAnimator(theobjs["words6"],"Z",5);

   // twelth animation, 1 step, 1000 ms
   anim = seq.newAnimator(1, 1000);
   anim.addAnimator(theobjs["words6"],"H");

   // thirteenth animation, 10 steps, 100ms (10 ms each) 
   anim = seq.newAnimator(10, 100);
   anim.addAnimator(theobjs["words7"],"S");
   anim.addAnimator(theobjs["title"], "M",200,500);

    // fourteenth animation, 10 steps, 100 ms
    anim = seq.newAnimator(10, 100);
    anim.addAnimator(theobjs["dotty5"],"H");
    anim.addAnimator(theobjs["words7"],"H");
    anim.addAnimator(theobjs["words8"],"S");
    anim.addAnimator(theobjs["words8"],"Z",5);
    anim.addAnimator(theobjs["title"], "M",300,500);
	

     // play all 14 animations, in order 
     // as they are defined in sequence array
     seq.play();
}

At the very end of the function that creates the opening animation sequence, the sequence is played.

One last aspect of the Dr. Dotty games is the interactive portion. This is handled by capturing the keypress event for the Web page, and passing the event to a function:

// handle keyboard events
if (navigator.appName != "Microsoft Internet Explorer") 
   document.captureEvents(Event.KEYDOWN);

document.onkeydown=keypress;

In the function, the keycode for the keypress event is accessed and compared to the letters for the answer: if a match is found, the letter is “filled in” in the answer (using DHTML to replace the existing underscore character with the letter); if a match is not found, Dr. Dotty is lowered into the quicksand further (using clipping to lower the good doctor, and DHTML “hide and show” to change Dr. Dotty’s message and expression).

Download the game source code from the link to the right and make your own version of the game. Have fun!