Winter Scene GIF

output

sketch

I started off by playing with the noise function, and when I was observing it, I thought the way it moved looked like a row of soldiers marching. Thus I decided to create infinite rows of noise soldiers walking towards the viewer. However, after I coded it up, I realized that what I had looked more like a waterfall, so I just created a scene by going from there instead.

During the entire process of creating this gif, I spend a lot of time worrying how I could get it to loop. Not taking risks made me feel like I did not learn as much as I could from this project. Also, I did not realize that there was a template uploaded, which could have saved me a lot of time. Thirdly, I found out that I enjoy watching my animation more when I am listening to some relaxing music, rather than being in silence, so I feel it might have been better if instead it is a music video with more contents. The combined effects made me feel serene, which I am glad for.

Thanks to Daniel Shiffman for his code of the particle system.

int square_width = 15;
color skycolor = color(40,40,40);
boolean sunrise = true;
int snowcolor = 140;
int stay = 0;
int frames = 0;

ParticleSystem ps1, ps2;

class Particle {
  PVector location;
  PVector velocity;
  PVector acceleration;
  float lifespan;

  Particle(PVector l) {
    acceleration = new PVector(0,0.1);
    velocity = new PVector(random(-10,10),1.0);
    location = l.get();
    lifespan = 255.0;
  }

  void run() {
    update();
    display();
  }

  // Method to update location
  void update() {
    velocity.add(acceleration);
    location.add(velocity);
    lifespan -= 1.0;
  }

  // Method to display
  void display() {
    stroke(255,200 - blue(skycolor) + 2);
    fill(255, 200 - blue(skycolor) + 2);
    ellipse(location.x,location.y,8,8);
  }
  
  // Is the particle still useful?
  boolean isDead() {
    if (lifespan < 0.0) {
      return true;
    } else {
      return false;
    }
  }
}




// A class to describe a group of Particles
// An ArrayList is used to manage the list of Particles 

class ParticleSystem {
  ArrayList particles;
  PVector origin;

  ParticleSystem(PVector location) {
    origin = location.get();
    particles = new ArrayList();
  }

  void addParticle() {
    particles.add(new Particle(origin));
  }

  void run() {
    for (int i = particles.size()-1; i >= 0; i--) {
      Particle p = particles.get(i);
      p.run();
      if (p.isDead()) {
        particles.remove(i);
      }
    }
  }
}


class Row_of_Noise{
  int start, end;
  float row;

  Row_of_Noise(int s, int e, float r)
  {
    start = s;
    end = e;
    row = r;
  }

  void walk_forward()
  {
    row *= 1.03;
    if(row > height)
      row = 0.1;

    start = width/2-(int)row*3;
    end = width/2+(int)row*3; 
  }
}

Row_of_Noise[] RoN;

void setup() {
  size(600, 600);
  stroke(0);
  smooth();
  noiseSeed(15251);
  initialize_rows_of_noise();
  ps1 = new ParticleSystem(new PVector(width/3,-50));
  ps2 = new ParticleSystem(new PVector(2*width/3,-50));
}

void initialize_rows_of_noise(){
  RoN = new Row_of_Noise[40];
  float r = 0.1;
  for(int i = 0; i < RoN.length; i++)
  {
    r *= 1.3;
    RoN[i] = new Row_of_Noise(width/2-(int)r*2, 
                              width/2+(int)r*2, 
                              r);
  }
}

void draw_row_of_noise(Row_of_Noise ron)
{
  beginShape();
  float theta = 0.0;
  for(int x = ron.start; x < ron.end; x++)
  {
    
    if(x % 50 == 0)
    {
      endShape();
      beginShape();
    }
    
    if(x % 50 < 10)
      continue;

    float y = noise((millis()/1000.0 + x)%50.0) * 
                   ((float)(ron.end - ron.start)/ 6.0) + ron.row;
    vertex(x-5,y+300);
  }
  endShape();
}

void draw() {

  if(53 < frames && frames < 285)
    saveFrame("outputgif/myname-loop-" + nf(frames,4) + ".png");
  if(blue(skycolor) > 200)
  {
    sunrise = false;
    if(stay == 0)
      stay = 50;
    else
      stay--;
  }

  if(blue(skycolor) < 10)
  {  
    sunrise = true;
    if(stay == 0)
      stay = 50;
    else
      stay--;
  }

  if(stay == 0)
  {
    if(sunrise)
    {
      skycolor = color(red(skycolor)+1, green(skycolor)+2, blue(skycolor)+3);
      snowcolor++;
    }
    else
    {
      skycolor = color(red(skycolor)-1, green(skycolor)-2, blue(skycolor)-3);
      snowcolor--;
    }
  }

  background(skycolor);
  stroke(snowcolor);

  for(int i = 0; i < width; i++)
    line(i,noise(i/400.0)*100.0 + 245,i,height);

  // draws the waterfall
  stroke(0,100,200);
  noFill();
  for(int i = 0; i < RoN.length; i++)
  {
    draw_row_of_noise(RoN[i]);
    RoN[i].walk_forward();
  }

  ps1.addParticle();
  ps1.run();
  ps2.addParticle();
  ps2.run();

  frames++;
}

Comments are closed.