В
статье про физику EdgeBug и JumpBug мы познакомились с такой техникой, как bounce. Название это не общеупотребительное, и в дополнение к нему мы сейчас введём ещё одно. Можно найти немало примеров сокращений, когда игрок падает с большой высоты, делает bounce о наклонную поверхность и затем ударяется о другую поверхность, получая вертикальную скорость. Причём эта поверхность как правило не является слайдом, но движение по ней очень похоже на скольжение. Таким примером может послужить сокращение на
kzno_extremeblock, когда игрок ударяется о кнопку старта, затем движется на doubleduck'ах до наклонной поверхности и уже на ней происходит то самое скольжение, которое мы будем называть
Glide. Попробуем разобраться в физике этого явления.
Мы уже знаем, что в
PM_WalkMove выполняется трейс в направлении скорости, и если этот трейс ничего не задел, то новым положением игрока
origin
становится конец трейса. При переходе с горизонтальной поверхности на наклонную трейс в какой-то момент пересечёт эту наклонную поверхность, и тогда нужно, прямо как это было в
PM_AirMove, с помощью вызова
PM_FlyMove протянуть положение до пересечения, а затем спроецировать вектор скорости на наклонную плоскость и оставшийся путь протянуть уже вдоль плоскости. Однако на этом работа
PM_WalkMove не заканчивается:
Координаты и скорости, полученные в ходе работы
PM_FlyMove, сохраняются в переменные
down
и
downvel
, и производится расчёт для альтернативного перемещения: трейс на высоту ступеньки
stepsize
(18 юнитов) вверх, перемещение в конец трейса, вызов
PM_FlyMove, ещё один трейс обратно на
stepsize
вниз, перемещение в конец нового трейса. Как можно догадаться, этот вариант перемещения создан для того, чтобы можно было без выполнения прыжка подниматься по ступенькам. Ну а выбор между двумя вариантами производится следующим образом:
Если трейс вниз на
stepsize
пересекал слайд, то выбираем первый вариант. В противном случае выбираем тот вариант, который произвёл большее горизонтальное перемещение. Причём во втором варианте вертикальная скорость берётся из первого варианта. Звучит как-то неочевидно, поэтому рассмотрим простой пример. Пусть мы движемся со скоростью 400 юнитов/с в сторону плоскости, наклонённой на 45°. Два варианта возможного перемещения будут выглядеть следующим образом:
Хотя ступенек здесь нет, выигрывает по дистанции второй вариант. В этом случае горизонтальная скорость останется прежней, а вертикальная возьмётся из расчёта первого варианта (проекция скорости на плоскость даст
400 * cos(45°)
юнитов/с, а её вертикальная составляющая
400 * cos(45°) * cos(45°) = 400 / 2 = 200
юнитов/с). Далее
PM_CategorizePosition обнаружит, что вертикальная скорость больше 180 юнитов/с, и выставит флаг нахождения в воздухе. На следующем фрейме вместо
PM_WalkMove за нас возьмётся
PM_AirMove, в которую попадёт скорость величиной 400 по горизонтали и 192 по вертикали (8 юнитов/с у нас успела забрать гравитация в лице
PM_FixupGravityVelocity и
PM_AddCorrectGravity). В ней вызов
PM_FlyMove спроецирует вектор скорости, так что мы получим
(400 + 192) / 2 = 296
юнитов/с по горизонтали и столько же по вертикали. Начиная с этого момента логика движения действительно похожа на то, что происходит на слайде: вертикальная скорость теряет 8 юнитов/с, суммарная скорость проецируется на плоскость и становится меньше по величине. Отличие здесь состоит в том, что как только вертикальная скорость окажется меньше 180 юнитов/с,
PM_CategorizePosition перестанет утверждать, что мы находимся в воздухе, и управление скоростью вновь перейдёт к
PM_WalkMove, которая вместе с
PM_Friction будет гасить скорость намного быстрее.
Для этого же примера несложно прикинуть, какой должна быть минимальная начальная горизонтальная скорость, которая позволит перейти в glide. Исходя из условия в
PM_CategorizePosition на 180 юнитов/с по вертикали, получаем 360 юнитов/с по горизонтали. Для более пологих плоскостей требуемая скорость ещё выше. Отсюда становится понятно, что обычного разгона престрейфом для перехода на glide не хватит. Однако здесь возникает следующая идея: что если попытаться сделать glide, прыгнув во время движения вверх по наклонной плоскости? Как мы выяснили в
статье про физику bhop, вертикальная скорость после прыжка составляет
sqrt(2 * 800 * 45) - 4 = 264.328
юнитов/с, что больше 180, так что нам остаётся лишь набрать горизонтальную скорость больше 264.328. А вот это сделать с помощью престрейфа уже не так сложно, причём после проецирования скорости на плоскость вертикальная составляющая оказывается больше, чем в момент прыжка, а значит сам прыжок станет выше. Эта техника прыжка, увеличивающая высоту за счёт перехода в glide, в своё время получила название
Nannou Jump в честь джампера
Nannou, который с помощью неё продемонстрировал крайне сложное сокращение на карте
ae_strafers_heaven:
Здесь он разгоняется с помощью
W до скорости 277 юнитов/с и запрыгивает на стену высотой 64 юнита. По расчётам для увеличения высоты прыжка на 1 юнит достаточно набрать по горизонтали примерно 271 юнит/с. Однако сложность здесь появляется во-первых из того, что не вся часть набранного престрейфа имеет нужное направление, во-вторых начальная точка прыжка находится ниже подножья стены, и в-третьих после прыжка нужно ещё и успеть долететь до стены пока вертикальная скорость не поменяла знак.
Высота прыжка может быть увеличена ещё больше, если есть возможность предварительного набора скорости. Например, последний прыжок на
all1_hb_Johnny предполагает, что скорость будет набрана во время падения (высота блока перед финишем согласно надписи равна 65 юнитам):
Впрочем, последний прыжок здесь можно сделать и альтернативным способом с помощью weirdjump, тут уже кому как удобнее.