CMSC 110 (Introduction to Computing)

Spring 2012

Assignment #5

Due by 4:00 pm on Tuesday, March 27, 2012

Task: Design an underwater creature that will live in a virtual aquarium.

The creature should be designed so that it can be instantiated as an object. You should be able to create instances of the creature with varying sizes through a single float argument passed into the constructor. In addition to the constructor, make sure that the class includes methods called display() and move().

Make sure to name the class as <Emailusername>Obj. For example, my creature will be defined in a class called MfrussoObj. Your class's constructor should take a single float argument that is approximately the creature's size. The value of this argument should be roughly the diameter of a circle that encompasses your creature. In addition to the constructor, make sure that the class includes one method called display(), and one called move() so that one can incorporate your creature into a sketch with other creatures.

Step 1:  Cut and paste the following code into a file called sketch05<Emailusername>.pde (e.g., my sketch file would be called "sketch05mfrusso.pde").  Save the sketch immediately.  This is the main file for running Assignment 5.  The driver code listed below should be used VERBATIM to run your class, with ONE exception:  in the setup() function, you will need to replace "MfrussoObj" with the name of your creature object, which you will create in step 2.  This is the ONLY change you should make to the code below.

/***************************************
 DO NOT MODIFY FROM HERE ...
****************************************/
 
/** The array of objects */
AnimatedObject[] objs = new AnimatedObject[20];

/** Constant for the sandHeight */
int SAND_HEIGHT = 40;

/** Setup the sketch */
void setup() {
  size(800,600);
  smooth();

  // initialize all the objects
  for (int i=0; i < objs.length; i++) {
    objs[i] = new MfrussoObj(random(30,50));   // change this line to call your constructor
  }
}

/** The main draw loop */
void draw() {
  
  // draw the tank background
  background(50,50,255);
  
  // draw the sandy bottom of the tank
  fill(168,168,50);
  rect(0,height-SAND_HEIGHT, width, SAND_HEIGHT);
  
  // draw the enhanced tank background, if necessary
  drawTankBackground();
  
  // draw and animate each of the objects
  for (int i=0; i<objs.length; i++) {
    objs[i].display(objs);
    objs[i].move();
  }
}

/** A super class for animated objects */
class AnimatedObject {
  
  /** Location fields inherited by all subclass */
  int x;
  int y;
  
  /** Size parameter inherited by subclass */
  float size = 50;
  
  /** Constructor
   *  Note that your constructor should accept a single float specifying the size, which will overwrite the inherited default value 50
   *  In addition, your constructor should initialize x and y to a starting location where your creature will appear
   */
  
  /** Displays the object
   *  Note: Implement only one of the display() functions in your subclass, but NOT both.
   *  @param objs an array of AnimatedObject objects in the environment
   */
  void display() { }
  void display( AnimatedObject[] objs ) { display(); }
  
  /** Advances the object's animation by one frame 
   *  Note: Implement only one of the move() functions, but NOT both.
   */
  void move() { }

  /* Methods that provide access to class data fields */
  int getX() {return x;}
  int getY() {return y;}
  float getSize() {return size;}
}

/**************************************
 ... TO HERE
***************************************/

Step 2:  Create a file called <Emailusername>Obj.pde (e.g., my file would be called MfrussoObj.pde) -- you can start a new file by creating a new tab. Cut and paste the following code into the file. This file should be saved to the same sketch directory as the one you created in step 1.  For ease of running the sketch, keep both files open as tabs in Processing.  It is ESSENTIAL that you name your creature object and file appropriately, since we will later combine all creatures together into a single aquarium.   

Complete the assignment by implementing your sea creature in this file.

// Keep this line as is, except for renaming the class
class <Emailusername>Obj extends AnimatedObject { 
  
  // Constructor
  <Emailusername>Obj(float size) { 
    // ...
  }

  // Displays the creature
  void display() {
    // ...
  }

  // Moves the creature
  void move() {
    // ...
  }
  
}

/** If you want to enhance the tank background
 *  to showcase your own project, you can put
 *  drawing code in this function, which is called
 *  near the start of the draw() function above.
 */
void drawTankBackground() {
}

The focus should be on the use of classes to define the object factory. You will need to write the constructor, a display() method and a move() method, as described above. Make sure that your creature is not too small, nor too large, as it will have to live in an aqauarium with 30 other creatures!

In addition to moving the x,y position of your creature over time, define at least one "move behavior" appropriate to your creature. Some creatures will swim like a fish, or a submarine, some will wiggle about, some might just stay in one place and rotate, bubble, etc.

You can write the drawTankBackground() function above to modify the default aquarium background, if you wish.  Note that if you choose to use the default background, you must still include this function in your file with an empty function body (as defined above).

Note that the final showcase will include one instance of each creature defined by you and your classmates swimming together in a single aquarium sketch.

Hints:

Extra Credit:

For up to 20 points extra credit, make your creature react to nearby creatures in the aquarium.  Instead of using the display() function defined in step 2, use the following in its place:

/** Displays the object
 *  @param objs an array of AnimatedObject objects in the environment
 */
 void display( AnimatedObject[] objs ) {
   // ...
 }
This version of the display() function takes an array of all AnimatedObject objects, including the current object. 

You can compare creature objects using the standard '==' and '!=' operators. For example, you may want to do the following to ensure that the current object is different than a given object in the array. 

    if (this != objs[i]) { ... }

You can access the coordinates of each object in the array using objs[i].getX() and objs[i].getY() methods, and use the return values to determine the distance between the current creature and another creature.

    float distance = dist( x, y, obj[i].getX(), obj[i].getY() );

You might want to make a creature that puffs up (remember to update your creature's size if you do this!) or blows bubbles whenever some other creature comes close, or maybe track which elements change position over time and only puff at objects that move.  Or, you might want to make a creature that runs away from all other creatrues and tries to hide near stationary objects.

If you do the extra credit, be certain to clearly mark in your submission that you're including the extra credit and include a description of your creature's behavior.

What to include:

What to hand in: