Code refactoring, Inheritance and Polymorphism
class Butterfly { //fields float x; float y; float xSpeed; float ySpeed; int removeTimer =-1; float rotPos = PI/12; float rotVel = 0.07; Butterfly(float x, float y, float xSpeed, float ySpeed) { this.x=x; this.y=y; this.xSpeed=xSpeed; this.ySpeed=ySpeed; } void update() { move(); handleCollision(); if (removeTimer ==-1) { //When removeTimer not started yet drawButterfly(); //draw a normal bug } if (removeTimer >0) { removeTimer--; rotPos += rotVel; //make the wing rotate within (-PI/10, PI/10) if (rotPos > PI/10 || rotPos < -PI/10) rotVel = -rotVel; drawCapturedButterfly(); //Before removeTimer runs out draw captured bug } if (removeTimer==0) { //When removeTimer runs out butterflies.remove(this); //remove this butterfly from list. } } boolean isAlive() { return removeTimer==-1; } boolean captured() { boolean capped = false; if (isAlive()) { removeTimer=60; xSpeed=0; ySpeed=0; capped = true; } return capped; } void handleCollision() { if (x<-butterflyWidth/2) x=width+butterflyWidth/2; if (x>width+butterflyWidth/2) x=-butterflyWidth/2; if (y<-butterflyWidth/2) y=height+butterflyWidth/2; if (y>height+butterflyWidth/2) y=-butterflyWidth/2; } //methods void move() { y+=ySpeed; x+=xSpeed; } void drawCapturedButterfly() { //butterfly pushMatrix(); translate(x, y); //body fill(0); stroke(0); rect(-10, -40, 20, 80, ROUND); //attenae line(-10, -40, -10, -60); noFill(); arc(-20, -60, 20, 20, -PI, 0); //wings stroke(255, 50, 50); fill(0); //make left wing flap pushMatrix(); translate(-10, 0); rotate(rotPos); arc(0, 0, 80, 70, radians(170), radians(200)); popMatrix(); //make right wing flap pushMatrix(); translate(-10, 0); rotate(rotPos); arc(10, 0, 80, 70, radians(-30), radians(30)); popMatrix(); popMatrix(); } /*void drawButterfly() { //butterfly pushMatrix(); translate(x, y); //body fill(0); stroke(0); rect(-10, -40, 20, 80, ROUND); //attenae line(-10, -40, -10, -60); noFill(); arc(-20, -60, 20, 20, -PI, 0); line(10, -40, 10, -60); arc(20, -60, 20, 20, -PI, 0); //wings stroke(255, 50, 50); fill(255, 120, 120, 180); arc(-10, 0, 80, 70, radians(110), radians(250)); arc(10, 0, 80, 70, radians(-70), radians(70)); popMatrix(); } }*/ //Subclass overrides superclass drawButterfly() method to draw a boss charater void drawButterfly() { pushMatrix(); translate(x, y); scale(scale); if(removeTimer > 0) rotate(rotPos); //Boss will rotate whole body when captured before removeTimer runs out //As the Boss looks the same except for rotating body, so no separate method necessary //body fill(250, 150, 0); stroke(0); rect(-10, -40, 20, 80, ROUND); //attenae line(-10, -40, -10, -60); noFill(); arc(-20, -60, 20, 20, -PI, 0); line(10, -40, 10, -60); arc(20, -60, 20, 20, -PI, 0); //wings stroke(255, 50, 50); fill(0, 250, 250, 180); arc(-10, 0, 80, 70, radians(110), radians(250)); arc(10, 0, 80, 70, radians(-70), radians(70)); popMatrix(); } class BossButterfly extends Butterfly { int health=3; float scale = 1.5; //Timer used to gurangantee one click only reduce health by 1 //(otherwise one sticky click could be counted multiple times and thereby reduce health down to 0) int clickTimer; BossButterfly(float x, float y, float xspd, float yspd) { super(x, y, xspd, yspd); health=3; } } void update() { super.update(); //call parent class' update method to if (clickTimer>0) clickTimer--; //decrease clickTimer for each frame } boolean captured() { boolean bossCapped = false; if (health > 0) { if (clickTimer == 0) { //only when clickTimer runs out, health will be reduced by 1 health--; scale *= 0.85; //shrink by 15% with each hit clickTimer=30; //set the clickTimer so that a single click won't be incidentally counted as more than once } } else { //when heath reached 0 bossCapped = super.captured(); //call superclass captured method to return capped and incur boss removal } return bossCapped; }