The Design and Implementation of Multimedia Software
An Example with Described Dynamic Visual Content

The Code for the Sprite

/**
 * An encapsulation of a Sprite that "swims" from left to right
 *
 * @author  Prof. David Bernstein, James Madison University
 * @see     "The Design and Implementation of Multimedia Software (c) 2011"
 * @version 1.0
 *
 * @augments AbstractSprite
 */

SwimmingFish.prototype = new AbstractSprite();
SwimmingFish.prototype.constructor = SwimmingFish;

/**
 * Explicit Value Constructor
 *
 * @param {Array} contents  The images of the swimming object
 * @param {float}    The width of the Stage
 * @param {float}    The height of the Stage
 * @param {float}    The speed of the swimming object
 */
function SwimmingFish(contents,
                      width, height, speed)
{
       this.contents = contents;
       
       this.maxX = width;
       this.maxY = height;       

       this.x    = Math.random()*this.maxX;
       this.y    = Math.random()*this.maxY;

       this.initialSpeed = speed;
       this.speed        = speed;       
       this.lastTime     = 0;
       this.timeInState  = 0;       

       this.stateChange  = 1;       
       this.state        = 1;       
       
       var r = Math.random();
       if      (r < 0.33)
       {
          this.state        = 0;       
          this.stateChange  = 1;       
       }
       else if (r < 0.66)
       {
          this.state        = 1;       
          this.stateChange  = 1;       
       }
       else
       {
          this.state        = 2;       
          this.stateChange  = -1;       
       }
       


       this.INITIAL_LOCATION = 0;    

       this.setLocation(this.x, this.y);       
       
       this.setVisible(true);   
    }



/**
 * Get the (current) content associated with this Sprite
 *
 * @returns {Content} The static visual content
 */
SwimmingFish.prototype.getContent = function()
{
   return this.contents[this.state];
}


/**
 * Handle a tick from the metronome
 * (required by MetronomeListener)
 *
 * @param {int} time   The time
 */
SwimmingFish.prototype.handleTick = function(time)
{
   var millisPerState    = 500 - this.speed*20;       

   this.timeInState += (time - this.lastTime);
   if (this.timeInState > millisPerState)
   {
      this.timeInState = 0;
      this.state += this.stateChange;
      if      (this.state == 2) this.stateChange = -1;
      else if (this.state == 0) this.stateChange =  1;
   }
   this.lastTime = time;       

   this.updateLocation();
}


/**
 * Update the location is this Sprite
 *
 * @private
 */
SwimmingFish.prototype.updateLocation = function()
{
   this.x += this.speed;
       
   if (this.x > this.maxX)
   {
      this.x     = this.INITIAL_LOCATION;
      this.y     = Math.random()*this.maxX;
      this.speed = this.initialSpeed;          
   }
   
   this.setLocation(this.x, this.y);
}