Найти тему
Сделай игру

Боевые роботы. Часть 3. Умные враги

Оглавление

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

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

А вот и ИИ подъехал ИИ же и сгенерированный
А вот и ИИ подъехал ИИ же и сгенерированный

С чем имеем дело

Вообще, у злодея есть несколько настраиваемых параметров:

  1. Как далеко он видит: чем дальше видит, тем раньше начинает действовать;
  2. Оружие, которое он может применять - чем дальнобойней орудие, тем раньше подстрелит супостата (героя нашего то есть);
  3. Правила наступления;
  4. Правила отступления.

Собственно, ничего сложного.

Но как это всё делать?

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

И вот тут мы приходим к первому правилу:

Любая команда, отдаваемая ИИ, должна иметь вид рекомендации

То есть вместо evelRobot.attack() надо отдавать команду с параметрами, которые должны быть выполнены, но, если что, могут быть и не выполнены, а проигнорированы. Всякое бывает, вдруг на момент получения команды злодей сам себя уничтожит? А стрелять будет...

Какие есть команды

Тут, я, надо сказать, задумался. Вообще, чем меньше команд - тем лучше. Поэтому я решил, что команды нужно ровно три:

  1. Атаковать (выбранным оружием, в выбранное место) - основное действие злодея;
  2. Двигаться (неважно в каком направлении, но, пока что, не более чем на 1 клетку) - способ наступления (а после, возможно, и отступления);
  3. Защищаться и ждать - если не видишь противника и не знаешь где он - то просто жди, не отвлекай; пока ждёшь - защита увеличивается.

Собственно, все механизмы управления рекомендациями, пока что, выглядят так:

Система реакций. Пока не густо.
Система реакций. Пока не густо.

Но возникла небольшая проблема

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

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

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

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

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

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

И таких вот небольших, но неприятных затыков было великое множество. Что сильно тормозило процесс разработки.

И что в итоге получилось

Первая версия
Первая версия

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

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

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

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

А вот чего не хватает, так:

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

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