Как заставить объект летать или плавать выше определенной высоты, используя Box2d?

0

Я разрабатываю горизонтальную прокручивающую игру, состоящую из персонажа (сплошной круглый объект) и местности (земли).

Символ движется слева направо.

Когда мой персонаж (C) входит в конкретный регион (регион 2)/получает питание, я хочу, чтобы персонаж летал над определенной высотой и оставался на той высоте, пока не покинет регион.

Желаемое поведение:

                           (C)  (C)  (C) <--Height to remain at in Region 2
                                         (C)
                        (C)                  (C)<--UpperLimit

    (C)              (C)                         (C)
<^^^^^^^^^^^^^^^^^^^^^^^^^^^Ground^^^^^^^^^^^^^^^^^^^^^^^^^^^^^>
<----Region 1------><------Region 2------><------Region 3------>

В настоящее время я делаю следующее:

В моем игровом цикле я проверяю, вошел ли игрок в регион/или активировал питание.

    if (player.isInRegion2)
    {
        if(player.position.y < upperLimit)
        {
            [player fly];
        }
    }

И мой метод fly:

-(void)fly
{
    _body->ApplyLinearImpulse(b2Vec2(0,10), _body->GetPosition(), YES);
}

Проблема в том, что как только игрок пролетает мимо upperLimit, я перестаю применять импульс. Инерция переносит игрока на определенную высоту над upperLimit, но затем гравитация заставляет его опуститься до верхнего предела, после чего импульс снова применяется! В результате его ухабистый! Вместо гладкой перевернутой кривой "U", на которую я нацелен в своей диаграмме, я получаю кривую "UU".

Фактическое поведение:

                           (C)  (C)  (C)            (C)
                                          (C)    (C)   (C)
                        (C)                  (C)          (C)

    (C)              (C)                                       (C)
<^^^^^^^^^^^^^^^^^^^^^^^^^^^Ground^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^>
<----Region 1------><------Region 2------------------><------Region 3------>

Как я могу исправить свой алгоритм, чтобы мой персонаж плавно летал до моей целевой высоты и остается там до тех пор, пока он не покинет регион?

EDIT: Я попробовал следующее, упомянутое Алоком:

_body->ApplyForce( b2vec2(0.0f,- _body->GetMass() * world->GetGravity()),_body->GetWorldCenter(),YES );

Но это не сработает. Я думаю, что это не работает, потому что я использую фиксированный временной шаг:

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();
}
Теги:
game-physics
box2d
physics
cocos2d-iphone

2 ответа

0
Лучший ответ

После того, как я пересекаю верхний предел, я установил y-компонент скорости тела в нуль, пока не выйду из области.

0

Я думаю, вы имеете в виду, что он должен плавать в одной позиции Y. Для этого вы должны применить силу даже после UPPER_LIMIT, которая внутренне равна Gravity и ее массе.

tempBody-> ПрименитьForce (b2Vec2 (0.0f, - world-> GetGravity(). Y * tempBody-> GetMass()), tempBody-> GetWorldCenter());

  • 0
    Вы можете объяснить ? Я понимаю концепцию, но, применяя ее, я получаю то же поведение, что и раньше. Я изменил свой код, добавив блок «else», если он превышает верхний предел, чтобы вызвать код, который вы упомянули выше. Но я получаю такое же поведение.
  • 0
    Здесь вы просто применяете обратную силу для гравитации. Перейдите по этой ссылке, которую вы можете понять. coderzheaven.com/2012/04/12/...
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню