Последние рекорды серверов
Pro Nub

Физика HighJump

Опубликовано Kpoluk 13 Мая 2023 в 11:30
В статье про физику стрейфов мы немного покопались в функции PM_Friction, которая отвечала за трение, действующее на игрока. Тогда мы считали, что переменная friction просто равна значению квара sv_friction (по умолчанию 4). На самом деле здесь всё гораздо интереснее:


С точки зрения взаимодействия с картой можно сказать, что игрок – это параллелепипед, который задаётся двумя точками - player_mins и player_maxs. Это точки задают hull, то есть «оболочку» игрока. Для нас будут важны два состояния hull – когда игрок стоит и когда сидит (за выбор состояния отвечает переменная pmove->usehull). Как видно из кода, в горизонтальной плоскости моделька занимает квадрат 32 на 32 юнита, высота же составляет 72 юнита стоя и 36 юнитов сидя.

При движении по земле каждый фрейм PM_Friction производит так называемый трейс (trace). Обычно трейс означает, что движок проводит линию из одной точки в другую, чтобы выяснить, пересекла ли она что-нибудь по пути. Если пересечение есть, то трейс может сообщить, что именно за объект встретился на пути, а также на каком расстоянии. В нашем случае трейс чуть сложнее, так как функция PM_PlayerTrace учитывает размеры игрока в направлении трейса.

Начальная точка находится в 16 юнитах в направлении текущей скорости на уровне ног (который для стоячего игрока ниже его положения origin на 36 юнитов, а для сидячего игрока – на 18 юнитов). Конечная точка ниже начальной на 34 юнита. К этому нужно прибавить половину роста, то есть опять же 36 либо 18 юнитов.


Следовательно, если мы подбегаем к краю блока, то движок проверит, не выше ли он 70 юнитов, а если подползаем сидя – 52 юнитов. Если выше, то переменная friction умножится на pmove->movevars->edgefriction, то есть на значение квара edgefriction. По умолчанию он равен 2, поэтому трение станет в два раза сильнее. При значении edgefriction 1 любой hj превратится в обычный lj, а при значении 0 трение у края блока будет вообще пропадать (то есть если мы отпустим все кнопки, то просто соскользнём с блока).

Поскольку трейс происходит в 16 юнитах от игрока в направлении его скорости, то тут же возникает идея при разбеге удерживать вектор скорости как можно более параллельным краю блока. Такая техника выполнения hj на блоках известна давно, но на практике выполнить её очень сложно. Классическим примером служит 245 блок в исполнении Risible Ripple (скачать демку можно здесь), который в своё время сумел за счёт необычного престрейфа перелететь блок с дистанцией на несколько юнитов меньше, чем тогда считалось минимально возможным для данного блока. Эта была не первая подобная демка, но поскольку она была претендентом на мировой рекорд, то вызвала широкий резонанс в kz сообществе и даже была объявлена нелегальной. Позже её всё же приняли, а представления о физике игры пересмотрели. Напоследок предлагаю посмотреть анимацию, построенную по данным из той самой демки. Cиняя линия условно обозначает край блока, красная - вектор скорости, белая - направление взгляда, зелёная - вектор wishdir из статьи про физику lj. Престрейф на земле обозначен оранжевым, стрейфы в воздухе - жёлтым, воспроизведение замедлено в 20 раз:

GIF 6.07MB

Заметьте, что первый стрейф занимает времени на несколько фреймов больше, так как игроку нужно успеть повернуться на больший угол. Для сравнения вот прыжок max3semne на том же 245 блоке (скачать демку можно здесь), но уже c обычной техникой:

GIF 6.18MB

Есть также и другая хитрость, которую часто используют при прохождении сложных карт. Если hj блок соприкасается со стеной, то при разбеге достаточно удерживать вектор скорости как можно дольше направленным в сторону стены. В это время конец нашего вектора длиной 16 юнитов будет либо над блоком, либо внутри стены (если она не слишком тонкая). В любом случае трейс что-то пересечёт, и дополнительного замедления не возникнет. Конечно, форма блока или другие обстоятельства могут помешать воспользовать этим приёмом, но бывает также, что это вообще единственный способ пройти карту.

В следующий раз речь пойдёт про bhop и специальный параметр fuser2, введённый разработчиками в CS 1.6.