How To...

Animate Simultaneous Animations

Rotating Wheel result

If you plan it right, you can have multiple animations/actions taking place at the same time. In this example the robot is moving automatically from left to right and wrapping around the frame, it could also be controlled with the arrow keys without affecting the other animations. The robot also can raise and lower its right and left arms with the rotate(amount) command. It checks the keyPressed to see if the r or l keys have been pressed. The keyPressed() event toggles the motion of the arms with a nice trick of flipping a boolean variable with moveArm = !moveArm, the '!' flips the true to false and the false to true. The eyes blink randomly for 1.2 seconds with a timer that resets itself.

PROCESSING

Simultaneous Animations

// Simultaneous Animations
// v1.0
//
// Global Variables
int xLoc = 100;
// A bit wider than the actual robot
// to account for extended arms
int robotWidth = 210; 
// Arm stuff
boolean moveRightArm = false;
boolean moveLeftArm = false;
int armLeftAngle = 0;
int armRightAngle = 0;
int armLeftSpeed = 2;
int armRightSpeed = 2;
// Timer stuff
float timeToTest = 2000.0;
float lastTime = 0.0;

void setup() {
  size(500, 500);
}

void draw() {
  background(128);
  textAlign(CENTER);
  text("R for right arm, L for left", width/2, height-24);  
  xLoc++; // Constantly move left to right
  // Wrap
  if(xLoc >= width) { xLoc=-robotWidth; }
  translate(xLoc,100);
  drawRobot();  
}

void drawRobot() {
  // Animate right arm
  if(moveRightArm) { // keyPressed says the key was R
    // Toggle the rotation direction of the arm
    if(armRightAngle > 90 || armRightAngle < 0 ) { 
      armRightSpeed = -armRightSpeed; 
    }
    armRightAngle += armRightSpeed;
  }
  // Isolate the translation and rotation of the right arm
  pushMatrix();
    translate(50,100);
    rotate(radians(15 + armRightAngle));
    drawArm();
    drawHand();
  popMatrix();
  // Animate left arm
  if(moveLeftArm) {
    if(armLeftAngle > 90 || armLeftAngle < 0 ) { armLeftSpeed = -armLeftSpeed; }
    armLeftAngle -= armLeftSpeed;
  }
  pushMatrix();
    translate(120,100);
    rotate(radians(-15  - armLeftAngle));
    drawArm();
    drawHand();
  popMatrix();
  // Draw the rest of the robot
  rect(80,60,10,30);       // neck
  ellipse(85,50,50,50);    // head
  // drawFace does the blinking eyes
  drawFace();
  ellipse(50,100,40,40);   // r shoulder
  ellipse(120,100,40,40);  // l shoulder
  rect(50,80,70,70);       // body
  rect(60,150,20,50);      // r leg
  rect(90,150,20,50);      // l leg
  arc(70,200,30,30,PI, PI * 2, PIE); // r foot
  arc(100,200,30,30,PI, PI * 2, PIE); // l foot
}

void drawArm() {
  // Arm is drawn from 0,0 to make the rotation work
  strokeWeight(10);
  line(0,0,0,50);
}

void drawHand() {
  // Isolate positioning of hand
  pushMatrix();
    translate(0,50);
    rotate(radians(90));
    strokeWeight(2);
    arc(0,0,30,30,radians(30 ), radians(330), PIE);
  popMatrix();
}

void drawFace() {
  ellipseMode(CENTER);
  ellipse(75,45,15,15);
  ellipse(75,45,5,5);
  ellipse(95,45,15,15);
  ellipse(95,45,5,5);
  // Blink at random
  if(millis() >= timeToTest + lastTime) {
    ellipse(75,45,15,15);
    line(70,45,80,45);
    ellipse(95,45,15,15);
    line(90,45,100,45);
    // 1250.0 controls how long the blink lasts
    if(millis() >= timeToTest + lastTime + 1250.0) {
      // Randomize the amount of time until the next blink
      timeToTest = random(200.0,1600.0);
      lastTime = millis();
    }
  }
  strokeWeight(4);
  line(70,60,100,60);
  strokeWeight(2);
}

void keyPressed() {
  // Check for the r or l keys and 
  // toggle the animation on and off
  if(key == 'r') {
    moveRightArm = !moveRightArm;
  }
  if(key == 'l') {
    moveLeftArm = !moveLeftArm;
  }
}