Your browser does not support the canvas tag.

previous        Show / Hide Source        Download        next
//Interactive Toy: Puppet
//By: Andrew Guagliano
//Teacher: Nicolas Hestler
//Student Number: 991405014
//Due Date: Oct 1, 2018

////DESCRIPTION////
//Control the puppet with your mouse and keyboard! The puppet will start out on 
//the table. Use your mouse to lift it up and move it side to side. If you want to
//move the arms and legs, use your keyboard to do so (controls listed below). If
//the puppet's clothes aren't quite your style, you can use your left mouse button
//to change them to a completely new, random colour. When you're done, you can 
//place the puppet back on the table.

////CONTROLS////
//MOUSE: move puppet up and down, plus left and right
//LEFT MOUSE BUTTON: randomize clothing colour
//A/Z: move left arm up and down
//S/X: move left leg up and down
//D/C: move right arm up and down
//F/V: move right leg up and down


////////////////////////////////
  /////Global Variables///////
////////////////////////////////

//Control Points for Limbs
float lHandY;
float rHandY;
float lFootY;
float rFootY;

//Random Colours
float rCol = random(255);
float gCol = random(255);
float bCol = random(255);

////////////////////////////////
  //////Setup Function///////
////////////////////////////////

void setup() {
  //set the size of the window
  size (400, 400);
  //get rid of the cursor
  noCursor();
}

////////////////////////////////
  ///////Draw Function////////
////////////////////////////////

void draw() {
  //set background
  background(190,190,230);
  //Call all functions
  backgroundStripes();
  desk();
  leftLeg();
  rightLeg();
  leftArm();
  rightArm();
  drawBody();
  drawHead();
}

////////////////////////////////
  //////Draw Right Leg////////
////////////////////////////////

//NOTE: I sincerely struggled to get the legs to look natural. I wanted to get the
//legs moving up and down consistently with the rest of the body, but I found it
//incredibly difficult to do that while also making it seem like the legs could be
//lifted up off the table. Essentially what happened is that in order for the lift
//off the table to look natural, the rFHeight variable needed to be static in the 
//else statement, but the rest of the body needed to be moving. This worked perfectly
//until I tried to incorporate the movement of the limbs. I tried many things to 
//make this look natural, such as adding the rLY variable to it, as well as the 
//rFootY variable (as well as both together), but these nor anything else I tried 
//(such as adding rFootY to every value in the if statement) were able to work. 
//The result is that they end up looking like the foot is floating in space at 
//certain points in the sketch. Unfortunately, due to the time constraints, I had 
//to leave this function in an incomplete state. This was likely too ambitious
//of an angle for this project, considering the sheer amount of work due in the 
//weeks prior and the short timeframe we had to complete this. In the end it doesn't
//look terrible, but it's not what I set out to achieve and I wanted to at least 
//make it known that I made an effort in this portion. Hopefully in the feedback you
//can let me know what I may have done to get this to work properly?

void rightLeg() {
  
//Declare variables
  float rLHeight;
  float rLY;
  float rFHeight;
  float rLX;
  
 //Assign buttons to move limbs
 //I figured out how keyPressed works via https://processing.org/reference/key.html
 //as well as the Gone Fishing example
  if (keyPressed) {
    if (rFootY>-90){
      if (key == 'f' || key == 'F') {
        rFootY--; 
      }
    }if (rFootY<30){
      if (key == 'v' || key == 'V') {
        rFootY++; 
      }
    }
  } 
    
    //Move with the rest of the body
    if (mouseY>250) {
        rLHeight = 350;
        rFHeight = 360;
    } else if(mouseY<67){
        rLHeight=230+(mouseY/5);
        rFHeight=283+(mouseY/5);
    } else if (mouseY<130) {
        rLY = (mouseY);
        rLHeight = 177+rLY;
        rFHeight = 230+rLY;
    } else {
        rLY = (mouseY/2.8);
        rLHeight = 261+rLY;
        rFHeight = 360;
  }
  
  //Constrian X
    if (mouseX<60) {
        rLX=60;
    } else if (mouseX>330) {
        rLX=330;
    } else {
        rLX = mouseX;
  }
  
  //Draw line for string
    strokeWeight(0.5);
    stroke(0);
    line(115+rLX,rFHeight+rFootY,rLX+50,-200);
    
  //Draw line for leg
    stroke(rCol, gCol, bCol);
    strokeWeight(20);
    line(50+rLX, rLHeight, 100+rLX, rFHeight+rFootY);
    
  //Ellipse for shoe
    fill(0);
    noStroke();
    ellipse(115+rLX,rFHeight+rFootY,50,30);
}

////////////////////////////////
  ///////Draw Left Leg////////
////////////////////////////////

void leftLeg() {
  
//Declare variables
  float lLHeight;
  float lLY;
  float lFHeight;
  float lLX;
  
//Assign buttons to move limbs
  if (keyPressed) {
    if (lFootY>-90){
      if (key == 's' || key == 'S') {
        lFootY--; 
      }
    } if (lFootY<30){
        if (key == 'x' || key == 'X') {
          lFootY++; 
        }
     }
  } 
 
 //Move with rest of body
   if (mouseY>250) {
       lLY=mouseY/5;
       lLHeight = 350;
       lFHeight = 360;
   } else if(mouseY<67){
       lLY=0;
       lLHeight=230+(mouseY/5);
       lFHeight=283+(mouseY/5);
   } else if (mouseY<130) {
       lLY = (mouseY);
       lLHeight = 177+lLY;
       lFHeight = 230+lLY;
   } else {
       lLY = (mouseY/2.8);
       lLHeight = 261+lLY;
       lFHeight = 360;
   }

  //Constrian X
    if (mouseX<60){
      lLX=60;
    }else if (mouseX>330){
      lLX=330;
    }else{
      lLX = mouseX;
    }
    
  //Draw line for string
  strokeWeight(0.5);
  stroke(0);
  line(-115+lLX,lFHeight+lFootY,lLX-50,-200);
  
  //Draw line for leg
  stroke(rCol, gCol, bCol);
  strokeWeight(20);
  line(-50+lLX, lLHeight, -100+lLX, lFHeight+lFootY);
  
  //Draw ellipse for shoe
  fill(0);
  noStroke();
  ellipse(-115+lLX,lFHeight+lFootY,50,30);
}

////////////////////////////////
  //////Draw Right Arm////////
////////////////////////////////

void rightArm() {
  
//Declare variables
  float rAHeight;
  float rAY;
  float rAX;
  
//Move with rest of body
  if (mouseY>250) {
      rAHeight = 300;
  } else if (mouseY<65) {
      rAY = (mouseY/5);
      rAHeight = 102+rAY;
  } else {
      rAHeight = mouseY +50;
  }
  
//Constrian X
  if (mouseX<60){
    rAX=60;
  }else if (mouseX>330){
    rAX=330;
  }else{
    rAX = mouseX;
  }
 
//Assign buttons to move limbs
  if (keyPressed) {
     if (rHandY>-90){
       if (key == 'd' || key == 'D') {
         rHandY--; 
       }
    }if (rHandY<30){
        if (key == 'c' || key == 'C') {
          rHandY++; 
        }
     }
  }
  
  //Draw line for string
  strokeWeight(0.5);
  stroke(0);
  line(150+rAX,rAHeight+60+rHandY,rAX,-200);
  
  //Draw line for arm
  stroke(rCol, gCol, bCol);
  strokeWeight(20);
  line(150+rAX, rAHeight+60+rHandY, 50+rAX, rAHeight+20);
  
  //Draw hand
  fill(160, 120, 100);
  noStroke();
  ellipse(150+rAX,rAHeight+60+rHandY,30,30);
}

////////////////////////////////
  ///////Draw Left Arm////////
////////////////////////////////

void leftArm() {
  
//Declare variables
  float lAHeight;
  float lAY;
  float lAX;

//Move with rest of body
  if (keyPressed) {
    if (lHandY>-90){
      if (key == 'a' || key == 'A') {
        lHandY--; 
      }
    }if (lHandY<30){
       if (key == 'z' || key == 'Z') {
         lHandY++; 
       }
     }
  }

    if (mouseY>250) {
      lAHeight = 300;
  } else if (mouseY<65) {
      lAY = (mouseY/5);
      lAHeight = 102+lAY;
  } else {
      lAHeight = mouseY +50;
  }
  //Constrian X
    if (mouseX<60){
      lAX=60;
  }else if (mouseX>330){
      lAX=330;
  }else{
      lAX = mouseX;
  }
  
  //Draw a string
  strokeWeight(0.5);
  stroke(0);
  line(-150+lAX,lAHeight+60+lHandY,lAX,-200);
  
  //Draw the leg
  stroke(rCol, gCol, bCol);
  strokeWeight(20);
  line(lAX-150, lAHeight+60+lHandY, lAX-50, lAHeight+20);
  
  //Draw ellipse for hand
  fill(160, 120, 100);
  noStroke();
  ellipse(-150+lAX,lAHeight+60+lHandY,30,30);
}

////////////////////////////////
  /////////Draw Head//////////
////////////////////////////////

void drawHead() {
  
//Declare variables
  float yHeight;
  float hY;
  float hX;
  
//Move with rest of body
    if (mouseY>325) {
      yHeight = 325;
      hY = 50;
  } else if (mouseY<70) {
      hY = (mouseY/5);
      yHeight = 55+hY;
  } else {
      yHeight = mouseY;
      hY = (mouseY/5);
  }

     if (mouseX<60){
       hX=60;
  }  else if (mouseX>330){
       hX=330;
  }  else{
       hX = mouseX;
  }

  //Draw the string
  strokeWeight(0.5);
  stroke(0);
  line(hX,yHeight,hX,-200);
  
  //Draw the arm
  noStroke();
  fill(160, 120, 100);
  ellipse(hX, yHeight, 100, 100);
  
  //Draw eyes
  fill(0);
  ellipse(hX+23, yHeight-20, 10, 10);
  ellipse(hX-23, yHeight-20, 10, 10);
  
  //Draw the hat
  stroke(255-rCol,255-gCol,255-bCol);
  strokeWeight(5);
  //Fill and stroke are 255-xCol to be complementary of body colour
  fill(255-rCol,255-gCol,255-bCol);
  rect(hX+42,yHeight-30,hX-40,yHeight-75);
  line(hX+55, yHeight-30, hX-55, yHeight-30);
  
  //Draw smile
  strokeWeight(1);
  stroke(0);
  noFill();
  curve(hX+50, yHeight-50, hX+23, yHeight+20, hX-23, yHeight+20, hX-50, yHeight-50);
  noStroke();
}

////////////////////////////////
  /////////Draw Body//////////
////////////////////////////////

void drawBody() {
//Declare variables
  float bHeight;
  float bY;
  float bX;

    if (mouseY>250) {
      bHeight = 250;
      bY = 50;
  } else if(mouseY<67){
      bY=-67+(mouseY/5);
      bHeight=120+bY;
  } else if (mouseY<150) {
      bY = (mouseY)-120;
      bHeight = 120+bY;
  } else {
      bHeight = mouseY;
      bY = (mouseY/5);
  }
  
     if (mouseX<60){
       bX=60;
  }  else if (mouseX>330){
       bX=330;
  }  else{
       bX = mouseX;
  }
  fill(rCol,gCol, bCol);
  rectMode(CORNERS);
  noStroke();
  rect(bX-65, 310+bY, bX+65, bHeight);
}

////////////////////////////////
  /////////Draw Wall//////////
////////////////////////////////

void backgroundStripes(){
  noStroke();
  rectMode(CORNER);
  
  //Create stripes on wall
  for (int s=0;s<=400;s=s+40){
    fill(255,255,255,50);
    rect(s,0,40,400);
    fill(100,100,100,50);
    rect(s+10,0,20,400);
  }
  
  //Create shadow from table
  for (int s=0;s<=150;s=s+1){
    fill(0,0,0,0+s*2);
    rect(0,230+s,400,1);
  }
}

////////////////////////////////
  /////////Draw Desk//////////
////////////////////////////////

void desk(){
 fill(180,150,130);
 rect(0,250,400,150);
 
 //Create gradient for light
  for (int s=0;s<=150;s=s+5){
    fill(255,255,255,0+s);
    rect(0,270+s,400,5);
  }
 //Create small shadow at end of table
  for (int s=0;s<=150;s=s+1){
    fill(0,0,0,20-s);
    rect(0,250+s,400,1);
  }
}

////////////////////////////////
  /////Randomize Colours//////
////////////////////////////////

void mouseClicked(){
  //On click, randomize a colour for each RGB value, and then assign this value to
  //each part of the body, as well as the hat (which subtracts this randomized
  //value from 255 to create a colour that complements the rest of the body).
  rCol= random(255);
  gCol= random(255);
  bCol= random(255);
}


/*
use conditionals to set ranges for everything. Each function should use a
variable to control Y pos and/or width. This should be as simple as using an if
statement to set two "maximum" values for x for each body part, and whenever the 
value of x goes beyond those values, it gets assigned that value. Everything between
the two values should just be mouseX. The same rules should be used for constraining
y values.

body should "grow" to a certain size, and then stop. Should look like the
puppet goes from limp, to standing on table, to slightly off table. To do this,
use a series of if statements for each body part that adjusts the height and/or
size of each shape or parts of it. The body itself should be a rectangle that
starts out square-like, and as it rises should become rectangular until it 
reaches a certain size(200?). The head should always rise with the mouse's Y 
position until it reaches a specified constraining value. Arms and legs will be 
more difficult, as they will have to move upwards at different times. Use lines 
for both. Arms shoud move with the body but always be about 3/4 of the way up it. 
Legs will be the last to rise, and the part of the legs connected to the body 
should rise well before the feet do. Use small circles for hands, and oval-like 
ellipse for shoes/feet.

Draw a face for the puppet, as well as a hat. These should be drawn in the function
for the head, and should all be related to the values that the head uses to move
around. Use two ellipse for the eyes and a curve for the mouth, so that it smiles.
For the hat, use a rectangle and a line at its bottom to create a brimmed top hat.
The colour of the eyes and mouth should be black, but the colour of the hat will be
random.

Create a function that can change the y position of each limb individually. Use
keyPressed() to move limbs up and down. These will use if statements to detect
when each individual key is pressed, and when it is a variable will either be
increaed or decreased. These variables will be global so that they can be set in
the if statement and then used outside of it easily. When these variables reach a
certain value (-30/30ish? likely will change depending on limb) they cannot be
moved up or down any further.

create lines that make it seem like strings are attatched to the puppet and are
controlling it. These don't require their own function and can be kept within
the function of the body part that they are "tied" to. The top end of the strings
should all have an (x,y) co-ordinate well off the top of the screen, and the
bottom ends should all be the same as the center point of the hand or foot they are
to seem connected to. The head should follow a similar principle, being the same
as the center point of the head. These should all be drawn early on so that they
appear behind the limb they are connected to. 

use a for loop to create a striped wall in the background. Make a variable s and
increase it by 40 every time the loop runs, until it reaces 400 when it stops.
In the loop, create 2 vertical rectangles: one set at X value S and width of 40,
and the other set at s value s+10 and width of 20 to create the illusion of 
wallpaper.

draw a table, and have a gradient on that to simulate a light effect, using a
for loop. Then, using another for loop, create shading on the wall and the table.
Each of these will follow the same general format: create variable s that
increases by a value every time the loop runs, and runs until s reaches the size
of the table (150ish?). In the loop, create a rectangle (black for shadows, white
for light) with opacity 0+s. Each rectangle's width should be the r, where r is
the value that s is increased by every time the loop runs. The (x,y) co-ordinate
of the rectangle's starting position should be x=0, y=end of desk (250?)+s, to
create a gradient.

The puppet's "suit" should turn into a random colour on a mouse click. Create
global variables for R, G, and B and have their values be random (up to 255).
Have a function for mouseClicked that randomizes each of these values again. The
R, G, and B values for everything that the puppet is wearing should be assigned to
these variables, except for the shoes (which remain black) and the hat. The hat will
also use these variables but they will be subtracted from 255 for each, creating a
colour for the hat that complements the rest of the suit.

*/
/*
use conditionals to set ranges for everything. Each function should use a
variable to control Y pos and/or width. This should be as simple as using an if
statement to set two "maximum" values for x for each body part, and whenever the 
value of x goes beyond those values, it gets assigned that value. Everything between
the two values should just be mouseX. The same rules should be used for constraining
y values.

body should "grow" to a certain size, and then stop. Should look like the
puppet goes from limp, to standing on table, to slightly off table. To do this,
use a series of if statements for each body part that adjusts the height and/or
size of each shape or parts of it. The body itself should be a rectangle that
starts out square-like, and as it rises should become rectangular until it 
reaches a certain size(200?). The head should always rise with the mouse's Y 
position until it reaches a specified constraining value. Arms and legs will be 
more difficult, as they will have to move upwards at different times. Use lines 
for both. Arms shoud move with the body but always be about 3/4 of the way up it. 
Legs will be the last to rise, and the part of the legs connected to the body 
should rise well before the feet do. Use small circles for hands, and oval-like 
ellipse for shoes/feet.

Draw a face for the puppet, as well as a hat. These should be drawn in the function
for the head, and should all be related to the values that the head uses to move
around. Use two ellipse for the eyes and a curve for the mouth, so that it smiles.
For the hat, use a rectangle and a line at its bottom to create a brimmed top hat.
The colour of the eyes and mouth should be black, but the colour of the hat will be
random.

Create a function that can change the y position of each limb individually. Use
keyPressed() to move limbs up and down. These will use if statements to detect
when each individual key is pressed, and when it is a variable will either be
increaed or decreased. These variables will be global so that they can be set in
the if statement and then used outside of it easily. When these variables reach a
certain value (-30/30ish? likely will change depending on limb) they cannot be
moved up or down any further.

create lines that make it seem like strings are attatched to the puppet and are
controlling it. These don't require their own function and can be kept within
the function of the body part that they are "tied" to. The top end of the strings
should all have an (x,y) co-ordinate well off the top of the screen, and the
bottom ends should all be the same as the center point of the hand or foot they are
to seem connected to. The head should follow a similar principle, being the same
as the center point of the head. These should all be drawn early on so that they
appear behind the limb they are connected to. 

use a for loop to create a striped wall in the background. Make a variable s and
increase it by 40 every time the loop runs, until it reaces 400 when it stops.
In the loop, create 2 vertical rectangles: one set at X value S and width of 40,
and the other set at s value s+10 and width of 20 to create the illusion of 
wallpaper.

draw a table, and have a gradient on that to simulate a light effect, using a
for loop. Then, using another for loop, create shading on the wall and the table.
Each of these will follow the same general format: create variable s that
increases by a value every time the loop runs, and runs until s reaches the size
of the table (150ish?). In the loop, create a rectangle (black for shadows, white
for light) with opacity 0+s. Each rectangle's width should be the r, where r is
the value that s is increased by every time the loop runs. The (x,y) co-ordinate
of the rectangle's starting position should be x=0, y=end of desk (250?)+s, to
create a gradient.

The puppet's "suit" should turn into a random colour on a mouse click. Create
global variables for R, G, and B and have their values be random (up to 255).
Have a function for mouseClicked that randomizes each of these values again. The
R, G, and B values for everything that the puppet is wearing should be assigned to
these variables, except for the shoes (which remain black) and the hat. The hat will
also use these variables but they will be subtracted from 255 for each, creating a
colour for the hat that complements the rest of the suit.

*/