Intro:
My sister used to love butterflies, so I decided I would try to animate a Monarch butterfly migration flight in Processing.
Process:
I started by creating a class called Butterflies, and made a simple butterfly shape, with a body and wings. I then added some code that would make the Butterflies fly along the screen at varying speeds and at random points on the X axis to give a sense of magnitude to the migration.
Finally, in order to make the animation more dynamic, I added some code that told the Butterflies to move towards the X coordinate of the mouse, so that the user had some control over the animation.
Challenges:
I really wanted the butterflies to flap their wings as they flew, but I couldn’t figure out how to make that happen. I tried to add a variable butterflyWing with two possible states, butterflyExtend and butterflyContract. I wanted the butterflies to alternate between the two randomly on every frame count. I drew the two states, but no matter what I tried, I couldn’t get the result I wanted. I also wasn’t sure how to even search for what I wanted. I ended up watching a number of Coding Train videos in hopes of finding some help, but in the end I was unsuccessful.
Final:
Code:
The Butterfly Class code:
class Butterfly{
  float posX, posY;
  float butterflyWidth, butterflyHeight;
  color butterflyColor;
  float speed;
  
  Butterfly(float _posX_, float _posY_, float _speed){
    posX = _posX_;
    posY = _posY_;
    butterflyWidth = random(10, 20);
    butterflyHeight = random(50, 100);
    butterflyColor = color(252,127,3);
    speed = _speed;
}
void migration(){
 butterflyBody();
 butterflyWing();
 butterFly();
 update();
}
void constructButterfly(float _posX_,float _posY_){
  
}
void butterFly(){
  posY += speed;
  
  if (posY > height+butterflyHeight/2) {
    posY = +butterflyHeight/2;
  }
    
}
void update(){ 
  if (posX > mouseX){
    posX --;
  }
  if (posX < mouseX){
    posX ++;
  }
}
void butterflyBody(){
  fill(0);
  stroke(0);
  strokeWeight(1);
  strokeJoin(ROUND);
  ellipse(posX, posY, butterflyWidth, butterflyHeight);
}
void butterflyWing(){
  fill(butterflyColor);
  triangle(posX, posY, posX-butterflyHeight, posY+butterflyHeight/20, posX-butterflyHeight, posY+butterflyHeight);
  triangle(posX, posY, posX+butterflyHeight, posY+butterflyHeight/20, posX+butterflyHeight, posY+butterflyHeight);
  triangle(posX, posY, posX-butterflyHeight, posY-butterflyHeight/20, posX-butterflyHeight, posY-butterflyHeight);
  triangle(posX, posY, posX+butterflyHeight, posY-butterflyHeight/20, posX+butterflyHeight, posY-butterflyHeight);
}
}
The operational code:
Butterfly[] myButterflies;
void setup(){
 size(1280, 1280); 
 rectMode(CENTER);
 
 myButterflies = new Butterfly[50];
 for (int i=0; i<myButterflies.length; i++){
   myButterflies[i] = new Butterfly(random(width), height + 100, random(5, 10));
 }
}
void draw() {
  background(255);
  
  for (int i=0; i<myButterflies.length; i++){
    myButterflies[i].migration();
  }
}
