Domanda

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();
}
È stato utile?

Soluzione 2

After I cross the upper limit, I set the bodies velocity y-component to zero, until I exit the region.

Altri suggerimenti

I think you mean it has to float in same Y Position. For that you should apply force even after UPPER_LIMIT which internally equals Gravity and it's mass.

tempBody->ApplyForce( b2Vec2(0.0f,- world->GetGravity().y * tempBody->GetMass()),tempBody->GetWorldCenter());

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top