Началось всё с того, что я захотел написать игру в изометрической проекции и, вдохновившись Nether Earth со спектрума, решил, что и моя игра должна быть обязательно в таком же изометрическом виде. Добавил мотивации и тот факт, что OpenGL/WebGL позволяет делать такие проекции и мне захотелось это попробовать.
Примеры таких игр
Вот, например, Nether Earth, о которой я уже писал. Выглядит простенько по сегодняшним меркам, но на момент выхода - это было нечто замечательнейшее (1987 год).
Следующим номинантом на приз за лучшую изометрию стал, разумеется, Red Alert. Там изометрическая проекция сделала своё дело, плюс, добавилась ещё возможность разделения карты ещё и по высоте: появились ямы и эстакады, расположенных на разных уровнях.
Но на этом, конечно, никто останавливаться не собирался. В более поздних версиях того же Red Alert'а, равно как и во многих других играх, количество уровней стало больше, а позже, появилась ещё и 3d исполнение, позволяющее играть всё в ту же игру, но уже не будучи привязанным к одному направлению вида: изометрическая проекция стала обозреваема со всех сторон.
И, разумеется, были другие игры, в которых на изометрических картах двигались изометрические персонажи, но стили игр, динамика или сюжетная канва были совершенно различными. Рассказывать о них можно очень долго, а потому не стану.
Что же буду делать я
Задумка моя стала не столь грандиозной, как Red Alert. Всё же в одиночку запилить такой проект - дело непростое и весьма длительное. Даже после того, как будет готова схема игры - на графику и озвучивание уйдёт много времени.
Я вижу это как пошаговую стратегию, где у игрока один или несколько персонажей и есть задание на условную миссию. Персонажи действуют последовательно, в соответствии с количеством доступных очков действий. Потом ход завершается и ходит противник.
Сперва это будет визуально упрощённая, плоская схема, без специальных анимаций и тому подобного, затем хочу перевести это в изометрическую проекцию и подключить WebGL, возможно и Rust, если для него найдётся место в этой игре (что не факт).
Итогом должна стать небольшая игра. Ну, поехали!
Да будет карта
Всё началось с генератора карты. Вообще, хорошо, когда есть специальный обработчик, позволяющий обслуживать игровую область, однако, при этом, не отвечающий за рисование; за рисование пусть отвечает специальный класс - так что пока я буду использовать заглушку, генерирующую цветные квадратики.
В идеале, в игре может быть несколько уровней карты (что не факт, но кто знает): один персонаж может быть наверху, скажем, на эстакаде, второй - внизу, под ним. Поэтому я заложил такую возможность, хотя изначально использовать её не буду: всё же с самого начала пытаться предусмотреть примерно всё - сомнительная инициатива. Кстати, градиентная заливка - это второй уровень карты. Надо же было его как-то обозначить.
Первые манёвры
Для начала добавлю на карту условного героя (красный треугольник) и двух его противников (оранжевые треугольники).
Теперь, кликая по клеткам, герой будет передвигаться. Но есть три ограничения:
- Максимальная длина одного перемещения - 1 клетка (диагональное движение не допускается);
- Перемещаться можно только по двум типам клеткам (светло-серым и чуть более тёмным);
- Перед выбором точки движения - зона, куда можно "пойти" - подсвечивается.
Конечно, это не изометрическая проекция, однако на данном этапе я лишь пытаюсь пройти путь "детских болячек" и обнаружить, с какими сложностями придётся встретиться, когда дело дойдёт до задуманного вида.
Тут, безусловно, есть большой простор для того, как можно сделать лучше. Пока не надо: если сразу стараться сделать превосходно, то при условии отсутствия детального плана и чёткого понимания, как всё должно выглядеть в конечном итоге (а я, знаете ли, имею лишь общее видение картинки, но некоторые моменты пока весьма расплывчаты) - то вместо результата будет постоянная борьба с перфекционизмом (формой прокрастинации).
В качестве первого результата я поставил несколько целей:
- Есть ходы, для игрока и для противника (пока у героя 1 персонаж, у противника - два);
- У всех персонажей есть очки активности: на передвижение и атаку они тратятся;
- Есть ограничения на передвижение, стрельбу и обзор (на карте не должно отображаться то, чего не видно, но стрелять наугад можно) и ещё много всяких ограничений, которые я буду придумывать по ходу дела;
- В игре есть несколько режимов действий, между которыми можно переключаться, но пока что левая кнопка мышки - это передвижение, правая - атака, колёсико мышки - переключение оружия (это первичное управление, которое наверняка будет переделано);
- Игра заканчивается, когда достигаются цели: изначально они заключаются в том, чтобы уничтожить противников.
Итак, в левом верхнем углу доступное оружие. В будущем оно будет, наверное, как-то лучше стилизовано и появятся дополнительные ограничения. Кстати, переключение оружия меняет подсвечиваемый радиус атаки. Также заметно, что не все персонажи сразу видны: второй оранжевый треугольник (противник) стал заметен лишь после того, как игрок подошёл поближе (пока враг не движется, т.к. не умеет).
Сама идея кнопки "следующий ход" - по сути заглушка. Ход должен перезагружаться автоматически, после того, как враги походят. Но для этого они должны научиться сперва ходить. Это и будет следующим шагом.
После - надо научить наших крошек стрелять и можно считать, что первый этап завершён.
Сложности, с которыми столкнулся
Тут всплыла старая как мир история, о которой можно написать целую книгу про архитектуру приложений.
Суть сводит к следующему: есть некоторая задача и у неё есть самый заметный фрагмент (в моём случае - это карта и анимация вокруг неё). Но, помимо этого, есть много других аспектов, которые в самом начале не выглядят значительными (порядок ходов, способ передачи управления, анимация и тому подобное).
Но, когда доходит до них (а уже, напомню, написана значительная часть кода), внезапно выясняется, что то, как всё реализовано - никуда не годится: код не может работать как надо и, чтобы это изменить - надо ставить костыли.
Короче, я станцевал на этих граблях. В какой-то момент, поддержка кода начала выглядеть так:
Короче, пришлось переписывать часть всего. И очень вовремя, так как когда дошло дело до первичных анимаций, стало ясно что дальше будет только сложней. Я даже об этом статью писал.
Первый итог
Ну вот и получилось нечто изначальное: герой теперь перемещается по карте, оружие стреляет, перезаряжается. Изначально я надеялся научить и противников ходить, атаковать и вообще взаимодействовать, но выяснилось, что даже для такого простого набора действий - надо написать несколько решений, которые я знаю лишь в теории (из теории графов).
Ну а пока что небольшая демонстрация. Дальше я добавлю немного разума противникам и сделаю бой, хочется надеяться, более впечатляющим.