CMSC 110 (Introduction to Computing)
Spring 2016
Assignment #5
Due by 11:40 AM on Monday, April 4, 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 DgcObj.
Step 1: Cut and paste the following code into a file called sketch05<Emailusername>.pde (e.g., my sketch file would be called "sketch05dgc.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 "DgcObj" with the name of your creature object, which you will create in step 2. IMPORTANT: Do NOT change any code in the super class definition.
// The array of objects AnimatedObject[] objs = new AnimatedObject[20]; // Recursively drawn background from image provided by you PImage img; // Setup the sketch void setup() { size(800,600); img = loadImage("background.jpg"); // initialize all the objects for (int i=0; i < objs.length; i++) { objs[i] = new DgcObj(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 DgcObj.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.
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:
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.This method takes an array of all AnimatedObject objects, including the current object.
* 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) { }
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]) { ... }
What to produce: