Reputation: 620
I want to simulate a ball bouncing, and in the future create more and make them rebound. This is my code (using p5.js, a processing library for javascript)
var xpos = 200;
var ypos = 450;
var vy = 0;
var gravity = 0.6;
var bounce = -1.00;
var diameter = 30;
function setup() {
var myCanvas = createCanvas(windowWidth, windowHeight);
stroke(255);
noFill();
}
function draw() {
background(0);
ellipse(xpos, ypos, diameter, diameter);
vy += gravity;
ypos += vy;
if(ypos > (windowHeight - diameter/2)) {
vy *= bounce;
}
}
It looks as if it's working fine, but when the bounce get's really small, it begins to glitch and disappears, here's a codepen. I don't know how to make it just stop and roll or something (obviously not roll if there is no x
property, but just stop moving after the bouncing stops)
Any help is appreciated, thank you.
Upvotes: 0
Views: 1209
Reputation: 886
You want to first apply acceleration, then do collision tests, then adjust position for collisions.
If you want restitution, apply that to vy
after each collision, e.g.
Edit: also using checks to see if an object should be "resting" helps
var xpos = 200;
var ypos = 0;
var vy = 0;
var gravity = 10;
var bounce = 0.9; // typically represented as a positive normalized value
var diameter = 30;
var sleepTolerance = gravity; // this will provide a solid result
// KA variables
var windowHeight = height;
var windowWidth = width;
frameRate(30);
var draw = function() {
background(0);
ellipse(xpos, ypos, diameter, diameter);
var asleep = false;
if(!asleep){
vy += gravity;
ypos += vy;
}
var heightAboveGround = ypos - (windowHeight - diameter/2);
if(heightAboveGround > 0) { // remember y is inverted
// position adjusted for reflection after collision
// including restitution (resulting from the bounce)
ypos -= bounce * heightAboveGround;
// apply restitution to subsequent velocity
vy *= -bounce;
if (heightAboveGround <= sleepTolerance && abs(vy) <= sleepTolerance){
asleep = true;
ypos = windowHeight - diameter/2;
}
}
};
Upvotes: 2
Reputation: 3104
I was able to more closely simulate a bouncing ball by making two adjustments:
Update the bounce:
// Attenuate velocity by making the magnitude of this value < 1
var bounce = -0.9;
// Give initial vy
var vy = 0.1;
And ensure we only add gravity when ball is "in the air" (prevents our ball from "sinking beneath the ground"):
function draw() {
background(0);
ellipse(xpos, ypos, diameter, diameter);
var floor = windowHeight - diameter/2;
var inAir = ypos <= floor;
var moving = Math.abs(vy) > 0.01;
if (inAir && moving) {
vy += gravity;
}
ypos += vy;
if(!inAir && vy > 0) {
vy *= bounce;
if (!moving) {
vy = 0;
}
}
}
Upvotes: 0