Question
Please help with this! WIll give major thumbs up! I want to create a dog using processing shape-drawing primitives with Line/rect/quad/triangle /* KEYBOARD COMMANDS: /*
Please help with this! WIll give major thumbs up! I want to create a dog using processing shape-drawing primitives with Line/rect/quad/triangle
/* KEYBOARD COMMANDS: /* 'b' toggles display of bounding boxes for debugging, initially on /* 'f' toggles freezing of display in draw() off / on. /* '~' applies shuffle() to each Avatar object, repositioning the mobile ones. /* '!' applies forceshuffle() to each Avatar object, repositioning all of them. */
// The only GLOBAL VARIABLES are for the collection of Avatar objects. // All Avatar state variables go inside of Avatar-derived subclasses. Avatar avatars [] ; // An array holding multiple Avatar objects. int backgroundColor = 255 ; // Wraps from 255 back to 0. boolean showBoundingBox = true ; // toggle with 'b' key boolean isFrozen = false ; // toggle with 'f' key to freeze display
void setup() { // setup() runs once when the sketch starts, initializes sketch state. // size(1000, 800); fullScreen(P2D); background(backgroundColor); avatars = new Avatar [50] ; avatars[0] = new Professor(width/4, height/4, 2, 3, 2); // See constructors in their classes below to interpret parameters. int cyan = color(0, 255, 255, 255); // Red, Green, Blue, Alpha // By positioning based on system variables *width* and *height*, as opposed to // using fixed location numbers, your sketch will work with any display size. avatars[1] = new Furniture(width/2, 5, width, 10, cyan); // 10 pixels wide boundary is impenetrable avatars[2] = new Furniture(width/2, height-5, width, 10, cyan); avatars[3] = new Furniture(5, height/2, 10, height, cyan); avatars[4] = new Furniture(width-5, height/2, 10, height, cyan); avatars[5] = new Professor(3*width/4, 3*height/4, 2, 1, 1); int magenta = color(255, 0, 225, 255); final int barlength = 200 ; avatars[6] = new Furniture(barlength/2, height/2, barlength, 10, magenta); // 10 pixels wide boundary is impenetrable avatars[7] = new Furniture(width-barlength/2, 2*height/3, barlength, 10, magenta); avatars[8] = new Furniture(width/3, barlength/2, 10, barlength, magenta); avatars[9] = new Furniture(width/3, height-barlength/2, 10, barlength, magenta); color orange = color(255,184,0,255); avatars[10] = new Paddle(width/2, height/2, barlength, 10, .5, orange); for (int i = 11 ; i
void draw() { if (isFrozen) { return ; // toggle 'f' key to freeze/unfreeze display. } // draw() is run once every frameRate, every 60th of a sec by default. background(backgroundColor); // This erases the previous frame. rectMode(CENTER); ellipseMode(CENTER); imageMode(CENTER); shapeMode(CENTER); textAlign(CENTER, CENTER); // Display & move all avatars in a for loop. for (int i = 0 ; i
// KEYBOARD COMMANDS documented at top of this sketch. // System calls keyPressed when user presses a *key*. // Examples of control characters like arrows in a later example. void keyPressed() { if (key == 'b') { // toggle bounding boxes on/off showBoundingBox = ! showBoundingBox ; } else if (key == 'f') { isFrozen = ! isFrozen ; } else if (key == '~') { for (int i = 0 ; i
/** overlap checks whether two objects' bounding boxes overlap **/ boolean overlap(Avatar avatar1, Avatar avatar2) { int [] bb1 = avatar1.getBoundingBox(); int [] bb2 = avatar2.getBoundingBox(); // If bb1 is completely above, below, // left or right of bb2, we have an easy reject. if (bb1[0] > bb2[2] // bb1_left is right of bb2_right || bb1[1] > bb2[3] // bb1_top is below bb2_bottom, now reverse them || bb2[0] > bb1[2] // bb2_left is right of bb1_right || bb2[1] > bb1[3] // bb2_top is below bb1_bottom, now reverse them ) { return false ; } // In this case one contains the other or they overlap. return true ; }
/** * An *interface* is a specification of methods (functions) that * subclasses must provide. It provides a means to specify requirements * that plug-in derived classes must provide. * This interface Avatar specifies functions for both mobile & immobile * objects that interact in this sketch. **/ interface Avatar { /** * Avatar-derived class must have one or more variable * data fields, at a minimum for the x,y location, * where 0,0 is the middle of the display area. **/ /** Derived classes provide a constructor that takes some parameters. **/ /** * Write a display function that starts like this: pushMatrix(); translate(x, y); and ends like this: popMatrix(); with all display code inside the function. Write this in your derived class, not here in Avatar. In addition to translate, the display() code in your class must use one or more of scale (with 1 or 2 arguments), rotate, shearX, or shearY. You can also manipulate variables for color & speed. See my example classes for ideas. **/ void display(); /** Write move() to update variable fields inside the object. * Write this in your derived class, not here in Avatar. **/ void move(); /** * getBoundingBox returns an array of 4 integers where elements * [0], [1] tell the upper left X,Y coordinates of the bounding * box, and [2], [3] tell the lower right X,Y. This function * always returns a rectangular bounding box that contains the * entire avatar. Coordinates are those in effect when display() or * move() are called from the draw() function, **/ int [] getBoundingBox(); /** Return the X coordinate of this avatar, center. **/ int getX(); /** Return the Y coordinate of this avatar's center. **/ int getY(); /** Randomize parts of a *mobile* object's space, including x,y location. **/ void shuffle() ; /** Randomize parts of *every* object's space, including x,y location. **/ void forceshuffle(); }
/** * An abstract class provides helper functions and data fields required by * all subclasses. Abstract class CollisionDetector provides location and * scaling and rotation data fields that subclasses use. It also provides * helper functions, notably detectCollisions() for collision detection, that * are used by all subclasses. The keyword *protected* means that only subclasses * can use protected data & methods. The keyword *private* means that only the * defining class can use them, and *public* means that any class can use them. **/ abstract class CollisionDetector implements Avatar { protected int myx, myy ; // x,y location of this object protected float myscale ; // scale of this object, 1.0 for no scaling protected float speedX ; // speed of motion, negative for left. protected float speedY ; // speed of motion, negative for up. float myrot = 0.0 ; // subclasses may rotate & scale float rotspeed = 0.0, sclspeed = 0.0 ; // subclasses may change myscale, myrot in move(). // Testing shows that mobile shapes may push other mobile shapes // off of the screen, depending on order of collision detection. // Some Avatar classes may want their displays to wander around outside. // Data field xlimit and ylimit test for that. // See java.lang.Integer in https://docs.oracle.com/javase/8/docs/api/index.html protected int xlimitleft = Integer.MIN_VALUE ; // no limit by default protected int ylimittop = Integer.MIN_VALUE ; // no limit by default protected int xlimitright = Integer.MAX_VALUE ; // no limit by default protected int ylimitbottom = Integer.MAX_VALUE ; // no limit by default // The constructor initializes the data fields. CollisionDetector(int avx, int avy, float spdx, float spdy, float avscale, float scalespeed, float rotation, float rotatespeed) { myx = avx ; myy = avy ; speedX = spdx ; speedY = spdy ; myscale = avscale ; sclspeed = scalespeed ; myrot = rotation ; rotspeed = rotatespeed ; } void shuffle() { // default is to do nothing; override this in derived class. } void forceshuffle() { // default is to change location; add to this in derived class. myx = round(random(10, width-10)); // Put it somewhere on the display. myy = round(random(10, height-10)); } int getX() { return myx ; } int getY() { return myy ; } // Check this object against every other Avatar object for a collision. // Also make sure it doesn't wander outside the x and y limit values // set by the constructor. Putting detectCollisions() in this abstract class // eliminates the need to put it into multiple derived class move() functions, // which can simply call this function. protected void detectCollisions() { int [] mine = getBoundingBox(); for (Avatar a : avatars) { if (a == this) { continue ; // this avatar always overlaps with itself } int [] theirs = a.getBoundingBox(); if (overlap(this,a)) { if (mine[0] >= theirs[0] && mine[0] = theirs[0] && mine[2] = theirs[1] && mine[1] = theirs[1] && mine[3] = 1) println("DEBUG WENT OFF LEFT " + speedX); // Too many print statements, restrict to the bigger Avatars. // I usually comment out print statements until I am sure the bug is gone. } if (xlimitright != Integer.MAX_VALUE && myx >= xlimitright && speedX > 0) { speedX = - speedX ; myx = xlimitright - 1 ; if (myscale >= 1) println("DEBUG WENT OFF RIGHT " + speedX); } if (ylimittop != Integer.MIN_VALUE && myy = 1) println("DEBUG WENT OFF TOP " + speedY); } if (ylimitbottom != Integer.MAX_VALUE && myy >= ylimitbottom && speedY > 0) { speedY = - speedY ; myy = ylimitbottom - 1 ; if (myscale >= 1) println("DEBUG WENT OFF BOTTOM " + speedY); } } }
/** * Professor is my Avatar-derived class that displays & moves a mobile Professor. * You must write your own Avatar-derived class. You can delete class Professor * or use it to interact with your Avatar-derived class. **/ class Professor extends CollisionDetector { /* The data fields store the state of the Avatar. */ protected int legdist = 0 ; // You can initialize to a constant here. Professor(int avx, int avy, float spdx, float spdy, float avscale) { super(avx,avy,spdx,spdy,avscale,0,0,0); // Call the base class constructor to initialize its data fields, // then initialize this class' data fields. xlimitright = width ; ylimitbottom = height ; // limit off-screen motion to xlimitleft = 0 ; // one width or height off the display ylimittop = 0 ; // in either direction } void shuffle() { forceshuffle(); // always do it. } // The display() function simply draws the Avatar object. // The move() function updates the Avatar object's state. void display() { // Draw the avatar. pushMatrix(); // STUDENT *MUST* use pushMatrix() & translate first in display(). translate(myx, myy); scale(myscale); noStroke(); fill(240, 150, 150); ellipse(0, 0, 50, 40); // head, 0,0 is the conceptual center of the object. // An object rotates around its 0,0 point. quad(-5 , 0, 5 , 0, 10 , 40 , -10 , 40 ); // neck fill(0); // professor gown ellipse(0, 60 , 40 , 80 ); // torso stroke(0); // stick arms & legs strokeWeight(8); line(0, 60 , -20 -abs(10-legdist) , 120 ); // left leg line(0, 60 , 20 +abs(10-legdist) , 120 ); // right leg strokeWeight(5); line(0, 60 , -40 , 20 -2*abs(10-legdist) ); // left arm line(0, 60 , 40 , 20 +2*abs(10-legdist) ); // right arm strokeWeight(2); fill(0, 50, 255); ellipse(-10 , -5 , 10 , 10 ); // avatar's right side of glasses ellipse(10 , -5 , 10 , 10 ); // avatar's right side of glasses line(-5 , -5 , 5 , -5 ); // glasses connector line(-15 , -5 , -22 , -8 ); // left earpiece line(15 , -5 , 22 , -8 ); // right earpiece fill(0); ellipse(0, 1 , 5 , 5 ); // nose arc(0, 10 , 20 , 10 , 0, PI); // mouth quad(-30 , -15 , 30 , -15 , 15 , -30 , -35 , -30 ); popMatrix(); // STUDENT *MUST* use popMatrix() last in display(). } // The move() function updates the Avatar object's state. void move() { // get ready for movement in next frame. myx = round(myx + speedX) ; myy = round(myy + speedY) ; legdist = (legdist+1) % 20 ; detectCollisions(); } int [] getBoundingBox() { int [] result = new int[4]; result[0] = myx-round(40*myscale) ; // left extreme of left arm result[1] = myy - round(30*myscale); // top of hat result[2] = myx + round(myscale*max(20 +abs(10-legdist),40)); // max of right leg & arm result[3] = myy + round(120*myscale) ; // bottom of legs return result ; } }
/** * Class Furniture implements immobile obstacles as rectangles. * It adds fields for object width, height, and color. **/ class Furniture extends CollisionDetector { /* The data fields store the state of the Avatar. */ protected int mywidth, myheight, mycolor ; // Save the the problems of writing a new display function // by implementing no-op rotation and scaling here, // subclasses can use them. // rot is in degrees. // The constructor initializes the data fields. Furniture(int avx, int avy, int w, int h, int c) { super(avx,avy,0,0,1.0,0,0,0); mywidth = w ; myheight = h ; mycolor = c ; } // The display() function simply draws the Avatar object. // The move() function updates the Avatar object's state. void display() { // Draw the avatar. pushMatrix(); // STUDENT *MUST* use pushMatrix() & translate first in display(). translate(myx, myy); if (myrot != 0.0) { rotate(radians(myrot)); } if (myscale != 1.0) { scale(myscale); } fill(mycolor); stroke(mycolor); strokeWeight(1); rect(0,0,mywidth,myheight); // 0,0 is the center of the object. popMatrix(); // STUDENT *MUST* use popMatrix() last in display(). } // The move() function updates the Avatar object's state. // Furniture is immobile, so move() does nothing. void move() { } int [] getBoundingBox() { int [] result = new int[4]; result[0] = myx-mywidth/2 ; // left extreme of rect result[1] = myy - myheight/2; // top of rect result[2] = myx + mywidth/2; // right of rect result[3] = myy + myheight/2; // bottom of rect return result ; } } /** * Paddle extends class Furniture into a mobile, rotating rectangle. **/ class Paddle extends Furniture { // Call base class constructor to initialize its fields, // then initialize fields added by this class (none presently), // and let limits on off-screen excursions. Paddle(int avx, int avy, int w, int h, float rotatespeed, int c) { super(avx, avy, w, h, c); rotspeed = rotatespeed ; xlimitright = 2 * width ; ylimitbottom = 2 * height ; xlimitleft = - width ; // one width or height off the display ylimittop = - height ; // in either direction } void move() { myrot += rotspeed ; while (myrot >= 360) { myrot -= 360 ; } while (myrot
1. Write another direct subclass of abstract class CollisionDetector that implements your custom avatar You can use Processing shape-drawing primitives arc/ellipse/line/point/quad/rect/triangle, or a .svig vector graphics file, or include at most one jpg or .png image file in your class. You must use at least one Processing shape-drawing primitive. Your avatar class must be mobile and support creation of multiple objects. You may keep my Professor class and construct a small number of mobile Professor(s), or you may delete class Professor if you do not use it. Name your class whatever you want. Tell me its name in a comment at the top of the file 2. Your class' display) method must use pushMatrix0 and translate0 as the first two instructions. Make sure to have a well-defined 0,0 reference point within the body of your class objects. Denote the well-defined 0,0 reference point with a comment in the code. Also, popMatrix0 must be the final instruction in your display function. 3. Your move0 method can change the scale, rotation, color, or other custom properties of your avatar Make sure to call detectCollisions0 as the final step of move0 4. Redefine method getBoundingBox) in your class to accurately depict the bounding box for your object. Test this using the 'b' key command to show the bounding box. The box must encompass your avatar without being overly big. 5. Construct some number of your avatars and store them in the avatars[] array within setup0). Make sure your constructor initializes any data fields you add, and use super...) to call its base class constructor 6. Change the immobile Furniture class' methods to create obstacles (they work more like membranes) that use Processing's arc or ellipse or quad or triangle shapes instead of (or in addition to) my Furniture's use of rect. Make sure that getBoundingBox) is correct for your class. Place some of your immobile Furniture objects in your scene 7. Create a mobile peer class to Paddle that moves in a periodic manner using Processing shape(s). Make sure that getBoundingBox0 is correct for your class. Place some of your mobile class objects in your sketch. 8. Update your sketch documentation comments at the top to include your name and any other appropriate changes. Identify the classes you have added or changed in comments at the top; put the add/change detail comments within the classes themselves. Add documentation comments to your new classes. Make especially sure to document the body parts for your avatar similar to comments in Professor.display0. Make sure to document your avatar's internal 0,0 reference point within displayO 9. Test thoroughly. Each substantial bug results in a 10% deduction. Get with me during lab time or office hours if you get stuck. 10. Do not change any code other than that specified here without checking with me first. Interface Avatar and the abstract class Collision Detector MUST remain unchanged. Function setup) requires some new constructor calls for your classes and space in the avatars] array. You will need a new 1. Write another direct subclass of abstract class CollisionDetector that implements your custom avatar You can use Processing shape-drawing primitives arc/ellipse/line/point/quad/rect/triangle, or a .svig vector graphics file, or include at most one jpg or .png image file in your class. You must use at least one Processing shape-drawing primitive. Your avatar class must be mobile and support creation of multiple objects. You may keep my Professor class and construct a small number of mobile Professor(s), or you may delete class Professor if you do not use it. Name your class whatever you want. Tell me its name in a comment at the top of the file 2. Your class' display) method must use pushMatrix0 and translate0 as the first two instructions. Make sure to have a well-defined 0,0 reference point within the body of your class objects. Denote the well-defined 0,0 reference point with a comment in the code. Also, popMatrix0 must be the final instruction in your display function. 3. Your move0 method can change the scale, rotation, color, or other custom properties of your avatar Make sure to call detectCollisions0 as the final step of move0 4. Redefine method getBoundingBox) in your class to accurately depict the bounding box for your object. Test this using the 'b' key command to show the bounding box. The box must encompass your avatar without being overly big. 5. Construct some number of your avatars and store them in the avatars[] array within setup0). Make sure your constructor initializes any data fields you add, and use super...) to call its base class constructor 6. Change the immobile Furniture class' methods to create obstacles (they work more like membranes) that use Processing's arc or ellipse or quad or triangle shapes instead of (or in addition to) my Furniture's use of rect. Make sure that getBoundingBox) is correct for your class. Place some of your immobile Furniture objects in your scene 7. Create a mobile peer class to Paddle that moves in a periodic manner using Processing shape(s). Make sure that getBoundingBox0 is correct for your class. Place some of your mobile class objects in your sketch. 8. Update your sketch documentation comments at the top to include your name and any other appropriate changes. Identify the classes you have added or changed in comments at the top; put the add/change detail comments within the classes themselves. Add documentation comments to your new classes. Make especially sure to document the body parts for your avatar similar to comments in Professor.display0. Make sure to document your avatar's internal 0,0 reference point within displayO 9. Test thoroughly. Each substantial bug results in a 10% deduction. Get with me during lab time or office hours if you get stuck. 10. Do not change any code other than that specified here without checking with me first. Interface Avatar and the abstract class Collision Detector MUST remain unchanged. Function setup) requires some new constructor calls for your classes and space in the avatars] array. You will need a new
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started