Сделать объект скользящим вокруг препятствия

У меня есть области пути, которые я создаю в игре для canvas /html5, и она работает так, чтобы игрок оставался в этих областях. У меня есть функция isOut (border, x, y), которая возвращает true, если точка находится за границей. Я проверяю только новую позицию x /y отдельно с соответствующей старой позицией x /y. Затем, если каждый из них отсутствует, я присваиваю им предыдущее значение из предыдущего кадра. Старые позиции хранятся в переменной от закрытия, которое я сделал.

вот так:

opos = [x,y];//old position
npos = [x,y];//new position

if(isOut(bound, npos[0], opos[1])){
    npos[0] = opos[0]; //assign it the old x position
}
if(isOut(bound, opos[0], npos[1])){
    npos[1] = opos[1]; //assign it the old y position
}

Он выглядит красиво и хорошо работает под определенными углами, но если ваша граница имеет диагональные области, это приводит к дрожанию движения. Происходит то, что y pos выходит из области, в то время как x не делает этого и продолжает толкать игрока в сторону, как только он немного сдвинет игрока в сторону, игрок может двигаться вперед, а затем y выходит снова, и весь процесс повторяется , Кто-нибудь знает, как мне добиться более плавного скольжения ? У меня есть доступ к вектору скорости игрока, углу и скорости (при использовании с углом). Я могу перемещать игру с углом /скоростью или скоростью x /y, поскольку я создал резервные копии, чтобы перевести одно в другое, если они были изменены вручную.

3 голоса | спросил Isaiah 10 42011vEurope/Moscow11bEurope/MoscowThu, 10 Nov 2011 21:22:23 +0400 2011, 21:22:23

1 ответ


1

предполагая, что путь создан из ломаной линии, ваша функция isOut может сделать больше, чем просто возвращать, находится ли игрок вне пути или нет. почти легко определить, какую линию прошел ваш игрок, когда он вышел наружу, а затем легко вычислить вектор, перпендикулярный к пересеченной линии, и точное положение, в котором игрок вышел за границу. используя эти данные, вы можете создать новую функцию движения, которая не будет нарушена.

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

NiPoint3 CTerrainController::GetSlideMovement(NiPoint3 &pOrigin, NiPoint3 &pDir)
{
    const unsigned int SearchCount = 5;
    float start, end;
    float rang;
    NiPoint3 rh, lh;

    NiPoint3 right;
    start = 0.0f;
    end = -NI_PI / 2.0f;
    rh = pOrigin;
    rh.z -= CHARACTER_WAIST_HEIGHT;
    for (unsigned int i = 0; i < SearchCount; i ++)
    {
        float ang = (start + end) / 2.0f;
        NiMatrix3 rot;
        rot.MakeZRotation(ang);
        right = rot * pDir;
        right *= (pDir * right) / right.SqrLength();
        if (mPick.PickObjects(pOrigin + right, -NiPoint3::UNIT_Z) && mPick.GetResults().GetAt(0)->GetAVObject()->GetName() != "collision_no walk")
        {
            end = ang;
            rh = mPick.GetResults().GetAt(0)->GetIntersection();
        }
        else
            start = ang;
    }
    rang = -end;

    NiPoint3 left;
    start = 0.0f;
    end = NI_PI / 2.0f;
    lh = pOrigin;
    lh.z -= CHARACTER_WAIST_HEIGHT;
    for (unsigned int i = 0; i < SearchCount; i ++)
    {
        float ang = (start + end) / 2.0f;
        NiMatrix3 rot;
        rot.MakeZRotation(ang);
        left = rot * pDir;
        left *= (pDir * left) / left.SqrLength();
        if (mPick.PickObjects(pOrigin + left, -NiPoint3::UNIT_Z) && mPick.GetResults().GetAt(0)->GetAVObject()->GetName() != "collision_no walk")
        {
            end = ang;
            lh = mPick.GetResults().GetAt(0)->GetIntersection();
        }
        else
            start = ang;
    }

    if (rang < end)
        return rh;
    return lh;
}

некоторые заметки:

эта функция получает исходные данные и скорость игрока в качестве входных данных, а затем возвращает скорость после применения эффекта слайда. он пытается найти свободное пространство перед игроком и говорит игроку двигаться в этом конкретном направлении. Оператор if, который проверяет выбранные объекты, почти эквивалентен if(!isOut(pOrigin + right))

ответил Ali1S232 11 52011vEurope/Moscow11bEurope/MoscowFri, 11 Nov 2011 01:55:37 +0400 2011, 01:55:37

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132