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

Боевые роботы. Часть первая

Началось всё с того, что я захотел написать игру в изометрической проекции и, вдохновившись Nether Earth со спектрума, решил, что и моя игра должна быть обязательно в таком же изометрическом виде. Добавил мотивации и тот факт, что OpenGL/WebGL позволяет делать такие проекции и мне захотелось это попробовать. Примеры таких игр Вот, например, Nether Earth, о которой я уже писал. Выглядит простенько по сегодняшним меркам, но на момент выхода - это было нечто замечательнейшее (1987 год). Следующим номинантом на приз за лучшую изометрию стал, разумеется, Red Alert. Там изометрическая проекция сделала своё дело, плюс, добавилась ещё возможность разделения карты ещё и по высоте: появились ямы и эстакады, расположенных на разных уровнях. Но на этом, конечно, никто останавливаться не собирался. В более поздних версиях того же Red Alert'а, равно как и во многих других играх, количество уровней стало больше, а позже, появилась ещё и 3d исполнение, позволяющее играть всё в ту же игру, но уже не бу
Оглавление

Началось всё с того, что я захотел написать игру в изометрической проекции и, вдохновившись Nether Earth со спектрума, решил, что и моя игра должна быть обязательно в таком же изометрическом виде. Добавил мотивации и тот факт, что OpenGL/WebGL позволяет делать такие проекции и мне захотелось это попробовать.

А вот мои будущие герои... и злодеи
А вот мои будущие герои... и злодеи

Примеры таких игр

Вот, например, Nether Earth, о которой я уже писал. Выглядит простенько по сегодняшним меркам, но на момент выхода - это было нечто замечательнейшее (1987 год).

Nether Earth
Nether Earth

Следующим номинантом на приз за лучшую изометрию стал, разумеется, Red Alert. Там изометрическая проекция сделала своё дело, плюс, добавилась ещё возможность разделения карты ещё и по высоте: появились ямы и эстакады, расположенных на разных уровнях.

Red Alert: несколько уровней карты
Red Alert: несколько уровней карты

Но на этом, конечно, никто останавливаться не собирался. В более поздних версиях того же Red Alert'а, равно как и во многих других играх, количество уровней стало больше, а позже, появилась ещё и 3d исполнение, позволяющее играть всё в ту же игру, но уже не будучи привязанным к одному направлению вида: изометрическая проекция стала обозреваема со всех сторон.

Command & Conquer Red Alert 3: Uprising
Command & Conquer Red Alert 3: Uprising

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

Что же буду делать я

Задумка моя стала не столь грандиозной, как Red Alert. Всё же в одиночку запилить такой проект - дело непростое и весьма длительное. Даже после того, как будет готова схема игры - на графику и озвучивание уйдёт много времени.

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

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

Итогом должна стать небольшая игра. Ну, поехали!

Да будет карта

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

Немного манипуляций и получаем такую вот простую двухуровневую карту
Немного манипуляций и получаем такую вот простую двухуровневую карту

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

Первые манёвры

Для начала добавлю на карту условного героя (красный треугольник) и двух его противников (оранжевые треугольники).

Начальный вид
Начальный вид

Теперь, кликая по клеткам, герой будет передвигаться. Но есть три ограничения:

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

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

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

В качестве первого результата я поставил несколько целей:

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

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

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

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

Сложности, с которыми столкнулся

Тут всплыла старая как мир история, о которой можно написать целую книгу про архитектуру приложений.

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

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

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

Что тут с кодом вообще?
Что тут с кодом вообще?

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

Первый итог

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

Упрощённый вид
Упрощённый вид

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