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

Самонаводящаяся ракета в компьютерных играх: пишем свой алгоритм

Оглавление

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

Самонаведёмся же!
Самонаведёмся же!

Два или три измерения?

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

Входные условия

Давайте исходить из того, что любая самонаводящаяся ракета имеет несколько параметров:

  • Крейсерская скорость движения (на ней ракета следует к цели);
  • Форсаж (на нём ракета пролетает конечный участок пути, но управление ухудшается);
  • Запас топлива (или время жизни) - сокращается с самого начала полёта, при форсаже сильнее;
  • Чувствительность управления (устанавливает предельно возможные радиусы поворота ракеты).

Также присутствует алгоритм "головка самонаведения", который управляет ракетой и отслеживает количество топливо (время жизни), принимает решение о манёврах.

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

Простое решение

Самое простое решение - это постоянное сопоставление координат ракеты и координат цели. Ракета, само собой, должна быть направлена в какую-то сторону, но всё выстраивается вокруг координатной сетки {x,y}. Выглядит всё это примерно так

Преследование до бесконечности
Преследование до бесконечности

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

Код без отрисовки
Код без отрисовки

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

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

Продвинутое решение

Теперь представим, что у нас нет никаких координат, есть только условно-бесконечное пространство, положение ракеты относительно вертикали (в какую сторону она летит) и положение цели относительно головки самонаведения. И расстояние от ракеты до цели (пеленг и дистанция). Итак, новое решение включает в себя:

  • более никаких координат - всё относительно ракеты;
  • более плавные (похожие на настоящие) виражи поворотов;
  • форсаж на конечной прямой;
  • более реалистичное ограничение топлива.

Общие сведения

В прежнем примере ракета могла поворачивать практически на 90 градусов, что не является правильным поведением; реалистичная ракета имеет некоторый предельный угол поворота, который, при этом, зависит от скорости полёта (чем выше скорость, тем меньше предельный угол поворота).

Скорость, так же, неоднородна: присутствует разгон, когда скорость постепенно увеличивается. Этот эффект присутствует как при запуске ракеты, так и на финальном этапе полёта, когда она летит в цель.

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

Калибровка

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

Основной код
Основной код

Тут всё просто - ракета постоянно вращается и отображается угол поворота.

Угол поворота соответствует
Угол поворота соответствует

У данной процедуры есть вполне важное прикладное значение, даже несколько.

Во-первых, "нулевой угол" поворота отсчитывается не от верхней, а от правой оси (то есть там, где нам привычные 90 градусов - там ноль), что даёт смещение.

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

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

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

Наверняка, это можно сделать проще
Наверняка, это можно сделать проще
Угол до цели
Угол до цели

Возможно фраза "угол до цели" не совсем верна, но пока буду использовать её.

Полусфера/полукруг

При наведении ракеты, впрочем, угол в 360 градусов будет излишним, т.к. ракета действует в ограниченных рамках, то есть +/- 180 градусов: это что-то вроде маркера, куда нам поворачивать, налево или направо.

Движение ракеты и угол на цель
Движение ракеты и угол на цель

Можно видеть, что углы теперь работают вполне правильно, а, значит, можно попробовать и начать разрабатывать модуль самонаведения.

Алгоритм наведения

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

Цель головки сводится к обеспечению алгоритма:

  1. Вывести ракету на курс таким образом, чтобы цель была прямо перед ней;
  2. Сблизиться на определённую дистанцию;
  3. Убедиться, что угол до цели меньше константы;
  4. Включить форсаж, чем снизить манёвренность, и достичь цели;
  5. В случае промаха - повторить манёвр.

В уравнении есть константы: дистанция перехода на форсаж и угол на цель, на котором на форсаж можно перейти (чтобы не промахнуться). Подберу их опытным путём.

Маневрирование ракеты - это просто движение вперёд с небольшой корректировкой угла направления. Хотя координаты не используются для расчётов положений (только угол и дистанция), однако, они используются для отображения данных на экране. Поэтому положение, всё же, будет считаться в координатах {x,y}.

Перемещение ракеты
Перемещение ракеты

Данный алгоритм работает вполне неплохо, но не идеально.

Наведение и атака
Наведение и атака

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

Заключение

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

  • Вычисление углов: надо много и часто считать, это может негативно сказаться на всём прочем;
  • Обязательно надо учитывать разные системы записи и применения координат в программе;
  • Ракеты могут улететь за экран навсегда (но это не баг, это фича) - или же надо хорошо проработать вопрос самонаведения;
  • У ракеты есть "время жизни" или запас топлива - если это не учитывать, ракета будет летать вечно и может достать тогда, когда этого никто не ждёт.

В целом, как не трудно заметить, кодовая база весьма скромна, а результат вполне себе приемлемый. А если вложить побольше времени - можно сделать ракеты более эффективными.

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