Прыжки с переменной высотой в боковых скроллерах

10

Как сделать так, чтобы игрок прыгал выше, если клавишу прыжка удерживать дольше? В настоящее время я просто уменьшаю гравитацию, пока нажата клавиша и игрок прыгает, но это выглядит странно.

Джон Стимак
источник
может быть, просто с помощью какой-то модификации того, насколько вы уменьшаете гравитацию, вы получаете лучшее прыжковое действие.
Ali1S232
@Gajet Это довольно неуклюже и кажется странным способом сделать это.
Коммунистическая утка
Хм, вы говорите, что снижение гравитации не означает, что вы используете физический движок. Это тот случай? Вы используете Импульсы, чтобы прыгать?
Джонатан Коннелл
Физического движка нет, и я не использую Импульсы
Джон Штимак
В каком случае, как падает ваш игрок? Вы просто переводите его положение в соответствии с вектором движения * прыжок * гравитации?
Джонатан Коннелл

Ответы:

9

Сначала вы должны решить, как вы хотите, чтобы прыжок был похож.

В реальной жизни высота прыжка определяется в тот момент, когда вы покидаете землю. Вы не можете продолжать прыгать выше, пока вы уже в воздухе.

Так что, если вы можете контролировать высоту прыжка, находясь в воздухе, вы получите некоторый эффект «реактивного ранца».

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

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

Я бы начал с этого:

Оставьте гравитацию в покое (т.е. никогда не меняйте ее). Когда игрок нажимает кнопку прыжка, применяйте силу прыжка, пока игрок нажимает кнопку прыжка (до некоторого ограничения по времени). Затем, когда игрок отпускает кнопку прыжка, он не может снова применить какую-либо силу прыжка (то есть он не может инициировать прыжок снова), пока он сначала не коснется земли, после чего прыжки будут возобновлены.

Ольховский
источник
Я попробовал это, и я получил эффект реактивного ранца. Мне было интересно, есть ли способ избежать этого.
Джон Штимак
1
Возможно, это не та игра, о которой вы мечтали, но в Super Mario 2 вы подпрыгнули выше, немного наклонившись перед прыжком. (Что в определенной степени интуитивно понятно, поскольку вы не прыгаете слишком далеко, если пытаетесь делать это прямо из положения стоя.)
Дариен
3
Jcubed: вместо добавления силы к скорости, попробуйте добавить силу непосредственно в позицию. Тогда игрок будет двигаться линейно вверх, а не ускоряться вверх.
Ольховский
@Jcubed: когда играешь в такие игры, как super meat boy, которые, я думаю, имеет тот же эффект прыжка, что и ты, кажется, что, пока ты удерживаешь кнопку прыжка, к персонажу прикладывается сила, она противоположна гравитации и меньше, чем она, и остальное похоже на то, что сказал Алховский. если бы я реализовал что-то подобное, я бы начал с 60-80% гравитации в качестве прыжковой силы.
Ali1S232
1
Я делаю это все время, просто сохраняйте время, в течение которого вы устанавливаете скорость прыжка вверх, удерживая кнопку достаточно короткой, чтобы это не было заметным эффектом реактивного ранца - тогда это будет как Супер Марио довольно легко, с небольшим количеством магии твики Не уменьшайте «силу», просто продолжайте сбрасывать скорость до максимальной скорости прыжка, пока не истечет время jumpHigherTime или игрок не отпустит кнопку ... также, я чувствую, что мальчики супер-мяса прыгают, чтобы быть неточными и раздражающими, как и любой прыжок с платформы который опирается только на физический движок; p
Оскар Дювеборн
7

Я видел, как некоторые люди делают это:

  1. Создайте переменную (я назову ее jumpTime) (число / double / float). Когда нажата клавиша перехода, установите jumpTimeкакое-либо число (т 0.5. Е. Это будет количество секунд, на которое повлияет удерживание клавиши перехода).

  2. Затем для каждого шага установите скорость, jumpTimeумноженную на какое-то другое число, и уменьшите jumpTimeна delta(разницу во времени между каждым шагом).

  3. Повторите это, пока не jumpTimeдостигнет нуля или ниже, или когда игрок отпускает клавишу прыжка. После этого используйте обычную физику (применяйте постоянное отрицательное ускорение, пока игрок не достигнет земли).

Возможно, вам придется использовать метод проб и ошибок (или «логическое угадывание»), чтобы найти подходящие значения для этих «некоторых чисел», если вы не знаете, как это сделать.


ОБНОВЛЕНИЕ: я нашел трюк, который делает прыжок более реалистичным (поскольку изначально он медленно поднимается, а затем быстро понижается). Infinite Mario также использует следующую строку (293 из Character.js версии JavaScript) ... this.Ya *= 0.85;Это просто как «воздушное перетаскивание» и ограничивает / замедляет скорость персонажа в воздухе. Таким образом, в каждом кадре умножьте y-скорость (вертикальную скорость) на число меньше единицы, чтобы оно замедлялось при падении назад (и, следовательно, и движение вверх, и падение вниз во время прыжка будет аналогичным и более реалистичным). Я знаю, я плохо объясняю ...

Когда персонаж прыгает, используя метод, который я первоначально описал выше, он «поднимается» быстрее, чем «падает вниз». Перетаскивание, однако, замедляет вертикальную скорость. Так как мы устанавливаем вертикальную скорость, чтобы быть пропорциональной jumpTimeкаждому кадру, это сопротивление не оказывает большого влияния на первую половину прыжка. Однако в следующей половине (падение вниз) вертикальная скорость устанавливается не для каждого кадра, а просто добавляется другим числом (в данном случае это гравитационная постоянная). Следовательно, сопротивление действует при падении, и поскольку оно уменьшает скорость (в любом направлении), оно замедляет падение, делая его похожим на первую половину.

Есть и другие способы решения этой проблемы, например, снижение влияния гравитации на персонажа по мере его падения. Однако нам нужно выяснить, насколько мы должны уменьшить гравитацию.


Пример из практики: Бесконечный Марио

Вот что я нашел (из строки 206 Mario.java Маркуса Перссона (Notch)):

    if (keys[KEY_JUMP] || (jumpTime < 0 && !onGround && !sliding))
    {
        if (jumpTime < 0)
        {
            xa = xJumpSpeed;
            ya = -jumpTime * yJumpSpeed;
            jumpTime++;
        }
        else if (onGround && mayJump)
        {
            world.sound.play(Art.samples[Art.SAMPLE_MARIO_JUMP], this, 1, 1, 1);
            xJumpSpeed = 0;
            yJumpSpeed = -1.9f;
            jumpTime = 7;
            ya = jumpTime * yJumpSpeed;
            onGround = false;
            sliding = false;
        }
        else if (sliding && mayJump)
        {
            world.sound.play(Art.samples[Art.SAMPLE_MARIO_JUMP], this, 1, 1, 1);
            xJumpSpeed = -facing * 6.0f;
            yJumpSpeed = -2.0f;
            jumpTime = -6;
            xa = xJumpSpeed;
            ya = -jumpTime * yJumpSpeed;
            onGround = false;
            sliding = false;

            facing = -facing;
        }
        else if (jumpTime > 0)
        {
            xa += xJumpSpeed;
            ya = jumpTime * yJumpSpeed;
            jumpTime--;
        }
    }
    else
    {
        jumpTime = 0;
    }

Версия javascript в основном та же https://github.com/robertkleffner/mariohtml5/blob/master/code/character.js

Это похоже на предложение Ольховского, но в этом случае сила будет пропорциональна количеству времени, прошедшего после того, как игрок нажал клавишу прыжка.

Моя версия JavaScript:

    if ( onGround && jump && !jumped ) {
        jumpTime = maxJumpTime;
        onGround = false;
        jumped = true;
        this.vel.y = jumpTime * jumpConstant;
        A = true;
    } else if ( !onGround && jump && jumpTime > 0 && !released ) {
        jumpTime -= evt.delta;
        this.vel.y = jumpTime * jumpConstant;
        B = true;
    } else if ( !onGround && ( !jump || jumpTime <= 0 ) ) {
        this.vel.y -= gravityConstant * evt.delta;
        jumpTime = 0
        released = true;
    } if ( this.pos.y < 0 && !A && !B ) {
        onGround = true;
        released = false;
        this.pos.y = 0;
        this.vel.y = 0;
    }
    if ( !jump && onGround ) jumped = false;

Однако некоторые значения для констант (например, "gravityConstant" и "jumpConstant"), тем не менее, дадут нереальный переход. Но иногда игры не должны быть реалистичными! ( обновление см. раздел обновления выше)

Этому вопросу уже более года, но я надеюсь, что это поможет!

ErnWong
источник
2

Как сказал Ольховский, высота прыжка определяется в тот момент, когда вы покидаете землю, а не после этого.

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

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

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

Конрад Рудольф
источник
2
Думаю, я помню, как играл на каком-то платформере именно с такой механикой - не отрывайтесь от земли, пока вы не «зарядите» прыжок. С помощью некоторых симпатичных анимаций (таких как облако пыли, растущее у ног персонажа) это можно сделать, чтобы чувствовать себя интуитивно понятным.
Яри ​​Комппа
2

Я нашел другое решение в ответе Дэвида Гувея на вопрос « Как заставить персонажа прыгать? »

Резюме:

Его идея состояла в том, чтобы установить скорость, когда игрок нажимает кнопку прыжка. В каждом кадре он только вычисляет гравитацию. Однако, когда игрок отпускает кнопку, он устанавливает скорость на меньшее значение, если скорость больше, чем она. Скорость уменьшается только в каждом кадре под действием силы тяжести.

Я не должен красть его ответ, так что читайте его пост. Его решение находится в разделе « Прыжок с переменной высоты ».

Так что на самом деле люди придумали много разных способов решить эту проблему ...

ErnWong
источник