Recitation 6: Processing Animation by Min Jee (Lisa) Moon

Some Interesting functions that I used

  • System
    • import
  • Image related:
    • PImage
    • image()
    • resize()
    • minim = new Minim(this);
    • tint()
  • Sound related:
    • minim.loadFile()
    • play()
    • rewind()
  • Instruction related
    • PFont
    • createFont()
    • textFont()
    • textAlign()
  • Interaction part
    • mousePressed() 
      • pmouseX
      • pmouseY
    • keyPressed()
      • key, keyCode

One of the functions that my code would be different from anybody else would be — because I wanted to add sound to my program — I imported minim. If you want to run my code, please go to the processing library and import minim.

The source code is below.

//Music from https://www.youtube.com/watch?v=xeOCmkrH3p8&t=268s
//snow falling sound effect from http://blog.naver.com/PostView.nhn?blogId=s___apple___&logNo=140124130929
import ddf.minim.*;
import ddf.minim.analysis.*;
import ddf.minim.effects.*;
import ddf.minim.signals.*;
import ddf.minim.spi.*;
import ddf.minim.ugens.*;

Minim minim;
AudioPlayer background; 
AudioPlayer yoheaveho; 
AudioPlayer explosion;
AudioPlayer afterDust;
AudioPlayer warning;
//==========================================================================================================================================================================
PImage rabbit;
PImage rabbitFlip;
PImage dust;
PImage afterExplosion;
PImage resetButton;
PImage hearts;
PImage village;
//==========================================================================================================================================================================
// ground
  float ellipseHeight = 200;
  float ellipseWidth = 1140;
//==========================================================================================================================================================================
// snow info
  int snowQuantity = 300;
  
  float snowPosX =  width/2 + 240;
  float snowPosY = height/2 + 100;
  
  float [] xPosition = new float[snowQuantity];
  float [] yPosition = new float[snowQuantity];
  int [] flakeSize = new int[snowQuantity];
  int [] direction = new int[snowQuantity];
  int minFlakeSize = 1;
  int maxFlakeSize = 5;
//==========================================================================================================================================================================  
// snowball
  boolean exploded = false; // checks if the snowball already exploded or not
  boolean dustClicked = false; // checks if the user clicked on the dust
  boolean warningMsg = false;
  
  float snowBallPos = 785; 
  float snowBallPosY = 406;
  float snowBallSize = 50; // initialize the snowball size 
  float increasingSpeed = 2; // how much the snowball increases each press of the key
  float snowBallMax = 380; // maximum snowball size
 
// rabbit
  float rabbitNormalPos = snowBallPos + (snowBallSize/2 - 25) - 5;
  float flippedRabbitPos = snowBallPos - (snowBallSize/2 - 25) - 173 + 5;
  float rabbitPosY = 302;
 
String rabbitMode = "Normal";
//==========================================================================================================================================================================    
// instruction
PFont instructionFont;
//==========================================================================================================================================================================
// DO NOT MODIFY
void setSnow(){
  frameRate(20);
  noStroke();
  smooth();
  fill(255);
  
  for(int i = 0; i < snowQuantity; i++) {
    flakeSize[i] = round(random(minFlakeSize, maxFlakeSize));
    xPosition[i] = random(0, width);
    yPosition[i] = random(0, height);
    direction[i] = round(random(0, 1));
  }
}

void snow(){
  for(int i = 0; i < xPosition.length; i++) {
    
    fill(255);
    ellipse(xPosition[i], yPosition[i], flakeSize[i], flakeSize[i]);
    
    if(direction[i] == 0) {
      xPosition[i] += map(flakeSize[i], minFlakeSize, maxFlakeSize, .1, .5);
    } 
    
    else {
      xPosition[i] -= map(flakeSize[i], minFlakeSize, maxFlakeSize, .1, .5);
    }
    
    yPosition[i] += flakeSize[i] + direction[i]; 
    
    
    if(xPosition[i] > width + flakeSize[i] || xPosition[i] < -flakeSize[i] || yPosition[i] > height + flakeSize[i]) {
      xPosition[i] = random(0, width);
      yPosition[i] = -flakeSize[i];
    }
  }
}

void drawBackground(){
  background(#CEE1E6); // set the background color
  noStroke();          // remove the outline of the circle or rectangle
  ellipseMode(CENTER);
  fill(#F2F2F2);        // fill the circle and rectanlge with specific hexadecimal color value
  ellipse(width/2, height-200, ellipseWidth, ellipseHeight);
  rect(0, height-200, width, 500);
  
  image(village, (width/2) - 300, 117); // finally, add the image of villages at the background. 
}

void initialize() { // initializes all the variables
  // snowball
  tint(255, 255);
  exploded = false; // checks if the snowball already exploded or not
  dustClicked = false; // checks if the user clicked on the dust
  warningMsg = false;
  
  snowBallPos = 785; 
  snowBallPosY = 406;
  snowBallSize = 50; // initialize the snowball size 
  increasingSpeed = 2; // how much the snowball increases each press of the key
  snowBallMax = 380; // maximum snowball size
 
  // rabbit
  rabbitNormalPos = snowBallPos + (snowBallSize/2 - 25) - 5;
  flippedRabbitPos = snowBallPos - (snowBallSize/2 - 25) - 173 + 5;
  rabbitPosY = 302;
 
  rabbitMode = "Normal";
  
  background.close();
  explosion.close();
  afterDust.close();
  
  background = minim.loadFile("audio/background.mp3");
  yoheaveho = minim.loadFile("audio/yo-heave-ho.mp3");
  explosion = minim.loadFile("audio/explodedVoice.mp3");
  afterDust = minim.loadFile("audio/saved.mp3");
  warning = minim.loadFile("audio/warning.mp3");
  background.rewind();
  explosion.rewind();
  afterDust.rewind();
  warning.rewind();
  
  background.play();
  
}
//==========================================================================================================================================================================
void setup(){
  size(960, 600);
  
  // load image
  rabbit = loadImage("image/rabbit.png");
  rabbit.resize(0, 170);
  rabbitFlip = loadImage("image/rabbitFlipped.png");
  rabbitFlip.resize(0, 170);
  afterExplosion = loadImage("image/explodedSnowball.png");
  afterExplosion.resize(0, 200);
  
  dust = loadImage("image/dust.png");
  dust.resize(0, 500);
  
  resetButton = loadImage("image/reset.png");
  
  hearts = loadImage("image/heart.png");
  
  village = loadImage("image/village.png");
  
  // load font
  instructionFont = createFont("font/TEENAGEANGST.TTF", 30);
  textFont(instructionFont);
  textAlign(CENTER, CENTER);
  
  setSnow(); // set values for snow
  
  minim = new Minim(this);
  
  background = minim.loadFile("audio/background.mp3");
  yoheaveho = minim.loadFile("audio/yo-heave-ho.mp3");
  explosion = minim.loadFile("audio/explodedVoice.mp3");
  afterDust = minim.loadFile("audio/saved.mp3");
  warning = minim.loadFile("audio/warning.mp3");
  
  background.play();
  
}

void instruction(String mode){
  fill(0);
  if (mode == "rolling"){
    text("Press left or right arrow key to make the rabbit roll the snowball", width/2, 31);
  } else if (mode == "exploded"){
    text("Click on the dust to remove the dust!", width/2, 31);
  } else if (mode == "final"){
    text("Thank you for playing :)", width/2, 31);
    text("Press the restart button -> to restart", width/2, 62);
  } else if (mode == "affection"){
    text("Please say GOOD JOB to Lisa if you liked it! :)", width/2, 31);
  }
}

void draw(){
  drawBackground();
  snow();
  
  if (!exploded){                                                             // if the snowball did not explode yet
    instruction("rolling"); // instruction texts in a rolling mode
    
    if (rabbitMode == "Normal"){
      image(rabbit, rabbitNormalPos, rabbitPosY);
    } else if (rabbitMode == "Flip"){
      image(rabbitFlip, flippedRabbitPos, rabbitPosY);
    }
    snowBall(); // have the snowball
  } else {       // if the snowball exploded
    if (!dustClicked){
      image(afterExplosion, rabbitNormalPos-175, 306);
      if (pmouseX > (rabbitNormalPos - 186) && pmouseX < (rabbitNormalPos + 314) &&
          pmouseY > 118 && pmouseY < 588){
        tint(255, 200);
        image(dust, rabbitNormalPos-186, 104);  
        tint(255, 255);
      } else {
        tint(255, 255);
        image(dust, rabbitNormalPos-186, 104);  
      } 
      instruction("exploded");
    } else {
      tint(255, 255);
      while ((rabbitNormalPos-175) < ((width/2)-251)){
        rabbitNormalPos++;
        
        image(afterExplosion, rabbitNormalPos-175, 306);
      }
      
      while ((rabbitNormalPos-175) > ((width/2)-251)){
        rabbitNormalPos--;
        
        image(afterExplosion, rabbitNormalPos-175, 306);
      }
      
      image(afterExplosion, (width/2)-251, 306);
      if (pmouseX > (width-60) && pmouseY < 74){                          // reset hover
        tint(255, 150);
        image(resetButton, width-60, 10);
        tint(255, 255);
      } else {
        tint(255, 255);
        image(resetButton, width-60, 10);
      }
        
      if (pmouseX > 404 && pmouseX < 528 && pmouseY > 327 && pmouseY < 487){ // rabbit hover
        image(hearts, 316, 231);
        instruction("affection");
      } else {
        instruction("final");
      }
    }   
  } 
  
}

void snowBall(){
  ellipseMode(CENTER);
  fill(255);
  circle(snowBallPos, snowBallPosY, snowBallSize);
}

void keyPressed(){
  if (snowBallSize < snowBallMax){
    if (key == CODED){
      if (keyCode == LEFT) {       // roll the snowball left
        rabbitMode = "Normal";
        snowBallPos -= 10;
        rabbitNormalPos = snowBallPos + (snowBallSize/2 - 25) - 5; 
        flippedRabbitPos = rabbitNormalPos;  // to synchronize position
      } else if (keyCode == RIGHT) {
        rabbitMode = "Flip";
        snowBallPos += 10;
        flippedRabbitPos = snowBallPos - (snowBallSize/2 - 25) - 173 + 5; 
        rabbitNormalPos = flippedRabbitPos; // to synchronize position
      }
      
      yoheaveho.play();
      if (yoheaveho.position()>=yoheaveho.length()) {
        yoheaveho.rewind();
      }
                                                                            // when the rabbit is within the screen
      if((rabbitMode == "Normal" && rabbitNormalPos > 10) ||                       // when rabbit is facing the left, it should be greater than 10
      (rabbitMode == "Flip" && flippedRabbitPos < (width-173))){                    // when rabbit is facing the right, less than width-173
        warning.close();
        warning = minim.loadFile("audio/warning.mp3");
        snowBallSize += increasingSpeed;
      } else {
        yoheaveho.close();
        yoheaveho = minim.loadFile("audio/yo-heave-ho.mp3");
        warning.play();
        if (warning.position()>=warning.length()) {
          warning.rewind();
        }
      }
    }
  } else {                                                   // when the snowball exploded
    explosion.play();                // play the sound effect for the explosion
    rabbitMode = "Normal";            // because there is no more heading towards left or right
                                      // for sake of simplicity, using only one variable from now.
    
    if (rabbitNormalPos < 0){ // if the rabbit is outside the screen on the left side
      rabbitNormalPos = 10;
    } else if (rabbitNormalPos > width-183){ // if the rabbit is outside the screen on the right side
      // here, 183 is the width of the rabbit that has been resized by the .resize function
      rabbitNormalPos = width - 183;
    }
    
    exploded = true;
  }
}

void mousePressed(){
  if (exploded) {
    if (pmouseX > (rabbitNormalPos - 186) && pmouseX < (rabbitNormalPos + 314) &&
        pmouseY > 118 && pmouseY < 588){
      dustClicked = true;
      afterDust.play();
    }
  }
  
  if (dustClicked){
    if (pmouseX > (width-60) && pmouseY < 74){
      initialize();
    }
  }
}


The video for the additional assignment:

In order to achieve the smooth color transition, I was looking at the color selecting tool and noticed below pattern.

R = 255 G = 10 B = 10 -> B  ++

R = 255 G = 10 B = 255 -> R  – –

R = 10 G = 10 B = 255 -> G ++

R = 10 G- 255 B = 255 -> B – –

R= 10 G = 255 B = 10 -> R ++

R = 255 G = 255 B = 10 -> G – –

Therefore, I worked on the code without the colorMode() function.

The complete code is below.

float circleX;
float circleY;
float circleSize = 400;
float sizeChangeSpeed = 5;
float circleMoveAmt = 5;

float r = 255;
float g = 10;
float b = 10;
float colorChangeSpeed = 7;

int changePhase = 1;

void setup(){
  size(600, 600);
  circleX = width/2;
  circleY = height/2;
}

void draw(){
  background(255);
  chooseColor();
  drawCircle(color(r, g, b));
}

void drawCircle(color circleColor){
  ellipseMode(CENTER);
  strokeWeight(20);
  stroke(circleColor);
  
  ellipse(circleX, circleY, circleSize, circleSize);
  
  circleSize += sizeChangeSpeed;
  if(circleSize > 400 || circleSize < 80){
    sizeChangeSpeed = -sizeChangeSpeed;
  }
}

void chooseColor() {
  /*R = 255 G = 10 B = 10 -> B  ++
  R = 255 G = 10 B = 255 -> R  - -
  R = 10 G = 10 B = 255 -> G ++
  R = 10 G- 255 B = 255 -> B - -
  R= 10 G = 255 B = 10 -> R ++
  R = 255 G = 255 B = 10 -> G - -
  */
  // decides which phase it is
  if (r == 255 && g == 10 && b == 10){
    changePhase = 1;
  } else if (r == 255 && g == 10 && b == 255){
    changePhase = 2;
  } else if (r == 10 && g == 10 && b == 255){
    changePhase = 3;
  } else if (r == 10 && g == 255 && b == 255){
    changePhase = 4;
  } else if (r == 10 && g == 255 && b == 10){
    changePhase = 5;
  } else if (r == 255 && g == 255 && b == 10){
    changePhase = 6;
  }
  
  // change the color based on which phase it is
  if (changePhase == 1){
    b += colorChangeSpeed;
  } else if (changePhase == 2){
    r -= colorChangeSpeed;
  } else if (changePhase == 3){
    g += colorChangeSpeed;
  } else if (changePhase == 4){
    b -= colorChangeSpeed;
  } else if (changePhase == 5){
    r += colorChangeSpeed;
  } else if (changePhase == 6){
    g -= colorChangeSpeed;
  } 
   
}

void keyPressed(){
  
  if (key == CODED){
    if (keyCode == UP) {
      circleY -= circleMoveAmt;
    } else if (keyCode == DOWN){
      circleY += circleMoveAmt;
    } else if (keyCode == LEFT){
      circleX -= circleMoveAmt;
    } else if (keyCode == RIGHT){
      circleX += circleMoveAmt;
    }
  }
  
}

One Reply to “Recitation 6: Processing Animation by Min Jee (Lisa) Moon”

Leave a Reply