I'm developing a horizontal side scrolling game, that consists of a character (a solid circular object) and terrain (the ground).
The character moves from left to right.
When my character (C)
enters a particular region (Region 2) / gains a power up, I want the character to fly above a certain height, and remain at that height until he exits the region.
Desired behaviour:
(C) (C) (C) <--Height to remain at in Region 2
(C)
(C) (C)<--UpperLimit
(C) (C) (C)
<^^^^^^^^^^^^^^^^^^^^^^^^^^^Ground^^^^^^^^^^^^^^^^^^^^^^^^^^^^^>
<----Region 1------><------Region 2------><------Region 3------>
I currently do the following:
In my game loop I check if the player has entered the region / or triggered the power up.
if (player.isInRegion2)
{
if(player.position.y < upperLimit)
{
[player fly];
}
}
And my fly method:
-(void)fly
{
_body->ApplyLinearImpulse(b2Vec2(0,10), _body->GetPosition(), YES);
}
The problem is, that once the player flies past upperLimit
,I stop applying the impulse. Inertia carries the player to a certain height above upperLimit
, but then gravity causes him to drop down to the upper limit, at which point the impulse is applied again! As a result, its bumpy! Instead of the smooth inverted "U" curve that I am aiming for in my diagram, I get a "UU" curve.
Actual behaviour:
(C) (C) (C) (C)
(C) (C) (C)
(C) (C) (C)
(C) (C) (C)
<^^^^^^^^^^^^^^^^^^^^^^^^^^^Ground^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^>
<----Region 1------><------Region 2------------------><------Region 3------>
How can I correct my algorithm so my character smoothly flies to my target height and remains there until he exits the region ?
EDIT: I tried the following mentioned by Alok:
_body->ApplyForce( b2vec2(0.0f,- _body->GetMass() * world->GetGravity()),_body->GetWorldCenter(),YES );
But it doesn't work. I think it doesn't work because I use a fixed time step :
static double UPDATE_INTERVAL = 1.0f/60.0f;
static double MAX_CYCLES_PER_FRAME = 5;
static double timeAccumulator = 0;
timeAccumulator += dt;
if (timeAccumulator > (MAX_CYCLES_PER_FRAME * UPDATE_INTERVAL))
{
timeAccumulator = UPDATE_INTERVAL;
}
int32 velocityIterations = 3;
int32 positionIterations = 2;
while (timeAccumulator >= UPDATE_INTERVAL)
{
timeAccumulator -= UPDATE_INTERVAL;
_world->Step(UPDATE_INTERVAL,
velocityIterations, positionIterations);
_world->ClearForces();
}