Page 1 of 1

Shape/Body that will move but not be affected by gravity?

PostPosted: Wed Dec 31, 2014 12:14 am
by 7e11
Hello, I am working on a project using Chipmunk, Gosu, and Ruby. I am trying to create a body that will not be affected by gravity / other outside forces, but will move with a set velocity and rebound off of objects realisticly. Something like the image in the attached file.

GameImage.png
Example of what I want
GameImage.png (11.04 KiB) Viewed 3540 times


First I tried making the ball a static body, but that just resulted in the ball staying stationary when created no matter what forces were applied to it (Duh.)

Then I tried using
Code: Select all
CP::Space.rehash_static()
. However, I was not able to find this method in the bindings, and could not use it.

Next I tried to add the balls with real bodies, but with elasticities in the 50s. once the balls were able to hit multiple sides of the box, their velocity increased exponentially, and they skyrocketed out of the area.

Here is my (Broken) Ball Class

Thanks.

Re: Shape/Body that will move but not be affected by gravity

PostPosted: Sun Jan 04, 2015 4:25 pm
by maximile
Real bodies are the way to go. Elasticity should be set to 1.0 for the ball and the walls. This will get you close to what you want, but over time the velocity will change slightly. So you can set it every frame using cpBodySetVel to maintain the right speed.

Re: Shape/Body that will move but not be affected by gravity

PostPosted: Fri Feb 06, 2015 6:33 pm
by wrgood
I have solved this solution in a few ways, here are some things you can take a look at:

in cpSpace, there is a variable gravity. Normally you set that to whatever you want gravity to be, but when you look at the actual code that runs this gravity, you notice it just loops over all the objects, and applies the gravity. In one of my games, I just kept track of all the objects that had gravity applied (most of them), and just looped myself to apply the gravity just like they do in cpSpace. This way you can leave out whatever bodies you are not interested in.

this is the code from cpSpaceStep where the velocities are applied.
Code: Select all
// Integrate velocities.
cpFloat damping = cpfpow(space->damping, dt);
cpVect gravity = space->gravity;
for(int i=0; i<bodies->num; i++){
   cpBody *body = (cpBody *)bodies->arr[i];
   body->velocity_func(body, gravity, damping, dt);
}


Another option (that i haven't tried before), is every body has a velocity_func, and that is how any velocity gets applied to it. You can make your own function, and set the velocity func of your bodies. then you can branch depending on what you want to happen for each type of body. by default they use the function (found in cpBody)
Code: Select all
void cpBodyUpdateVelocity(cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt)
{
   // Skip kinematic bodies.
   if(cpBodyGetType(body) == CP_BODY_TYPE_KINEMATIC) return;
   
   cpAssertSoft(body->m > 0.0f && body->i > 0.0f, "Body's mass and moment must be positive to simulate. (Mass: %f Moment: %f)", body->m, body->i);
   
   body->v = cpvadd(cpvmult(body->v, damping), cpvmult(cpvadd(gravity, cpvmult(body->f, body->m_inv)), dt));
   body->w = body->w*damping + body->t*body->i_inv*dt;
   
   // Reset forces.
   body->f = cpvzero;
   body->t = 0.0f;
   
   cpAssertSaneBody(body);
}


Hope this helps