Loading...
Logo
Processing Forum
Hey everyone, I'm new to this forum and to Processing and would like some help with a falling snowflake project that is due on Monday. What I have already is falling snowflakes that change color and change shape as they fall (someone mentioned to me that it looks like glitter.) And wherever the mouse moves, there is also an umbrella that moves with it.

I would like to have the snow accumulate on top of the umbrella and stay there as the umbrella moves to collect more snow. I'm taking a mandatory Computer Science class that uses Processing and have been only at it for five weeks. 

Here's my code so far ( note that the images will not show up on your processing. I've attached a screenshot.) 

float[] xValues = new float[500];
float[] yValues = new float[500];
PImage img;
PImage img2;

void setup()
{
  noStroke();
  img2 = loadImage ("wintersky.jpg");
  img = loadImage("umbrella.png");
  size(700,500);
  for(int i=0;i < xValues.length;i++)
  {
    xValues[i] = random(0,width);
    yValues[i] = random(0,height);
  }
}

void draw()
{
  image(img2,0,0,700,500);
  for(int i=0;i < xValues.length;i++)
  {
    fill (random(0,255),random(0,255),random(0,255));
    ellipse(xValues[i],yValues[i], random(1,10), random(1,10));    
    yValues[i] = yValues[i] + 2;
    xValues[i] = xValues[i] + random(-2.5,2.5);
    if(yValues[i] > height + 5)
    {
      yValues[i] = -5;
      xValues[i] = random(0,width);
    }
  image(img, mouseX, mouseY);

}
}

Thanks, any help is appreciated!

Replies(7)

For now, most I can do is offer a code tweak.
And that you should remove image(img, mouseX, mouseY); from within the loop.
Lest it is re-drawn 500 times unnecessarily!!!
Copy code
    /**
     * Falling Glitters (v2.2)
     * by Yumikat2006 (2013/Jan) 
     *
     * http://forum.processing.org/topic/
     * been-only-using-processing-for-five-weeks-and-i-need-help-with-falling-snowflakes
     */
    
    final static short numFlakes = 500;
    final static short[] xValues = new short[numFlakes];
    final static short[] yValues = new short[numFlakes];
    
    final static byte maxFlakeSize = 10;
    final static byte fallSpeed = 2;
    
    PImage umbrella, bg;
    
    void setup() {
    
      size(700, 500);
      noStroke();
      noCursor();
    
      for (short i=0; i!=numFlakes; i++) {
        xValues[i] = (short) random(width);
        yValues[i] = (short) random(height);
      }
    
      umbrella = loadImage("umbrella.png");
      bg = loadImage("wintersky.jpg");
    
    
      image(bg, 0, 0, width, height);
      bg = get();
    
      imageMode(CENTER);
      ellipseMode(CENTER);
    }
    
    void draw() {
      background(bg);
    
      for (short i=0; i!=numFlakes; i++) {
    
        fill( (int) random(0x1000000) | 0xff000000 );
        ellipse( xValues[i], yValues[i], 
        random(1, maxFlakeSize), random(1, maxFlakeSize) );
    
        if ( (yValues[i] += fallSpeed) > height+maxFlakeSize ) {
          yValues[i] = -maxFlakeSize;
          xValues[i] = (short) random(width);
        }
    
        else  xValues[i] += random(-2, 3);
      }
    
      image(umbrella, mouseX, mouseY);
    }
    

Dear GoToLoop,

Thanks for your quick response! So is it pretty much difficult to have the snow accumulate on top of the umbrella?

yumikat2006
if you want to do this, I'd suggest that you need to make a little class for your snowflakes. At the moment it looks like you are just holding the positions in some global arrays. I'd make each snowflake and object and then perform some kind of check to see if its near  one of the points that define the top of the umbrella (you'd need code for this since at the moment it's just an image. Every update, I'd check for each snowflake whether its hit the umbrella (ie whether its within a short distance of any of the points. You could adjust the umbrella spline each time it gets hit. 

This might be a bit tricky if you are just starting but a good way to begin is to look into classes and objects. For example in chapter 8 here on Dan Shiffmans excellent site  http://www.learningprocessing.com/examples/ 

hope that helps
I've also been working on a snowflakes program. I have three snowflake variations: flaketype =0 (each snowflake is formed by 3 lines); flaketype = 1 (each snowflake is a point); flaketype=2 (each snowflake is a variable diameter circle). I also vary the color of the snowflakes (   fill(random(200,255)); My next step is to animate the falling snow. 

============================================================= 

/** My Snowflakes_2
* Processing: Test programs
* By rl7777 */




int i,j,lines,toggle,flaketype;
float cx, cy, x1, x2, y1, y2, xdelta, ydelta;
float horizon, horizon2,gap,screenbottom;
float shippos;
float px, py, px2, py2;

PrintWriter output;

void setup(){
  
 
  rectMode(CORNERS);
  screenbottom=400;
  size(800, int(screenbottom));
  
  background(0);
  fill(100);
  rect(20,20,780,screenbottom-20);
   horizon=320;
   horizon2=350;
   shippos=20.0;
 
 
  flaketype = 2; 
  // 0=lines, 1=point, 2=circle



// the ground 
//fill(0,0,255);
fill(40);
rect(20,320,780,screenbottom-20);


// the ocean
//=================================
 fill(100);
rect(20,horizon,780,horizon2);


// the ocean lines 
//=================================
lines=10;
gap=(horizon2-horizon)/lines;
for (j=0;(j<lines);j++){
  println(j);
  stroke(0,255,0);
line(20,(horizon+.1*j*j*gap),780,(horizon+.1*j*j*gap));
println(gap + " --- " + j + "--- " + (horizon+j*gap));
  }


// the moon
//=================================
fill(240);
ellipse(650,100,40,40);


// the snowflakes
//=================================
 for (i = 1; i<6000; i++){
  
  cx=random(20,780);
  cy=random(20,screenbottom-20);
  xdelta=random(1,4);
  ydelta=random(1,4);
  
  x1=cx-xdelta;
  x2=cx+xdelta;
  y1=cy-ydelta;
  y2=cy+ydelta;
  
  strokeWeight(1);
  fill(255,0,0);


switch(flaketype) {
case 0:
// making snowflakes out of lines
//=================================
// the four lines which comprise my model of a snowflake
stroke(255);
line(cx,y1,cx,y2);
   line(x1,cy,x2,cy);
    line(x1,y1,x2,y2);
     line(x1,y2,x2,y1);
break;

case 1:
// making snowflakes out of points
//=================================
stroke(255);
point(cx,cy);
break;

case 2:
// making snowflakes out of circles
//=================================
fill(random(200,255));
float diameter=random(10-15);
ellipse(cx,cy,diameter,diameter);
break;
}
 
 
 // reference lines
//=================================
   stroke(128);
   line(100,400,700,400);
   line(400,100,400,700);
   stroke(0);
   
}
       
}

void draw(){


//exit();
}
Well, I did some attempts and end up w/ a faulty solution.

This new version checks whether a glitter is inside an imaginary little rectangle at the top of the umbrella.
Very far from perfect, especially that I don't have access to the original umbrella sprite!

Once it's confirmed, the difference between (glitter location - mouse pointer)
is stored within class UmbrellaGlitter.

The falling glitter is deactivated; and in its place, a flake is drawn relative to mouse pointer
within glitters enhanced loop, which follows the top of the umbrella.
Which in turn, is the opposite calc of what had been stored -> (relative location + mouse pointer)!

So it is now a mixture of arrays + OOP approaches!
Falling glitters use regular arrays, and "captured" ones are class-based
w/ an ArrayList to store their instance references.

Hope it can help you reach where you aim:
Copy code
    /**
     * Falling Glitters (v3.8)
     * by YumiKat2006 (2013/Jan)
     *
     * http://forum.processing.org/topic/
     * been-only-using-processing-for-five-weeks-and-i-need-help-with-falling-snowflakes
     */
    
    final static short numFlakes = 01500;
    final static short[] x = new short[numFlakes];
    final static short[] y = new short[numFlakes];
    
    final static List<UmbrellaGlitter> glitters = new ArrayList(numFlakes);
    
    final static byte  maxFlakeSize  = 12;
    final static byte  fallSpeed = 2;
    final static byte  fps = 50;
    
    final static short captureValue  = -01000;
    final static float chanceToCatch = 3e-2;
    
    final static boolean isFinite = true;
    
    int w, ww, www, h, hh, hhh;
    
    PImage umbrella, bg;
    
    void setup() {
      size(700, 500);
      noStroke();
      noCursor();
      frameRate(fps);
    
      umbrella = loadImage("umbrella.png");
      w   = umbrella.width;
      h   = umbrella.height;
      ww  = w>>1;
      www = w>>2;
      hh  = h>>1;
      hhh = h>>2;
    
      bg = loadImage("wintersky.jpg");
      image(bg, 0, 0, width, height);
      bg = get();
    
      imageMode(CENTER);
      ellipseMode(CENTER);
    
      for (short i=0; i!=numFlakes; i++) {
        x[i] = (short) random(width);
        y[i] = (short) random(height);
      }
    }
    
    void draw() {
      background(bg);
    
      for (short i=0; i!=numFlakes; i++) {
    
        if (isFinite && x[i] == captureValue)   continue;
    
        fill( (color) random(0x1000000) | 0xff000000 );
        ellipse( x[i], y[i], 
        random(1, maxFlakeSize), random(1, maxFlakeSize) );
    
        if ( (y[i] += fallSpeed) > height+maxFlakeSize ) {
          x[i] = (short) random(width);
          y[i] = -maxFlakeSize;
        }
    
        else if (random(1) > chanceToCatch)    x[i] += random(-2, 3);
    
        else if (x[i] > mouseX-www && x[i] < mouseX+www && 
          y[i] > mouseY-hh+maxFlakeSize && y[i] < mouseY-hhh) {
    
          glitters.add( 
          new UmbrellaGlitter(x[i]-mouseX, y[i]-mouseY) );
    
          x[i] = captureValue;
        }
      }
    
      image(umbrella, mouseX, mouseY);
    
      for (UmbrellaGlitter ug: glitters)    ug.display();
    }
    
    class UmbrellaGlitter {
      final short x, y;
      final color c = (color) random(0x1000000) | 0xff000000;
      
      static final byte sz = maxFlakeSize>>1;
    
      UmbrellaGlitter(int xx, int yy) {
        x = (short) xx;
        y = (short) yy;
      }
    
      void display() {
        fill(c);
        ellipse(x+mouseX, y+mouseY, sz, sz);
      }
    }
    

Hello everyone! I've made a revised code.

float[] xValues = new float[2000];
float[] yValues = new float[2000];
boolean[] moving = new boolean[2000];
float[] xStay = new float[2000];
float[] yStay = new float [2000];
PImage img;
PImage img2;
import processing.video.*;
Movie movie;

void setup()
{
  noStroke();
  img2 = loadImage ("wintersky.jpg");
  img = loadImage("umbrella.png");
  movie = new Movie (this, "Spectrum.wav");
  size(700,500);
  for(int i=0;i < xValues.length;i++)
  {
    xValues[i] = random(0,width);
    yValues[i] = random(0,height);
    xStay[i] = -1;
    yStay[i]=-1;
    moving[i] = true;
  }
}

void draw()
{
  movie.play();
  image(img2,0,0,700,500);
  image(img, mouseX, mouseY);
  for(int i=0;i < xValues.length;i++)
  {
    if(moving[i] == true){
    fill (random(0,255),random(0,255),random(0,255));
    ellipse(xValues[i],yValues[i], random(1,10), random(1,10));    
    }
    else if(moving[i] == false){
      fill (255);
      ellipse(xValues[i], yValues[i], 5,5);
    }
    if(moving[i] == true){
      yValues[i] = yValues[i] + 2;
      xValues[i] = xValues[i] + random(-2.5,2.5);
    }
    
    if (xValues[i]>mouseX && xValues[i]<mouseX+70 && yValues[i]> mouseY && yValues[i]<mouseY+20){
    moving[i] = false;
    
  }
    if (moving[i]==false){
      if(xStay[i] == -1 && yStay[i]==-1){
        xStay[i] = xValues[i] - mouseX+random(29,30);
        yStay[i]= yValues[i]-mouseY+random(15,25);
      }
      if(xStay[i] != -1 && yStay[i]!=-1){
        xValues[i]=mouseX+ xStay[i];
        yValues[i]=mouseY+ yStay[i];
    }
    
    }
    
  if(yValues[i] > height + 5){
      yValues[i] = -5;
      xValues[i] = random(0,width);
    }
  }
}


The only problem is, once the snowflakes run out (there are 2000), it just stops. How do I make it so that once ALL of the snowflakes get on top of the umbrella, it starts over again? Any help would be appreciated! It is a project that is due tomorrow at 2:30. 
In my version, variable captureValue has an arbitrary value
which once assigned to an element from array x[],
the 1st loop within draw() ignores that one.

To be able to start over, a simple new counter could be decreased
each time a flake is captured by the umbrella.
Once it reaches zero, re-assigns new values to x[] & y[], just like what is done within setup().

Sorry I couldn't study your code now to be able to understand how to reset your flakes again.
Besides, it's more complex now!  

See if you can adapt my idea to suit yours.

Good luck!