We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpPrograms › Bouncing with gravity
Page Index Toggle Pages: 1
Bouncing with gravity (Read 1111 times)
Bouncing with gravity
Dec 29th, 2009, 7:21am
 
Hi, I've tried to make a sketch of a bouncin ball with gravity. Muy problem is that my ball bonce higher and higher. I have a hint of the cause, but Im not finishing finding the solution:

Because I increase y coordinate in an undeterminate amount each time, when the ball pass the floor, I have to correct this coordinate to height size, and there is an error there.

Because is complicated to correct it exactly, I´ve tried to correct it making the ball bounce lower and lower, so I subtract the gravity when it bounce in the floor. Well I add because y coordinates increases downside.

This is the code:

Code:
float x=100;
float yin=100;
float y;
float exceso;
float vx=10;
float gravedad=0.8;
float vy=0;
float diametro= 10;
//principio

void setup(){
y=yin;
size(600,600);//tamaño
background(100);//fondo
stroke (255);//lápiz
fill(255);
smooth(); //dibuja con suavidad
frameRate(20);//velocidad
}
//dibujo
void draw(){
background(100); //borra
ellipse(x,y,diametro,diametro);//dibuja la bola
x=x+vx;//aumenta x
y=y+vy;
vy=vy+gravedad;
//rebote

if(y>height-diametro/2){
vy=-vy+gravedad;
y=height-diametro/2;
}
if(y<diametro/2){
vy=-vy;
y=diametro/2;
}
if(x>width-diametro/2){
vx=-vx;
x=width-diametro/2;
}
if(x<diametro/2){
vx=-vx;
x=diametro/2;

}
}
Re: Bouncing with gravity
Reply #1 - Dec 29th, 2009, 7:56am
 
First off when it hits the floor/walls gravity doesn't come into it, simply multiply vx or vy by -1, or smaller if you want it to slow down each bounce (see code below).  As for the problem of it bouncing higher each bounce: you need to apply gravity to vy before applying vy to y.  i.e.:

Code:
vy += gravedad; 
 
 x += vx;//aumenta x
 y += vy;


and not:

Code:
x += vx;//aumenta x
 y += vy;
 vy += gravedad;



Note that y += vy; is just a shortcut for y = y + vy;.

Here's the revised code (see comments):

Code:
float x=200;
float yin=100;
float y;
float exceso;
// vx = 10 is perhaps a little high
float vx=5;
// 0.8 is definitely too high!
float gravedad=0.1;
float vy=0;
float diametro= 10;
float bounceFriction = 0.9;

void setup(){
 y=yin;
 size(600,600);//tamaño
 background(100);//fondo
 // Why draw a stroke if it's the same colour as the fill?
 //stroke (255);//lápiz
 noStroke();
 fill(255);
 smooth(); //dibuja con suavidad
 // it's not really a great idea to slow down frameRate to slow down movement
 // especially when this can be achieved simply by tweaking the variables such as gravity and vx
 //frameRate(30);//velocidad
}

void draw(){
 background(100); //borra
 ellipse(x,y,diametro,diametro);//dibuja la bola
 
 // Do this before adjusting current y!
 vy += gravedad;
 
 x += vx;//aumenta x
 y += vy;
 
 if(y>height-diametro/2){
   vy *= -bounceFriction;
   y=height-diametro/2;
 }  
 if(y<diametro/2){
   vy *= -bounceFriction;
   y=diametro/2;
 }  
   if(x>width-diametro/2){
   vx *=-bounceFriction;
   x=width-diametro/2;
 }
 if(x<diametro/2){
   vx *=-bounceFriction;
   x=diametro/2;
   
 }
}
Re: Bouncing with gravity
Reply #2 - Dec 30th, 2009, 6:35am
 
Thank you, I've made the changes and it works, I´ve been letting the ball bounce for a long time and it hasn't change its maximun height. But I dont understand wthe reason why my code doesn´t work and yours does.

Now I,ve tried to use the same code to make a simple videogame and the ball bounce lower and lower. I can´t see any difference between both codes. In fact I used copy and paste.

This is the code simplified of the videogame:

Code:
Bola pelota;
Bola jug1;
Bola jug2;
float vel=2;
float dista;
float gravedad=1.5;
boolean der1;
boolean izq1;
boolean der2;
boolean izq2;
//principio

void setup(){
size(500,350);//tamaño
pelota=new Bola(0,10,10,0,20);
jug1=new Bola(width/4,height-100,0,4,70);
jug2=new Bola(width*3/4,height-100,0,4,70);
background(100);//fondo
stroke (255);//lápiz
fill(255);
smooth(); //dibuja con suavidad
frameRate(17);//velocidad
}

//dibujo
void draw(){
background(100); //borra
rect(width/2,height-200,10,200);
pelota.bota();
jug1.bota();
jug2.bota();

jug1.golpea();
jug2.golpea();
mueve();
}


class Bola{
float x;
float y;
float vx;
float vy;
float diametro;

Bola(float xin,float yin,float vxin,float vyin, float diame){
x=xin;
y=yin;
vx=vxin;
vy=vyin;
diametro=diame;
}
void bota(){

ellipse(x,y,diametro,diametro);
vy=vy+gravedad;
x=x+vx;//aumenta x
y=y+vy;

//rebote

if((abs(x-width/2)<diametro/2+5)&&(y>height-200)){
if(x<width/2){
x=width/2-(diametro/2+5);
}
else
{
x=width/2+(diametro/2+5);
}
vx=-vx;
}
if(y>height-diametro/2){
vy=-vy;
y=height-diametro/2;

}
if(y<diametro/2){
vy=-vy;
y=diametro/2;
}
if(x>width-diametro/2){
vx=-vx;
x=width-diametro/2;
}
if(x<diametro/2){
vx=-vx;
x=diametro/2;

}
}
void golpea(){
dista=sqrt((x-pelota.x)*(x-pelota.x)+(y-pelota.y)*(y-pelota.y));
if (dista<diametro/2+pelota.diametro/2){
do{
dista=sqrt((x-pelota.x)*(x-pelota.x)+(y-pelota.y)*(y-pelota.y));
pelota.y-=pelota.vy/sqrt(pelota.vy*pelota.vy);
}
while (dista<=diametro/2+pelota.diametro/2);
pelota.vy*=-1;
if(pelota.x<x){
pelota.vx=-abs(pelota.vx);
}
else{
pelota.vx=abs(pelota.vx);
}
}
}
}

void mueve(){

jug1.x+=jug1.vx;

jug2.x+=jug2.vx;


}

Re: Bouncing with gravity
Reply #3 - Dec 30th, 2009, 7:04am
 
The answer is in the bounce:

Quote:
float bounceFriction = 0.9;

// <snip />

 if(y>height-diametro/2){
   vy *= -bounceFriction;
   y=height-diametro/2;
 }  


Instead of "vy = -vy" when it hits the ground I multiply it by -bounceFriction.  Since bounceFriction < 1 it reduces the velocity of the ball each time it hits a wall...
Page Index Toggle Pages: 1