Newbie Basic Bouncing Ball question

edited October 2013 in Questions about Code

I wrote this simple piece of code and i can't find the reason why after a few bounces (5 or 6) the ball sticks to the bottom? just tried to find it out for hours

float x = 300;
float y = 0;
float speedx = 0;
float speedy =5.0;
float gravity = 0.2;
float r = 50.0;

void setup(){
    size(600, 600);
    smooth();
}

void draw(){
    ball();
    move();
    bounce();
    gravity();
}

void ball() {
ellipse(x, y, r, r);
}

void move () {
    y=y+speedy;
}

void bounce() {
    if((x>width)||(x<0)){
        speedx=speedx*-1;
    }
    if((y>height)||(y<0)){
        speedy=speedy*-0.95;
    }
}

void gravity() {
    speedy=speedy+gravity;
}





    

    

  </pre>
Tagged:

Answers

  • Answer ✓

    post the code

  • posted the code, i had to find out how to format it.. sorry

  • you have to be careful with this. sometimes the y position is so far below the line before the bounce is detected that the -.95 velocity added on the next loop isn't enough to take it back above the line.

    add println(y + " : " + speedy); after line 33 and see....

  • edited October 2013
    604.1997 : -15.38999
    605.72974 : -14.449491
    613.0017 : -13.632967
    608.55005 : -12.698666
    608.7173 : -11.876254
    611.5184 : -11.137547 not enough of a bounce
    600.5808 : 10.390669 still below the line
    
    611.5184 - 11.137547 > 600...
    
  • thank you that should be the problem.. but i don't get the difference to daniel shiffmans code which works:

    
    // Learning Processing
    // Daniel Shiffman
    // http://www.learningprocessing.com
    
    // Example 5-9: Simple Gravity
    
    float x = 100;   // x location of square
    float y = 0;     // y location of square
    
    float speed = 0;   // speed of square
    
    // A new variable, for gravity (i.e. acceleration).   
    // We use a relatively small number (0.1) because this accelerations accumulates over time, increasing the speed.   
    // Try changing this number to 2.0 and see what happens.
    float gravity = 0.1;  
    
    void setup() {
      size(200,200);
    
    }
    
    void draw() {
      background(255);
    
      // Display the square
      fill(175);
      stroke(0);
      rectMode(CENTER);
      rect(x,y,10,10);
      
      // Add speed to location.
      y = y + speed;
      
      // Add gravity to speed.
      speed = speed + gravity;
      
      // If square reaches the bottom
      // Reverse speed
      if (y > height) {
        // Multiplying by -0.95 instead of -1 slows the square down each time it bounces (by decreasing speed).  
        // This is known as a "dampening" effect and is a more realistic simulation of the real world (without it, a ball would bounce forever).
        speed = speed * -0.95;  
      }
    }
    
    
    
        
    
  • edited October 2013 Answer ✓

    This is what I've come up with: >:/

    // forum.processing.org/two/discussion/702/
    // newbie-basic-bouncing-ball-question
    
    final static short DIAM = 70, RAD = DIAM >> 1;
    final static float GRAV = .2, BOUNCE = .95, INIT = 5;
    
    float x, y;
    float spdX, spdY = INIT;
    
    void setup() {
      size(100, 600);
    
      smooth();
      frameRate(60);
      ellipseMode(CENTER);
    
      fill(#008000);
      stroke(0);
      strokeWeight(3);
    
      x = width >> 1;
      y = RAD;
    }
    
    void mouseClicked() {
      y = constrain(mouseY, RAD, height - RAD);
      spdY = INIT;
    }
    
    void draw() {
      background(0300);
    
      display();
      move();
      gravity();
      bounce();
    }
    
    void display() {
      ellipse(x, y, DIAM, DIAM);
    }
    
    void move() {
      y += spdY;
    }
    
    void gravity() {
      spdY += GRAV;
    }
    
    void bounce() {
      //if (x > width  - RAD | x < RAD)   spdX *= -1;
      if (y > height - RAD | y < RAD)   spdY *= -BOUNCE;
    }
    
  • edited October 2013 Answer ✓

    but i don't get the difference to daniel shiffmans code

    different combination of start values, that's all.

    maybe he's chosen them because he knows they won't cause the issue, maybe he was lucky.

    the way around this is to set the position of the ball after the bounce as far above the bottom as it was below the limit when the bounce was detected (11.518 here), minus some bounce coefficient. it's kinda complicated (and i'm just off out...)

  • thank you very much!

  • edited October 2013

    I always warn with code like

    if (y > height - RAD | y < RAD) spdY *= -BOUNCE;

    or

    // If square reaches the bottom
      // Reverse speed
      if (y > height) {
        // Multiplying by -0.95 instead of -1 slows the square down each time it bounces (by decreasing speed). 
        // This is known as a "dampening" effect and is a more realistic simulation of the real world (without it, a ball would bounce forever).
        speed = speed * -0.95; 
      }
    

    because

    spdY *= -BOUNCE;

    or

    speed = speed * -0.95;

    doesn't give a stable / reliable / robust result. Let me explain.

    When the ball is too far outside the screen you mulitply it with BOUNCE (speed gets negative, good).

    But (big one) when in the next iteration it is still outside the screen you again mulitply with BOUNCE and the speed gets positive where it should really remain negative. Thus the ball can stutter outside the screen (move up and down in one spot).

    I always recommend

        speed = abs(speed) * -0.95; 
    

    So the result is reliable and always negativ. Good. (Because abs() gives you the absolute (always positive) value of speed and when you multiply it with a negative value, the result is always negative.)

    The line

    if (y > height - RAD | y < RAD) spdY *= -BOUNCE;

    we have to split into

      if (y > height - RAD )   spdY = abs(spdY) * -BOUNCE; // always neg
      if ( y < RAD)   spdY = abs(spdY) * BOUNCE; // always pos 
    
  • @Chrisir thanks very much that you clarified this for me!

  • you are welcome!

Sign In or Register to comment.