Your browser does not support the canvas tag.

previous        Show / Hide Source        Download        next
///////////////////////////////////////////////////////////////////////////////
/*                     Object-Oriented Toy - Hungry Panda
                             By Anita (YinTing) He
 
               Game entails:
                   - Floating dandelions
                   - Cute panda that waters the bamboos when the
                     mouse is clicked
                   - Water sprays/drops that come out of the can
                   - Randomly generated speed, position, & color
                     of each bamboo shoot
                   - Bamboos that grows faster when mouse pressed
                     & more bamboos that grows out 
                   - Updating emojis/emotions of the Panda -v-
 
 *////////////////////////////////////////////////////////////////////////////

///////////////////////VARIABLES & DECLARATION////////////////////////////////

//Declare Arrays
Dandelion[] dandelions = new Dandelion[20];
BambooShoots[] bamboos = new BambooShoots[15];
Water[] waterDrops = new Water[100];

//State variables
boolean gameEnd = false;
float growTime;
float appendTime = 20;

//////////////////////////////////CODE///////////////////////////////////////

void setup()
{

  size (800, 600);
  frameRate(30);
  smooth();
  
  //Print instructions
  println ("The Panda is hungry! Press and hold the mouse to water the bamboos and make them grow faster");

  //Initialize bamboos
  for (int i = 0; i < bamboos.length; i++) {
    bamboos[i] = new BambooShoots();
  }

  //Initialize dandelions
  for (int x = 0; x < dandelions.length; x++) {
    dandelions[x] = new Dandelion();
  }

  //Initialize bamboos
  for (int z = 0; z < waterDrops.length; z++) {
    waterDrops[z] = new Water();
    
  }
}


void draw()
{

  //Set background
  drawBG();

  //Update objects
  updateWateringCan();
  updateBamboos();

  //Draw objects
  drawPanda();
  drawDandelions();
  drawBamboos();
  drawWaterDrops();
  displayEmotions();
  
}


///////////////////////////////FUNCTIONS/////////////////////////////////////

/*-------------------------------------------------*/
//                                                 //
///////////////////Interactions//////////////////////
//                                                 //
/*-------------------------------------------------*/

void updateBamboos() {

  if (mousePressed){
    growTime ++;
    
    //Set so new bamboos grow after a certain period of time so it doesn't cluster
    if (growTime == appendTime){
      //New bamboo shoots
      BambooShoots moreBamboos = new BambooShoots();

      //Append to array
      bamboos = (BambooShoots[]) append (bamboos, moreBamboos);
        
      //Reset growTime so another appends in 20 frames
      growTime = 0;
    }
  }
}

/*-------------------------------------------------*/

void updateWateringCan() {

  if (!mousePressed) {
    wateringCanStatic();
  } else if (mousePressed) {
    wateringCanPour();
  }
}

/*-------------------------------------------------*/

void drawWaterDrops() {
  if (mousePressed) {
    for (int z = 0; z < waterDrops.length; z++) {
      waterDrops[z].spray();
      waterDrops[z].display ();
    }
  }
}

/*-------------------------------------------------*/
void displayEmotions() {
  noStroke();
  rectMode(CORNER);
  ellipseMode(CORNER);

  //Display "..." when nothing is pressed & bamboo shoots are still growing

  if (!mousePressed && gameEnd == false) {
    fill(0);
    
    ellipse(320, 360, 15, 15);
    ellipse(350, 360, 15, 15);
    ellipse(380, 360, 15, 15);
  }

  //Display music note when mouse is pressed & bamboo shoots are still growing

  if (mousePressed && gameEnd == false) {
    fill(0);
    
    rect(355, 350, 5, 40);
    rect(385, 350, 5, 40);
    rect(355, 350, 35, 5);
    rect(355, 360, 35, 5);
    ellipse(346, 382, 14, 11);
    ellipse(376, 382, 14, 11);
  }

  //Display heart when bamboo shoots have reached the top
  if (gameEnd == true) {
    fill(240, 100, 145);
    ellipseMode(CORNER);

    ellipse(348, 350, 33, 35);
    ellipse (372, 350, 33, 35);
    triangle(350.5, 378, 401, 379, 376.5, 397);
  }
  
}

/*-------------------------------------------------*/
//                                                 //
///////////////////Draw Arrays///////////////////////
//                                                 //
/*-------------------------------------------------*/

void drawDandelions() {
  
  for (int x = 0; x < dandelions.length; x++) {
    dandelions[x].floating ();
    dandelions[x].display ();
  }
  
}

/*-------------------------------------------------*/

void drawBamboos() {
  
  for (int i = 0; i < bamboos.length; i++) {
    bamboos[i].grow ();
    bamboos[i].display ();
  }
  
}

/*-------------------------------------------------*/
//                                                 //
///////////////Draw static objects///////////////////
//                                                 //
/*-------------------------------------------------*/

void wateringCanStatic() {
  
  ellipseMode(CORNERS);
  fill(0);
  noStroke();

  //Panda paws
  ellipse(395, 512, 455, 550);

  //Body
  quad(270, 420, 305, 450, 300, 470, 260, 430);
  quad(305, 410, 370, 410, 390, 520, 285, 520);

  //Handle
  noFill();
  stroke(0);
  strokeWeight(10);

  ellipse(350, 430, 400, 475);

  //Reset stroke
  strokeWeight(1);
  noStroke();
  
}

/*-------------------------------------------------*/

void wateringCanPour() {
  
  ellipseMode(CORNERS);
  fill(0);
  noStroke();

  //Panda paws
  ellipse(385, 460, 445, 500); 

  //Body
  quad(265, 470, 315, 490, 310, 510, 258, 482);
  quad(300, 450, 355, 435, 405, 536, 305, 560);

  //Handle
  noFill();
  stroke(0);
  strokeWeight(10);

  ellipse(350, 449, 395, 493);

  //Reset stroke
  strokeWeight(1);
  noStroke();
  
}

/*-------------------------------------------------*/

void drawPanda() {

  ellipseMode(CORNERS);

  //Black circles back
  fill(0);
  noStroke();

  ellipse(410, 377, 470, 438);
  ellipse(700, 380, 740, 420);
  ellipse(705, 502, 770, 540);

  //Drawing the body
  fill(255);
  stroke(0);
  strokeWeight(10);  

  arc(412, 341, 755, 620, 5.5*PI/6, 12.5*PI/6);
  ellipse(407, 471, 538, 553);
  ellipse(515, 471, 745, 560);
  ellipse(465, 490, 650, 560);

  //Covering up the lines
  fill(255);
  noStroke();

  ellipse(560, 460, 747, 545);
  ellipse(417, 440, 605, 535);
  ellipse(445, 520, 545, 549);

  //Black circles front
  fill(0);
  noStroke();

  ellipse(571, 525, 645, 570);
  ellipse(440, 480, 475, 520);
  ellipse(530, 480, 570, 525);
  ellipse(492, 495, 511, 509);
  arc(570, 380, 635, 450, 7*PI/6, 13*PI/6);
  
}

/*-------------------------------------------------*/

void drawBG() {

  noStroke();

  //Sky gradient
  float bgYPosition = 600;

  for (float x = 182; x > 9; x-=1) {
    fill (x, x+80, 249);
    rect(0, bgYPosition, width, 5);
    bgYPosition -= 5;
  }

  //Ground
  rectMode(CORNERS);
  ellipseMode(CORNERS);

  fill(160, 147, 120);
  rect(0, 520, width, height);
  fill(58, 64, 64);
  ellipse(40, 520, 300, 570);
  
}

/*-------------------------------------------------*/
class BambooShoots {

  //Data
  PVector position;
  PVector velocity;

  float sproutLocation;
  color bambooColor;

  //Constructor
  BambooShoots() {

    bambooColor = color (random(60, 100), random (139, 246), random(60, 118));
    sproutLocation = random(100, 250);

    //Assign random value to position.x since only y is needed
    position = new PVector (0, 540);
    velocity = new PVector (random(0.001, 0.3), random(0.001, 0.3));
    
  }
  
  /*-------------------------------------------------*/

  void display() {
    
    rectMode(CORNERS);
    noStroke();

    //Draws bamboo shoot
    fill(bambooColor);
    rect(sproutLocation, 550, sproutLocation-10, position.y);

    //Draws leaves once the height of the bamboo is high enough that the leaves don't appear below the soil
    stroke(bambooColor);
    strokeWeight(2);

    if (position.y < 508) {
      line(sproutLocation-10, position.y +40, sproutLocation-20, position.y + 30);
      triangle(sproutLocation-30, position.y+16, sproutLocation-20, position.y+30, sproutLocation-30, position.y+22);
      triangle(sproutLocation-20, position.y+30, sproutLocation-30, position.y+40, sproutLocation-26, position.y+32);
    }

    //reset stroke
    noStroke();
    
  }

  /*-------------------------------------------------*/

  void grow() {
    
    //Makes bambo grow upwards
    position.sub(velocity);

    //Set end game for emotion updates
    if (position.y < 0) {
      gameEnd = true;
    }

    //When mouse is pressed, bamboos grow at a faster rate
    if (mousePressed) {
      velocity.mult(1.01);
    }

    //When mouse isn't pressedm bamboos revert to initial growth rate
    if (!mousePressed) {
      velocity = new PVector (random(0.001, 0.3), random(0.001, 0.3));
    }
  }
}
class Dandelion {

  //Data
  PVector position;
  PVector velocity;

  float dandelionSize;

  //Constructor
  Dandelion() {

    dandelionSize = random (7, 15);

    position = new PVector (random(0, width+150), random(0, 540));
    velocity = new PVector (random(0.2, 0.7), random(0.2, 0.7));
    
  }

  /*-------------------------------------------------*/

  void display() {

    ellipseMode(CENTER);
    noStroke();

    //Draw glow
    fill(241, 255, 215, 108);
    ellipse(position.x, position.y, dandelionSize*1.7, dandelionSize*1.7);

    //Draw circle
    fill(255, 170);
    ellipse(position.x, position.y, dandelionSize, dandelionSize);
    
  }

  /*-------------------------------------------------*/
  
  void floating() {

    //Make the dandelions float up
    position.sub(velocity);
    
    //Once dandelions reaches edge, they respawn on the bottom right part of the screen
    if ((position.x < 0) || (position.y < 0)) {
      position.x = random(150, width+250);
      position.y = height;
      
    }
  }
}
class Water {

  //Data
  PVector position;
  PVector velocity;

  color waterColor = color(random(100, 255), 255, 255);

  //Constructor
  Water() {
    
    position = new PVector (random(230, 258), random(460, 490));
    velocity = new PVector (random(-4, -1), random(2, 4));
    
  }

  /*-------------------------------------------------*/

  void display() {
    
    rectMode(CENTER);
    noStroke();
    fill(waterColor);

    //Draw individual water drops
    rect(position.x, position.y, 5, 5);
    
  }

  /*-------------------------------------------------*/
  
  void spray() {
    
    //Move the water
    position.add(velocity);

    //If water reaches the y edge, it respawns near the nozzle
    if ((position.y < 460) || (position.y > 555)) {
      position.y = random(460, 490);
      position.x = random(220, 258);
      
    }
  }
}