Your browser does not support the canvas tag.

previous        Show / Hide Source        Download        next
//////////////////////////////////////////////////////////////////////////
//  Interactive Toy - Crane Game                              Irvin Lam //
//                                                                      //
//  Press Left and Right arrow keys to                                  //
//  move the crane on its horizontal axis                               //
//                                                                      //
//  Press Spacebar to take a chance at winning                          //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

void setup () {
  size (400, 400);
  frameRate(144);
  println("Press Left or Right arrow keys to move the crane");
  println("Press Spacebar to take a chance at winning");
}

boolean bun1here = true;
boolean bun2here = true;
boolean bun3here = true;

float x_bpos1 = (int)(random(140, 175));
float x_bpos2 = (int)(random(200, 270));
float x_bpos3 = (int)(random(300, 350));

float y_bpos1 = 275;
float y_bpos2 = 275;
float y_bpos3 = 275;


float moveSpeed = 2;
float gravity = 1.7;

boolean goLeft = false;
boolean goRight = false;
boolean space = false;
boolean grapple = false;
boolean grab1 = true;
boolean grab2 = true;
boolean grab3 = true;

float defaultPosx = 75;
float defaultPosy = 0;

float p1Posx = defaultPosx;
float p1Posy = defaultPosy;

void draw() {
  background(79, 149, 216);
  noStroke();
  ceiling();
  arcadeSpawner();
  door(100, 225, .4);
  crane(p1Posx, p1Posy);
  platform();
  bunnySpawner();
  dropZone();
  glass(); 
  pillar(0);
  pillar(370);
  controls();
  instruction();
}

//  Additional visual cues of controls
void instruction() {
  rectMode(CENTER);
  if (goRight == true) {
    fill(134, 11, 0);
  } else {
    fill(45);
  }
  //Right Arrow
  rect(145, 375, 30, 7);
  quad(140, 365, 155, 365, 170, 375, 160, 375);
  quad(170, 375, 160, 375, 140, 385, 155, 385);

  if (goLeft == true) {
    fill(134, 11, 0);
  } else {
    fill(45);
  }
  //Left arrow
  rect(55, 375, 30, 7); 
  quad(60, 365, 45, 365, 30, 375, 40, 375);
  quad(30, 375, 40, 375, 60, 385, 45, 385);


  //Space bar
  fill(190);
  quad(285, 378, 360, 378, 365, 387, 281, 387);
  fill(240);
  quad(290, 375, 355, 375, 360, 380, 285, 380); 
  fill(220);
  quad(285, 380, 360, 380, 362, 385, 283, 385);
}

void ceiling() {
  fill(100);
  rectMode(CORNER);
  rect(0, 0, 400, 50);
}

void door(int x, int y, float size) {
  fill(69, 67, 147);
  rectMode(CENTER);
  rect(x, y, 200*size, 400*size);
  fill(140);
  rect(x, y + (195*size), 200*size, 10*size);
  fill(25);
  rect(x, y-(190*size), 200*size, 20*size);
  rect(x-(100*size), y, 20*size, 400*size);
  rect(x+(100*size), y, 20*size, 400*size);

  fill(177, 11, 0);
  quad(x-(110*size), y+(200*size), x+(110*size), y+(200*size), x+(400*size), y+(800*size), x-(400*size), y+(800*size));
}

//  Spawns arcade machines in background
void arcadeSpawner() {
  for (int i = 0; i<2; i++) {
    arcade_m(225+(i*125), 225, .5);
  }
}

//  Draw base for arcade machine
void arcade_m(int x, int y, float size) {
  fill(69, 67, 147);
  rectMode(CENTER);
  rect(x, y, 200*size, 400*size);
  fill(80);
  rect(x, y+(50*size), 200*size, 75*size);
  fill(25);
  rect(x-(100*size), y, 10*size, 400*size);
  rect(x+(100*size), y, 10*size, 400*size);
  rect(x, y-(160*size), 200*size, 75*size);
  fill(153, 152, 196);
  rect(x, y-(60*size), 150*size, 100*size);
  fill(25);
  rect(x, y+(125*size), 200*size, 145*size);
}

void platform() {
  noStroke();
  fill(240);
  rectMode(CORNER);
  rect(0, 330, 400, 20);
}

void dropZone() {
  noStroke();
  fill(220);
  rectMode(CORNER);
  rect(0, 310, 125, 100);
}

void glass() {
  noStroke();
  rectMode(CORNER);
  fill(255, 50);
  rect(0, 0, 400, 400);
  //  Draws the light reflections on glass pane
  for (int i = 0; i<3; i++) {
    quad(-100+i*400, -100, -130+i*400, -100, -670+i*400, 500, -700+i*400, 500);
  }
}

void pillar(int xpos) {
  noStroke();
  rectMode(CORNER);
  fill(181, 219, 149);
  rect(xpos, 0, 30, 400);
  fill(245);
  rect(xpos+25, 0, 2, 400);
  rect(xpos+2, 0, 2, 400);
}

//  Initiates control panel elements
void controls() {
  noStroke();
  rectMode(CORNER);
  fill(187, 233, 217);
  rect(0, 350, 400, 50);
  joyStick(380);
  d_button();
}

//  Joystick drawing and movement
void joyStick(int y) {
  noStroke();
  ellipseMode(CENTER);
  if (goLeft == true) {
    fill(200);
    quad(75, y-50, 85, y-50, 105, y, 95, y);
    fill(25);
    ellipse(100, y, 20, 10);
    fill(200);
    ellipse(99, y-5, 10, 7);
    fill(177, 11, 0);
    ellipse(80, y-50, 20, 20);
  } else if (goRight == true) {
    fill(200);
    quad(125, y-50, 115, y-50, 95, y, 105, y);
    fill(25);
    ellipse(100, y, 20, 10);
    fill(200);
    ellipse(102, y-5, 10, 7);
    fill(177, 11, 0);
    ellipse(120, y-50, 20, 20);
  } else {
    fill(200);
    rectMode(CENTER);
    rect(100, y-25, 10, 50);
    fill(25);
    ellipse(100, y, 20, 10);
    fill(200);
    ellipse(100, y-5, 10, 7);
    fill(177, 11, 0);
    ellipse(100, y-50, 20, 20);
  }
}

//  Visual cue for when space button is pressed (depresses button)
void d_button() {
  fill(130, 15, 0);
  ellipseMode(CENTER);
  ellipse(250, 380, 30, 15);


  //button reaction
  if (space == true) {
    fill(177, 11, 0);
    ellipseMode(CENTER);
    ellipse(250, 378, 20, 10);
  } else if (space == false) {
    ellipseMode(CENTER);
    fill(157, 15, 0);
    ellipse(250, 378, 20, 10);
    fill(177, 11, 0);
    ellipse(250, 375, 20, 10);
  }
}

// Crane movement
void crane(float posX, float posY) {
  rectMode(CORNER);
  fill(240);
  rect(posX-10, posY-200, 20, 300);
  fill(150);
  rect(posX-25, posY+90, 50, 10);
  grappler(posX, posY);
  noFill();
  stroke(100);
  ellipse(posX-23, posY+95, 10, 10);
  ellipse(posX+23, posY+95, 10, 10);

//  Descends the crane
  if (space == true) {
    if (p1Posy >= 0 && p1Posy <= 125) {
      p1Posy += moveSpeed;
    } else {
      space = false;
      grapple = true;
      grappler(posX, posY);
    }
  }

//  Ascends the crane and brings it back to its original (x and y) position
  if (space == false && p1Posy != defaultPosy) {
    p1Posy -= moveSpeed;
    if (p1Posx >= defaultPosx && p1Posx != defaultPosx) {
      p1Posx -= moveSpeed;
    } else if (p1Posx <= 100 && p1Posx != defaultPosx) {
      p1Posx += moveSpeed;
    }
  }

//  Re-opens the crane
  if (p1Posy == defaultPosy && p1Posx == defaultPosx) {
    grapple = false;
  }
}

//  Draws the two different states of the grappler (open & close)
void grappler(float posX, float posY) {
  if (grapple == false) {
    fill(177, 11, 0);
    ellipseMode(CENTER);
    ellipse(posX-23, posY+95, 14, 14);
    ellipse(posX+23, posY+95, 14, 14);
    quad(posX-30, posY+95, posX -16, posY+95, posX-16, posY+135, posX-30, posY+130);
    quad(posX+16, posY+95, posX+30, posY+95, posX+30, posY+130, posX+16, posY+135);
  } else if (grapple == true) {
    fill(177, 11, 0);
    ellipseMode(CENTER);
    ellipse(posX-23, posY+95, 14, 14);
    ellipse(posX+23, posY+95, 14, 14);
    quad(posX-30, posY+95, posX -16, posY+95, posX, posY+135, posX-15, posY+130);
    quad(posX+16, posY+95, posX+30, posY+95, posX+15, posY+130, posX, posY+135);
  }
}


//  Spawns bunnies
void bunnySpawner() {
//  initiates the bunnies and draws them in their respective starting positions
  bunny_1(x_bpos1, y_bpos1);
  bunny_2(x_bpos2, y_bpos2);
  bunny_3(x_bpos3, y_bpos3);

//  Makes it so that the grapple carries the bunnies upwards with the crane
//
//  grab1,2,3 booleans are there to ensure that no more than one bunny can be moved at the same time

  if (grapple == true) {
    if (p1Posx < x_bpos1 + 10 && p1Posx > x_bpos1-10 && grab1 == true) {
      grab2 = false;
      grab3 = false;
      x_bpos1 = p1Posx;
      y_bpos1 = p1Posy+150;
      bunny_1(p1Posx, p1Posy + 150);
      bunny_2(x_bpos2, y_bpos2);
      bunny_3(x_bpos3, y_bpos3);
    } else if (p1Posx > x_bpos2-10 && p1Posx < x_bpos2 + 10 && grab2 == true) {
      grab1 = false;
      grab3 = false;
      x_bpos2 = p1Posx;
      y_bpos2 = p1Posy+150;
      bunny_1(x_bpos1, y_bpos1);
      bunny_2(p1Posx, p1Posy + 150);
      bunny_3(x_bpos3, y_bpos3);
    } else if (p1Posx > x_bpos3-10 && p1Posx < x_bpos3 + 10 && grab3 == true) {
      grab1 = false;
      grab2 = false;
      x_bpos3 = p1Posx;
      y_bpos3 = p1Posy+150;
      bunny_1(x_bpos1, y_bpos1);
      bunny_2(x_bpos2, y_bpos2);
      bunny_3(p1Posx, p1Posy+150);
    }
  }

//  Makes bunnies fall once the crane grappler is released
//  Also makes the bunny disappear if it goes beyond the height of the screen

  if (grapple == false) {
    if (x_bpos1 == defaultPosx) {
      y_bpos1 += gravity;
      bunny_1(x_bpos1, y_bpos1);
      if (y_bpos1 > 400) {
        bun1here = false;
        println("You Won a Bunny!");
        grab2 = true;
        grab3 = true;
      }
    }
    if (x_bpos2 == defaultPosx) {
      y_bpos2 += gravity;
      bunny_2(x_bpos2, y_bpos2);
      if (y_bpos2 > 400) {
        bun2here = false;
        println("You Won a Bunny!");
        grab1 = true;
        grab3 = true;
      }
    }
    if (x_bpos3 == defaultPosx) {
      y_bpos3 += gravity;
      bunny_3(x_bpos3, y_bpos3);
      if (y_bpos3 > 400) {
        bun3here = false;
        println("You Won a Bunny!");
        grab1 = true;
        grab2 = true;
      }
    }
  }
}

//  Drawing bunnies with seperate methods allows me to make individual bunnies disappear 
//  after it reaches a certain threshold, that way it doesn't fall infinitely.
void bunny_1(float x, float y) {
  if (bun1here == true) {
    bunny(x, y);
  }
}
void bunny_2(float x, float y) {
  if (bun2here == true) {
    bunny(x, y);
  }
}
void bunny_3(float x, float y) {
  if (bun3here == true) {
    bunny(x, y);
  }
}

//  Draw function for the bunny base
void bunny(float x, float y) {
  fill(237, 177, 230);
  ellipseMode(CENTER);
  //ears
  ellipse(x+10, y-10, 10, 40);
  ellipse(x-10, y-10, 10, 40);
  fill(255);
  ellipse(x+9, y-8, 10, 40);
  ellipse(x-9, y-8, 10, 40);
  //head
  fill(237, 177, 230);
  ellipse(x, y+10, 30, 35);
  //eyes
  fill(50);
  ellipse(x-7, y+4, 5, 5);
  ellipse(x+7, y+4, 5, 5);
  //nose
  triangle(x-2, y+7, x+2, y+7, x, y+11);
  //torso
  fill(237, 177, 230);
  ellipse(x, y+40, 35, 50);
  fill(255);
  ellipse(x, y+45, 30, 40);
  //feet
  fill(237, 177, 230);
  ellipse(x-10, y+65, 30, 10);
  ellipse(x+10, y+65, 30, 10);
}

//  Controls of the toy
void keyPressed() {
  //Left arrow
  if (keyCode == 37) {
    p1Posx -= moveSpeed;
    goLeft = true;
  }
  //Right arrow
  if (keyCode == 39) {
    p1Posx += moveSpeed;
    goRight = true;
  }
  //Space key
  if (keyCode == 32) {
    space = true;
  }
}

void keyReleased() {
  if (keyCode == 37) {
    goLeft = false;
  }
  if (keyCode == 39) {
    goRight = false;
  }
}