////S2

String title= "Monster is zapped by Witch. ";
String author= "Rahul Mathur";
String news="S2";
String hint1= "To place treat, click below horizon";
String hint2= "To zap or reset the monster click the buttons";

Button one, two, three, four;
Witch monika = new Witch();
Monster robert = new Monster();
Animal rosa= new Animal();
Tree[] h= new Tree[5];

int score=0;
float left=20, right=780, horizon=200, bottom=580;
float xTreat=0, yTreat;
float nearby=50;

void setup() {
  size( 900, 700 );
  horizon= height/2.6;
  one= new Button( "Zap", 50, 40, color(250) );
  two= new Button( "Back", 50, 80, color(100,0,100) );
  three= new Button( "Reset", 50, 120, color(250,0,250) );
  four= new Button( "Trees", 50, 160, color(180,15,15) );
  //
xTreat= width-45;
yTreat= random( horizon+20, height-20 );
  //
  randomTrees();
}
void randomTrees() {
  float top= horizon-45;
  for (int j=0; j<5; ++j) {
    h[j]= new Tree( random( left,right), random(top,bottom) );
  }
  background(0,50,0);
}

void draw() {
  scene();
  action();
  Trees();
  messages();
}

void scene() {
  background( 120,0,0 ); // night
  fill( 100,200,100 );
  rect( 0, horizon, width, height-horizon );     // grass;
  fill(300,330,250);
  float xMoon=width/2, yMoon=horizon/2;
  if (abs(xMoon-monika.x) <50) fill(255,255,50);
  ellipse( xMoon,yMoon, 80,80);             //Moon
  // Buttons
  one.show();
  two.show();
  three.show();
  four.show();
}
void Trees() {
  // Trees
  for (int j=0; j<4.5; ++j) {
   h[j].show();
  }
}

void action() {
 showTreat( xTreat, yTreat );
  // Monster chases treat
  robert.show();
  robert.move();
  // Witch rides broom 
  monika.show();
  monika.move();
  // Rabbit scoots around
  rosa.show();
  rosa.move();
}
void showTreat(float x, float y) {
  if (x <=0) return;
  float w=50, h=50;
  fill(random(250,255),0,0);
  ellipse( x,y, w-random(5), h-random(5) );
  fill (255,255,0);
  ellipse( x,y, w-random(5,10), h-random(5,10) );
  fill(random(250,255),random(250,255),0);
  ellipse( x,y, w-random(15,20), h-random(15,20) );
}
void messages() {
   fill(0);
  textSize(28);
  text( title, 10, 20 );
  textSize(16);
  text( "SCORE: "+score, width-200,30 );
  textSize(12);
  text( news, width-200, 50 );
  text( hint1, width/4, 40 );
  text( hint2, width/4, 55 );
  text( author, 10, height-10 );
}
//// Events ///
void keyPressed() {
  news= " "+key;
  if (key == 'q') { exit(); }
  if (key == 'a') { reset(); }
  if (key == 'z') { backWitch(); }
  if (key == 'w') { zap(); }
  if (key == 's') { randomTrees(); }
}
void mousePressed() {
  news="(" +(int)mouseX+ "," +(int)mouseY+ ")";
  if ( one.hit() ) { zap();  }
  else if ( two.hit() ) { backWitch();  }
  else if ( three.hit() ) { reset();  }
  else if ( four.hit() ) { randomTrees();  }
  else if ( rosa.clicked() ) { rosa.reset();  }
  else if ( monika.clicked() ) {  monika.reset();  }
  else if ( robert.clicked() ) { robert.reset();  }
  //
  else if (mouseY>horizon) {
  xTreat=mouseX;
  yTreat=mouseY;
    score -=15;
    news= "Candy was placed." ;
    robert.reset();
    monika.reset();
  }
}
void zap() {
  //// Witch zaps downward (wihh red laser);
  score -= 10;
  monika.countdown=60;
  background(0,90,0);
}
void backWitch() {
  //// Reverse direction for witch.
  monika.dx *= -1;
}
void reset() {
  //// Monster disappears
  robert.reset();
  monika.reset();
  rosa.reset();
}


class Button
{
  // Properties //
  float x=100, y=100;
  int w=80, h=30;
  String name= "Click here";
  color c=color (0, 200, 0 );
  
  
  // Constructions //
 Button() {this("Click here");  }
 Button(String name) { this(name, 100, 100);  }
 Button( float xx, float yy )  {
   this( "Click here", xx, yy );
 }
 Button( String name, float xx, float yy  ) {
   this( name, xx, yy, color(255,200,200) );
 }
 Button( String name, float x, float y, color c )
 {
   this.name=name;
   this.x=x;
   this.y=y;
   this.c=c;
 }
 
   // Methods //
   void show() {
   fill ( c );
   rect ( x,y,w,h );
   fill(0);
   textSize(25);
   text( name, x+10, y+20 );
 }
 boolean hit() {
   return(
    mouseX > x
    && mouseX < x+w
    && mouseY > y
    && mouseY < y+h );
 }
}

class Witch
{
  float x,y, dx;
  float w=40, h=80, hh=30;
  int countdown=0;
  Witch() {
      x=790;
      y=65;
      dx=-1;
  }
  void show() {
    if (x<-0) return;
    float broom=y+h;
    fill(255,100,0);
    ellipse( x,y, 25, hh );
    fill(0);
    rect( x-w/2, y+hh/2, w, h );
    triangle( x-10,y-hh/2, x+10, y-hh/2, x,y-45 );
    rect (x-20,y-15, 40,3 );
    fill(100,0,100);
    rect( x-60,broom,120,3 );
    triangle( x+50,broom, x+60,broom-12, x+60,broom+12 );
    if (countdown<=0) {return; }
    countdown -= 1;   // Zapping with laser
    if (countdown == 0) {
      news= "MISSED.";
      score -=40;
      return;
    }
    //Zapping -- laser beam 
    fill( 255,0,0 );
    rect( x+60,broom, 12,height, 8 );
    if (abs(x-robert.x) < 90) {
      news= "Monster was zapped!";
      score += 100;
      countdown=0;
      robert.reset();
    xTreat=0;
      background(255,0,255);
    } else if (abs(x-rosa.x) < 50) {
      news= "WHOOPS! You zapped the rabbit.";
      background(255);
      countdown=0;
      score -= 35;
      rosa.reset();
    }
  }
  void move() {
    if (countdown>0) { return; }      // Wait for countdown.
    x += dx;
   }
   void reset() { x=width-20; dx=-1.5; }
    boolean clicked() {
     return (dist( x,y, mouseX,mouseY ) < 20 );
    }
  } // class Witch //
  
  class Monster
  {
   float x=20,y=200, dx,dy;
   float w=60,h=120;
   void move() {
     if (xTreat<=0) { return; }
    dx= (xTreat-x) / random(900,1300);    // Chase the treat
    dy= (yTreat-y) / random(900,1300);
     x += dx;
     y += dy;
     if (near(xTreat,yTreat)) {
       news= "Monster ate the candy!";
       score -= 50;
     xTreat=0;
       robert.reset();
       monika.countdown=0;
     }
   }
   void reset() { x=0; }
   void show() {
     if (x<=0) return;
     float step=3;
     if (x%50 < 25) step= -step;
     fill(0,0,250);
     rect( x,y+step, w/2,h );
     rect( x+w/2,y-step, w/2,h );
     fill(255,100,255);
     ellipse( x+w/2,y-10, 45, 45 );
     fill (250);
     ellipse( x+w/2-10,y-15, 15,15 );   // eyes
     ellipse( x+w/2+10,y-15, 15,15 );
   }
   boolean near( float xx, float yy ) {
     return dist(x,y, xx,yy) < nearby;
   }
   boolean clicked() {
     return near( mouseX,mouseY );
   }
  }// class Monster //
  
  class Animal
  {
    float x,y,dx,dy;
    Animal() { reset(); }
    void reset() {
    x=20;
    y=random(200,500);
    println(horizon);
    dx=random(1,3);
    dy=random(1,3);
  }
  void move() {
    if (x>width+20 || x<20) dx= -dx;       // Bounce off boundaries
    if (y>height-20 || y<horizon+20) dy= -dy;
    x += dx;
    y += dy;
  }
  void show() {
  noStroke();
    fill( 250 );
    ellipse( x,y, 80, 30 );
    float front=x+35;
    float rear=x-40;
    if (dx<0) { front=x-10; rear=x+40; }
    ellipse( rear,y-10, 16,16 );            
    stroke(255);
    fill(255,150,150);
    triangle( front-20,y-8, front-12,y-8, front-16,y-20 ); 
    triangle( front-12,y-8, front-4,y-8, front-8,y-20 ); 
    stroke(0);
  }
  boolean near( float xx, float yy ) {
   return dist(x,y, xx,yy) < nearby;
  }
  boolean clicked() {
    return near( mouseX,mouseY );
  }
}// class Animal //

class Tree
{
   float x,y, w,h;
   color leaves, trunk;
   Tree( float x, float y )
   {
     this.x=x;
     this.y=y;
     this.w=random(100,100);
     this.h=random(100,150);
     this.leaves= color( random(250), random(100,250), random(10,00) );
     this.trunk= color( random(100,200), random(0,250), random(0,250) );
   }
   void show() {
     fill(leaves);
     ellipse( x,y, w,w );
     fill(trunk);
     rect( x-w/16,y+w/2, w/8,h );
   }
}

