Page 1 of 1
Bodies attracting bodies
Posted: Mon Jul 13, 2009 3:02 pm
by jedd.jones
I'm looking for a good way to make one body attract other bodies like a gravitational field. I am wondering if there is some built in way to do this or am I going to need check proximity and do impulses per body?
-Jedd
Re: Bodies attracting bodies
Posted: Mon Jul 13, 2009 5:49 pm
by slembcke
No, there is no built in way to do it, and yes you will have to apply forces.
Re: Bodies attracting bodies
Posted: Sat Jul 18, 2009 6:40 pm
by gravity
I've been thinking about doing the same thing,
I iterated over two loops
Ball is just a class that has a cpBody property - "ballBody." "bodies" is an array of all of the bodies on the screen. I call this in my main game loop "tick" :
Code: Select all
for (int i = 0; i < [bodies count]; i++)
{
Ball *bodyi = [bodies objectAtIndex:i];
for (int j = i + 1; j < [bodies count]; j++) //notice that iteration goes from i+1, not 0
{
Ball *bodyj = [bodies objectAtIndex:j];
cpVect displacement = cpvsub(bodyi.ballBody->p, bodyj.ballBody->p); //get distance between the two bodies
cpVect normDisplacement = cpvnormalize(displacement); //normalize this
float forceScale = -400000* bodyi.ballBody->m * bodyj.ballBody->m / (cpvlengthsq(displacement));
//and multiply it by the magnitude of the force
cpVect force = cpvmult(normDisplacement, forceScale);
bodyi.netForce = cpvadd(bodyi.netForce, force);
bodyj.netForce = cpvsub(bodyj.netForce, force);
}
}
and then later on apply the netForce to each body.
This seems to work, except, I'm getting an outrageous increase in speed over time. I do apply cpBodyResetAllForces before hand, and the netForces all add to 0, so I don't know where the crazy increase in energy is coming from.
Hope this helps, and if anybody has anything to say on it, it is appreciated.
Re: Bodies attracting bodies
Posted: Sat Jul 18, 2009 11:12 pm
by gravity
lol.
My... solution... if you can call it that,
Code: Select all
for (int i = 0; i < [bodies count]; i++)
{
Ball *bodyi = [bodies objectAtIndex:i];
if (cpvlengthsq(bodyi.netForce) > 2000000) {
bodyi.netForce = cpvmult(bodyi.netForce, 1/1.2);
if (cpvlengthsq(bodyi.netForce) > 2500000) {
bodyi.netForce = cpvmult(bodyi.netForce, 1/1.5);
if (cpvlengthsq(bodyi.netForce) > 3000000) {
bodyi.netForce = cpvmult(bodyi.netForce, 1/1.8);
if (cpvlengthsq(bodyi.netForce) > 3500000) {
bodyi.netForce = cpvmult(bodyi.netForce, 1/2.5);
if (cpvlengthsq(bodyi.netForce) > 4500000) {
bodyi.netForce = cpvmult(bodyi.netForce, 1/2.9);
if (cpvlengthsq(bodyi.netForce) > 9500000) {
bodyi.netForce = cpvmult(bodyi.netForce, 0);
}
}
}
}
}
}
cpBodyApplyForce(bodyi.ballBody, bodyi.netForce, CGPointZero);
}
![Rolling Eyes :roll:](./images/smilies/icon_rolleyes.gif)