В данной публикации я расскажу о моём опыте разработки 2D игры под Android, которая затянулась на 2 года и набрала 15 загрузок в Google Play. Также поделюсь некоторыми мыслями по поводу разработки.
Предыстория
В один прекрасный день, когда на моей машине весело работал Debian Linux, а я бороздил просторы каталога конфигурационных файлов, попутно уничтожая свои нервные клетки, и ко мне пришла идея отдохнуть. Как и положено плохим парням с плохим зрением, я решил отдохнуть играя в какую-нибудь игру. Едва увидев скриншот игры Funny Boat, я понял, что мне срочно необходимо сделать её клон на Android.
Разработка
Практически сразу же началась разработка игры. В качестве игрового движка я выбрал ещё модный по тем временам AndEngine (язык java), так как имел некоторый опыт работы с ним. Проект получил техническое название "Light Rabbit". Спустя неделю у меня был простейший прототип. Я самостоятельно рисовал графику и писал код, в связи с чем первые результаты пугали. Также у меня были проблемы с отображением воды и волн, но это решилось за день-два.
Архитектура игры строится на использовании «сцен» (класс Scene) и древовидной структуре из них. Это наиболее удобное средство разграничения кода в AndEngine. Сцена по своей сути является одной из вершин дерева, у неё есть родитель и множество потомков, есть метод в который можно добавить рисование объектов и обработку событий. Как показала практика, удобно иметь корневую сцену, к которой подключены все основные сцены приложения. Корневая сцена является своеобразным менеджером и позволяет легко переключаться между сценами учитывая зависимости и особенности отдельных сцен. Именно от корневой сцены все события (например, нажатие на экран) рассылаются в нижестоящие «подключенные» сцены.
Собственно, на этом мне и стоило остановиться, привести всё в порядок, добавить меню, получение монет и рейтинг. Но я не остановился.
Добавил смену дня и ночи (и погоды тоже!).
Добавил систему юнитов с примитивным АИ, прочностью и прочими характеристиками. И вертолёт (а почему бы и нет?). Режим «дружеского огня» для юнита также регулировался с помощью параметра мировосприятия (Нейтралы, Пираты, Имперцы, Союзники, Враги для всех и так далее).
Добавил систему диалогов. (И да простит меня Олег Куваев за отладочные иконки)
Последние пункты заставили меня затянуть ленивую разработку еще на год (!). Пришлось серьезно изменить архитектуру игры, создать свой язык команд и сценариев на базе XML формата. Я даже успел выпустить другую игру за этот период.
<!DOCTYPE LRLevel>
<Level>
<Setting>
<Chapter>Глава вторая</Chapter>
<Name>Повседневность</Name>
<Zone>SEA</Zone>
<Weather>FAIR</Weather>
<DialogBase>DialogBases/level_01.lrdb</DialogBase>
<Fog colorR="20" colorG="20" colorB="20" colorA="255"/>
</Setting>
<Events>
<Event command="SET_WATER_WAVE_HEIGHT" arg_int="30"/>
<Event command="SET_WATER_WAVE_REPEATING" arg_int="20"/>
<Event command="SET_TIME" arg_int="6"/>
<Event command="STOP_TIME_IN" arg_int="21"/>
<Event command="UNIT_ADD" id="0" arg_int="-600" arg_str="SteamShip" arg_str2="RIGHT"/>
<Event command="UNIT_SET_PROJECTILES_COUNT" id="0" arg_int="32"/>
<Event command="SET_DIE_POSITION" arg_int="-100"/>
<Event command="UNIT_SET_POSITION" id="0" arg_int="200"/>
<Event command="SET_FOG_VISIBLE" arg_int="0"/>
<Event command="WAIT_SECONDS" arg_int="2"/>
<Event command="SHOW_REPLIC" id="1" arg_int="2"/>
...
Конечно, для написания сценариев в таком виде нужен был редактор, которого вовсе не было. Попытки были, но объемы работы разрастались настолько, что я начал планировать релиз еще года через 2.
Команды считываются из файла сценария и далее выполняются последовательно. Очень хотелось добавить условный оператор, но обошлось и без него.
Агенты
Простых последовательностей команд оказалось не достаточно, и тогда, я придумал такую штуку как «агенты». Агент создается командой, закрепляется за юнитом и следит за исполнением какого-либо условия, при этом не задерживая основной поток исполнения команд. После выполнения условия, агент производит действие и самоуничтожается.
Приведу примеры агентов:
- Убийство юнита при достижении им определенной позиции
- Изменение поведения юнита (прекращение движения в определенной точке, например)
Публикация
Через значительный промежуток времени у меня получился малосвязный сценарий, который раскинулся аж на 11 разнообразных уровней включая обучалку. Я решил, что пора завязывать с разработкой и заняться публикацией.
По наставлениям местных обитателей я сделал публикацию на сайтах slide.me и 4pda, и естественно, на google play маркете. Учитывая свою аналитику и отображаемое количество скачиваний на slide.me (порядка 400 загрузок) я делаю вывод либо о накрутке, либо о невозможности поступления данных с телефонов пользователей. По моим данным со slide.me пришло менее 5 установок.
Камень в огород 4pda
После публикации в тематическую ветку форума 4pda, моя тема провисела дня 2 на первых страницах, после чего просто исчезла без каких-либо причин. Однако это принесло около 10 установок.
Аналитика и встроенная реклама
В качестве первого опыта в игру была встроена аналитика и даже скромный баннер с рекламой. Для разработчика игр на движке AndEngine встраивание рекламы является не совсем тривиальной задачей в отличие, например, от пользователей Unity.
Отдельно хочется сказать, насколько я был поражен возможностями средств отслеживания действия и аналитики. При наличии интернета можно было узнать о нажатии на любую кнопку в игре, о том, сколько уровней кто прошел, а кто бросил (друзья жаловались на хардкорность).
Еще раз подчеркну, аналитика — это очень полезно даже для мелких приложений.
Бешенные деньги
Заработать с рекламного блока мне удалось почти 30 центов. Даже графики приводить не буду.
По воводу AndEngine
AndEngine — отличный игровой 2D движок, который дает большую свободу действий. Его можно легко расширять своим кодом, ведь он является открытым. Есть куча примеров, можно подключить физику Box2D или использовать шейдеры для графики. Имеется довольно большое сообщество, использующих его людей. Однако чувствуется, что он начал устаревать (deprecated не редкость), разработка остановлена (1.5 коммита в год не считается), и участь его в ближайшие годы — движок для ознакомления и небольших игр. Рекомендую не задерживаться и пересесть хотя бы на LibGDX, а может быть и на что-то более высокоуровневое.
Исходный код и большинство ресурсов
Это мой первый законченный проект такого масштаба. Обновляться он уже не будет. Не ищите там хорошего кода, однако некоторые моменты реализации (например класс воды для AndEngine) могут оказаться полезными. В README файле присутствует ссылка на Google Play для желающих пощупать.
Ссылка на репозиторий c кодом (Bitbucket).
Заключение
Если вы хотите, чтобы в ваши игры играло много народа, делайте их простыми, анализируйте тренды, не бросайтесь в разработку без четкого плана, наймите уже наконец художника.
Если вы делаете игру для себя — делайте что хотите.
Автор: Mhyhr