CMSC 110 (Introduction to Computing)

Spring 2016

Assignment #5

Due by 2:25 pm on Thursday, March 31, 2016

Task: Design an underwater creature that will live in a class aquarium. Please check out the big screen monitor in the CS hallway displaying past class aquariums!

Your creature class is by design a subclass of an abstract super class that is already laid out for you. There are numerous abstract methods that you must implement - see details below. You should be able to create instances of the creature with varying sizes through a single float argument passed into the two constructors. The value of this argument should be roughly the diameter of a circle that encompasses your creature. In addition to the constructors, the class should implement methods called display() and move(), as usual.

Make sure to name the class as <Emailusername>Obj. For example, my creature will be defined in a class called DxuObj.

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

// The array of objects 
AnimatedObject[] objs = new AnimatedObject[20];
// image file will be loaded in setup()
PImage img;

// Setup the sketch 
void setup() {
  size(800,600);
  // Recursively drawn background from image provided by you
  img = loadImage("background.jpg");

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

// The main draw loop
void draw() {  
  // display the tank background
  img.resize(width, height);
  image(img, 0, 0); 
  
  // draw and animate each of the objects
  for (int i=0; i<objs.length; i++) {
    objs[i].react(objs);
    objs[i].display();
    objs[i].move();
  }
}

/***************************************
 DO NOT MODIFY FROM HERE ...
****************************************/
// A super class for animated objects 
abstract class AnimatedObject {
  
  // Location fields inherited by all subclass 
  float x;
  float y;
  
  // Size parameter inherited by subclass 
  float size = 50;
  
  /** Constructors
   *  You are required to implement two construtors.
   */
  
  // Displays the object 
  abstract void display();
  
  // Advances the object's animation by one frame
  abstract void move();
 
// Display a signature block with name of creature

abstract void signature(float w, float h); /** Extra credit: up to 20 points.
* Modifies the object based on the other objects. *
Note that you are not allowed any drawing commands in this method * @param objs an array of AnimatedObject objects in the environment */ void react(AnimatedObject[] objs) { } // Methods that provide access to class data fields float getX() {return x;} float 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 DxuObj.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
   *  Accepts a single float specifying the size, which will overwrite the inherited default value 50
   *  In addition, this constructor should initialize x and y to a starting location where your creature will appear
   *  @param size the approximate size of the creature
   */
  <Emailusername>Obj(float size) { 
    // ...
  }

 /** Constructor that initializes x and y in addition to size
  *  @param x x-coordinate of the creature
  *  @param y y-corodinate of the creature 
  *  @param size the approximate size of the creature
  */
  <Emailusername>Obj(float x, float y, float size) { 
    // ...
  }


 /** Displays the object
  *  Note that you are not allowed to modify any fields in this method
  */
  void display() {
    // ...
  }

 /** Advances the object's animation by one frame
  *  Note that you are not allowed any drawing commands in this method 
  */
  void move() {
    // ...
  }

/** Display a signature block with name of creature
* and Your name with 0,0 representing the upper left
* hand corner of a wxh rectangle
* @param w the width of the signature block
* @param h the height of the signature block
*/

void signature(float w, float h) { // ... } }

You will need to write the constructors, a display() method and a move() method, as described above. Make sure that the only thing needed to changed the size of your creature is to change the float passed into the contructor, as it will have to live in an aqauarium with three dozen other creatures!

Basic movement of your sea creature just involves changing the x and y positions over time. However, you must make sure that the creature stays confined in the tank and does not disappear. Instead of simply bouncing the fish around or swimming in a straight line, think of more creative ways of modeling movement. For example, you can generate an invisible target (not drawn, but has some random x and y location), towards which your fish will swim. Once your fish gets into a certain radius of the target, it can suddenly dart away. You can regerate a new target every so many frames. The result of this will be a much more natural and deliberate fish movement. In addition to moving the x,y position of your creature over time, define at least one additional "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. Any rotation and translation that you need when drawing must be accomplished with transformations and the matrix stack, and any and all drawing must be accomplished in display() ONLY. Note that transformations are considered drawing related commands.

Step 3: You must implement an additional program to create a recursively-drawn aquarium background and save it in an image called "background.jpg", which the driver code provided above will load and display. You may draw inspirations from any of the class examples or other sources, but you must credit your sources. For example, you can choose a theme-appropriate background by adapting the recursive tree-drawing algoirithm to draw corals. We will however accept any recursively drawn backgrounds including those with more geometric patterns.

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:

Requirements:

  1. Your custom class extending AnimatedObject
  2. Superclass AnimatedObject is not modified
  3. A recursively drawn tank background stored in image "background.jpg"
  4. Implementation of your class constructors
    1. Constructors intializes class fields correctly
    2. Constructors called with a size will result in scaled versions of your creature and called with a position rsult in your creature being placed in the specified location
  5. Implementation of display() method
    1. display()is not allowed to modify any fields (class variables)
    2. display()is the only method allowed to have any drawing-related commands. Note that transformations are considered drawing related commands.
  6. Implementation of move() method
    1. Movement that changes your creature's location over time in the tank
    2. At least one additional "move behavior" that is appropriate to your creature, beyond the required change in location over time
  7. Any rotation and translation must be accomplished with transformations and the matrix stack
  8. A signature() method that displays a signature block with the name of the creature and your name at (0, 0) with parameterized width and height
  9. The drawing and movement of your sea creatures should not depend on any global variables except for the single global array that holds your creatures.
  10. A program that creates two or more instances of your creature swimming in your own creature tank with your recursive background
  11. For extra credit, an implementation of void react(AnimatedObject[] objs) that implements an advanced move behavior based on the location of other creatures in the tank (see below).
  12. Includes proper header and adequate comments - comment your class fields and methods!
  13. Drawing must scale properly regardless of the size of the sketch.
  14. Sign your work, using the classsignature()method.
  15. Interaction is optional. However, if you program it, you must program using the callback functions. You are not allowed to use the global variables (mousePressed, etc).

Extra Credit:

For up to 20 points extra credit, make your creature react to nearby creatures in the aquarium.  Implement the following method:

/** Extra credit: up to 20 points.
* Modifies the object based on the other objects. *
Note that you are not allowed any drawing commands in this method * @param objs an array of AnimatedObject objects in the environment */ void react(AnimatedObject[] objs) { }
This method 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 or blows bubbles whenever some other creature comes close. Or, you might want to make a creature that runs away from all other creatrues and tries to hide near stationary objects. Obviously, you should only modify your own creature in reaction. However, recall that you are NOT allowed any drawing commands in this method, so you must communicate whichever changes you want via changes of field values to display()

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 extra-credit behavior.

What to produce:

  1. The program
  2. An additional program that draws a recursively-rendered tank background and saves it in an image file called "background.jpg"
  3. In your usual write up (see below), include additional discussion that describes your recursive algorithm which generates the background. Also include figures that show progression of the recursion - show the result after one level of recursion, two levels, etc
  4. A write-up with your name, course and assignment number and a paragraph about the sketch, its inspiration, and how you designed and implemented it. Include a discussion about your experience working on this assignment. It should be a separate document and left in the sketch folder.
  5. A jpg image of your background called "background.jpg", in your sketch folder.
  6. A gif/jpg/png image of your sketch. Place in your sketch folder.
What to Hand in: