Статьи

Улучшение движения в 2D HTML5 играх

Недавно я выпустил Empty Black , мой 2D-шутер / головоломку / платформер. В этой статье я опишу, как я сделал движение игрока ловким и интуитивным. Сыграйте в игру, прежде чем читать, так что вы поймете, о чем я говорю.

Мой общий подход состоял в том, чтобы что-то изменить, а затем попробовать. Я взял идеи для корректировок из нескольких источников.

Один. Я изучил параметры, влияющие на движение персонажей игрока в других 2D-платформерах. Пол скользкий? Каково отношение бокового движения к высоте прыжка? Персонаж ускоряется при движении? Влияет ли высота прыжка персонажа на то, сколько времени игрок удерживает кнопку прыжка? Замедляется ли персонаж, когда сталкивается с подвижным объектом?

Два. Я исследовал необычное поведение персонажей игроков в других 2D-платформерах. Super Meat Boy заставляет персонажа автоматически выпрыгивать из стены при прыжке со стены. Спелунки позволяет персонажу подтягиваться вверх над выступами. В Castlevania персонаж может сделать дополнительный прыжок, находясь в воздухе.

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

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

К алгоритму.

Краткая версия: куча хаков.

Длинная версия:

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

Empty Black использует Box2D для управления физикой игрового мира. Любые движения подчиняются моделям сил трения и гравитации Box2D. Кроме того, Box2D обрабатывает реакции объектов, которые сталкиваются: отскоки, толчки, вращения и скольжения. Игра может опросить Box2D и спросить, к каким объектам относится конкретный объект. Если персонаж в настоящее время касается чего-то твердого, персонаж может прыгнуть.

За исключением того, что это не так просто. Помимо прыжка с земли, персонаж может прыгать со стены. Это означает приземляться и цепляться за стену, а затем снова прыгать от стены.

jump away from the wall

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

jump up the wall

Эта способность ограничена. Игрок может выпрыгнуть персонажа из стены и посадить его на той же стене. На данный момент, он не может прыгать снова. Если игрок попытается заставить его прыгнуть, персонаж упадет. Эта граница предназначена для улучшения игрового процесса. Проще спроектировать веселые уровни, если я могу положиться на непостижимую природу одинокой стены.

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

К счастью, у Box2D есть метафизический объект, который дополняет телесные стены, врагов и пули: датчик. Это духовное существо не имеет физического присутствия. Он имеет местоположение в мире и регистрирует столкновения. Программист может опросить его о таких столкновениях, как с физическими объектами.

Что я сделал, так это прикрепил широкий короткий датчик к нижней части персонажа. Это выглядело бы так, если бы вы могли видеть это:

sensor on bottom

Обратите внимание, как датчик перекрывает землю.

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

Как это поможет? Это не так. Но я могу прикрепить к персонажу еще два датчика, по одному на каждой из его сторон.

sensors on sides

Это означает, что игра может спрашивать каждый датчик, касается ли он чего-либо. Если нижний датчик касается какого-либо твердого основания, прыжки всегда разрешены. Если только боковой датчик касается твердой основы, игра должна быть продолжена.

Прыжки будут разрешены во всех случаях, кроме двух.

Один. Персонаж приземляется у стены, с которой он только что прыгнул.

jump to same wall

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

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

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

sliding up the wall

Чтобы остановить это, игра позволяет прыгать, только если игрок не вдавливает персонажа в стену.

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

over the wall

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

Если игрок отпустит кнопку прыжка до того, как персонаж достигнет своего пика в прыжке, персонаж немедленно начнет падать. Я украл эту идею у Super Meat Boy. Эффект — стеклянный потолок, вставляемый над головой персонажа. Это позволяет игроку контролировать высоту прыжка. Это останавливает Рики, болит голова.

Величина силы скачка обычно постоянна. Тем не менее, он увеличивается в двух ситуациях.

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

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

Сейчас: боковое движение.

Игрок нажимает левую клавишу со стрелкой. Что происходит?

Левая сила постоянно применяется, пока игрок не отпустит ключ. Величина силы зависит от того, насколько быстро персонаж движется в данный момент. Если это на максимальной скорости, сила не применяется. Если он неподвижен, применяется большая сила. Идея состоит в том, чтобы максимально быстро разогнать персонажа, а затем удерживать его на этой скорости. Это делает движение более предсказуемым. Это также решает вторую проблему Рики. Персонаж сразу же набирает максимальную скорость после прыжка.

Игрок отпускает клавишу, которая перемещает персонажа влево. Что происходит?

Персонаж сразу останавливается. Здесь нет скользкости. Таким образом, персонаж легче контролировать.

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

Два примера.

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

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

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

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

Вот краткое изложение для вас.

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

Эта статья первоначально появилась на BuildNewGames.com , совместная работа команд в Bocoup и Internet Explorer.