Найти в Дзене
Сделай игру

Обработчик столкновений. День третий.

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

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

Однако теперь, когда мы решили заложить возможность отскока, вся прежняя модель перестала работать: потребовался плавный пересчёт вектора движения. Работать всё должно так: сперва объект разгоняется до предельной скорости падения, потом ударяется о злодея и отскакивает в противоположном направлении с некоторой начальной скоростью (желательно, равной той, с которой двигался герой), потом, под действием гравитации, отлёт замедляется, достигает нуля и начинает герой падать опять вниз.

Траектория движения после отскока
Траектория движения после отскока

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

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

Я сделал несколько экспериментальных подходов. Главная трудность такого решения - её чрезвычайная трудоёмкость. То есть вектора направлений оказываются по своей внутренней логике сложней, чем всё остальное. Это неприемлемо. Нужно какое-то крайне простое решение.

И я его, конечно, не нашёл. Получилось что-то типа такого:

Класс, описывающий действие силы
Класс, описывающий действие силы

Если коротко, то есть что-то типа силы. Но эта сила имеет несколько характеристик. Во-первых, это сила смещения, всегда имеющая некие dx,dy - описывающие, на какое количество пикселей по обеим осям надо сместиться. Можно установить рассчётные функци завершения действия силы (например, при достижении ими какого-то значения или по истечении времени воздействия) и функция изменения значения - некий коэффициент k, который будет изменяться от 0 до 1 и возможное смещение будет происходить с поправкой на него (иными словами, функция от времени).

Например, сила гравитации будет выглядеть у меня так:

this.gravity - функция расчёта влияния гравитации
this.gravity - функция расчёта влияния гравитации

Собственно, всё это делалось с одной единственной целью - предоставить возможность добавлять дополнительные вектора, влияющие на движение героя. И я к этом сейчас чрезвычайно близок.

Сейчас я изменю управление: теперь корректировка лево-право будет производиться через "одноразовое" усилие.

Тут я исследовал вопрос
Тут я исследовал вопрос

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

При встрече со злодеем, герой рекошетит и меняет траекторию (временно) в противоположную сторону. Выглядит, возможно, не идеально, но вполне внушительно. Чтобы подавлять гравитацию, начальный импульс вдвое больше силы гравитации, а продолжительность отскока не более 1 секунды. Код силы отскока выглядит так:

Отражение героя от злодея
Отражение героя от злодея

Самое интересное в строчке force, там вся логика работы отскока зашита.

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

this._vector - суммированное смещение героя
this._vector - суммированное смещение героя

Ну и теперь, посмотрим, как всё это работает.

Вот такая вот альфа версия отражения
Вот такая вот альфа версия отражения

Ну на этом можно данный этап заканчивать. Далее, пожалуй, надо поработать ещё над несколькими вещами:

  • Заставить злодеев двигаться;
  • Сделать отражение более привлекательным и зависящим от угла падения (слишком резко в бок улетает что-то);
  • Лучше проработать механизм штрафов и блоков (сейчас герой в определённых условиях теряет скорость, но я бы уточнил условия этого);
  • Добавить новый тип блоков - односторонний (с одной стороны его пролететь можно, а с другой - нельзя);
  • Сделать анализатор: хочется понимать, с какой стороны бот столкнулся с блоком или объектом - для более качественной отработки реакции;
  • Столкновение с блоком снизу или сверху с большой скоростью пусть вызывает сотрясение экрана (так эффектней);
  • Добавить что-то типа снарядов: маленькие объекты (меньше чем шаг карты: с ними надо будет поработать на предмет взаимодействия - я про алгоритм взаимодействия с ними ещё не рассказывал).

Как видите, планов ещё много. Не переключайтесь, мы вернёмся после рекламной паузы.