Search code examples
processing

Processing | How to stop the ball from changing it's color


Here's a little code that I've written to get a ball bouncing in Processing. The ball should change it's color everything it bounces off the "ground" and become slower and slower and lay at the ground at the end. But - and that's the problem I've got - the ball doesn't stops changing it's color at the bottom - and that means it didn't stops bouncing, right?

The question is: How do I tell the ball to stop and not to change it's color anymore?

float y = 0.0;
float speed = 0;
float efficiency = 0.9;
float gravitation = 1.3;


void setup(){
  
  size(400, 700);
  //makes everything smoother
  frameRate(60);
  //color of the ball at the beginning
  fill(255);
  
}

void draw() {
  
  // declare background here to get rid of thousands of copies of the ball
  background(0);
  
  //set speed of the ball
  speed = speed + gravitation;
  y = y + speed;
  
  //bouce off the edges
  if (y > (height-25)){
    //reverse the speed
    speed = speed * (-1 * efficiency);
    
    //change the color everytime it bounces off the ground
    fill(random(255), random(255), random(255));
  }
  
  //rescue ball from the ground
  if (y >= (height-25)){
    y = (height-25);
  }
 
/*
  // stop ball on the ground when veloctiy is super low
  if(speed < 0.1){
    speed = -0.1;
  }
*/
  
  // draw the ball
  stroke(0);
  ellipse(200, y, 50, 50);
  
}

Solution

  • The problem is that even though you are setting the speed to -0.1 when it is small, and y to height - 25, the very next pass through the loop adds gravity to speed and then speed to y, making y larger than height - 25 (by slightly more than 1 pixel) again. This makes the ball jump up and down through an infinite loop of hops of zero height.

    You could use a threshold on the reflected speed. If it is below the threshold, stop the loop.

    At the top of the file, add a line like

    float threshold = 0.5; //experiment with this
    

    Then in draw(), right after the line

    speed = speed * (-1 * efficiency);
    

    add the line

    if(abs(speed) < threshold) noLoop();
    

    In this case, you can throw away the if clause which checks when the speed is super-low.