stuwest
stuwest

Reputation: 928

Gravity simulation going haywire

I'm currently working on a Processing sketch featuring a very basic gravity simulation (based on an example given in Daniel Schiffman's book Learning Processing) but my gravity keeps behaving in a bizarre way and I'm at a loss to know what to do about it. Here's the simplest example I can come up with:

float x = 50;
float y = 50;

float speed = 2;
float gravity = 0.1;

void setup() {
  size(400, 400);
}

void draw() {
  background(255);

  fill(175);
  stroke(0);
  ellipseMode(CENTER);
  ellipse(x, y, 10, 10);

  y = y + speed;
  speed = speed + gravity;

//Dampening bounce effect when the ball hits bottom
  if (y > height) {
    speed = speed * -0.95;
  }
}

The above is virtually identical to what's in Schiffman's book aside from a different starting speed and a different window size. It seems to work fine for the first two bounces but on the third bounce the ball becomes stuck to the bottom of the window.

I have no idea where to even begin trying to debug this. Can anyone give any pointers?

Upvotes: 1

Views: 1083

Answers (2)

Donald W. Smith
Donald W. Smith

Reputation: 101

Setting y to height in the (if y > height) block helps, but the ball never comes to 'rest' (sit on the bottom line when done).
There are two problems with Shiffman's example 5.9 which is where you probably started:
1) y can become greater than (height + speed), which makes it seem to go thud on the ground or bounce wildly
-- fixed with the suggestion
2) The algorithm to update y does things in the wrong order, so the ball never comes to rest Correct order is:

  • if it is time to 'bounce
    • negate speed including dampening (* 0.95)
    • set y to location of the 'ground'
  • Add gravity to speed
  • Add speed to y

This way, when it is time to bounce (y is > height), and speed is positive (going downward):
speed is set to negative (times dampening)
y is set to height
speed is set less negative by the gravity factor
y is made less positive by adding the (still negative) speed

In my example, I didn't want the object to disappear so I use a variable named 'limit' to be the lowest (most positive y) location for the center of the object.

float x = 50;
float y = 50;

float speed = 2;
float gravity = 0.1;

void setup() {
  size(400, 400);
  y = height - 20;  
}

void draw() {
  background(255);

  fill(175);
  stroke(0);
  ellipseMode(CENTER);
  ellipse(x, y, 10, 10);

  float limit = height - (speed + 5);

//Dampening bounce effect when the ball hits bottom
  if (y > limit) {
    speed = speed * -0.95;
    y = limit;
  }
  speed = speed + gravity;
  y = y + speed;
}

Upvotes: 1

David Schwartz
David Schwartz

Reputation: 182763

If y remains greater than height, your code just keeps flipping the speed over and over without giving the ball a chance to bounce. You want the ball to move away from the boundary whenever it is at or past the boundary.

Upvotes: 2

Related Questions