В данной публикации я расскажу о моём опыте разработки 2D игры под Android, которая затянулась на 2 года и набрала 15 загрузок в Google Play. Также поделюсь некоторыми мыслями по поводу разработки.



Предыстория


В один прекрасный день, когда на моей машине весело работал Debian Linux, а я бороздил просторы каталога конфигурационных файлов, попутно уничтожая свои нервные клетки, и ко мне пришла идея отдохнуть. Как и положено плохим парням с плохим зрением, я решил отдохнуть играя в какую-нибудь игру. Едва увидев скриншот игры Funny Boat, я понял, что мне срочно необходимо сделать её клон на Android.

Скриншот игры Funny Boat
image

Разработка


Практически сразу же началась разработка игры. В качестве игрового движка я выбрал ещё модный по тем временам AndEngine (язык java), так как имел некоторый опыт работы с ним. Проект получил техническое название "Light Rabbit". Спустя неделю у меня был простейший прототип. Я самостоятельно рисовал графику и писал код, в связи с чем первые результаты пугали. Также у меня были проблемы с отображением воды и волн, но это решилось за день-два.

Прототип 01


Архитектура игры строится на использовании «сцен» (класс 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).

Заключение


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

Если вы делаете игру для себя — делайте что хотите.

Комментарии (8)


  1. fogone
    14.03.2016 11:57
    +6

    Я бы предложил, фразу "делайте что хотите" в качестве заголовка использовать.


  1. BIanF
    14.03.2016 14:04
    +4

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


  1. Mugik
    14.03.2016 14:36
    +1

    Такое ощущение, что статья готовилась к 1 апреля, но случайно опубликовалась раньше строка.

    Давно так не смеялся)

    Особенно пол конец «делайте что хотите».


  1. Gamegen
    14.03.2016 16:10

    Для разработчика игр на движке AndEngine встраивание рекламы является не совсем тривиальной задачей

    Не припомню, чтобы это действительно вызвало какие-то особые проблемы. Если мне память не изменяет, то я просто в в главном layout'е сделал два слоя: в первом (нижнем) была вьюшка со сценой AndEngine, а во втором (верхнем) — вьюшка с баннером. Я просто передвигал, включал или выключал вьюшку банера в нужный момент. Проблемой стал переворот отображения баннера на 90 градусов и назад без изменения ориентации экрана.


  1. OlegKozlov
    15.03.2016 10:02

    Эпилог делает всю статью, спасибо! :)


  1. peterkam
    15.03.2016 10:53

    Отличный жизнеутверждающий вывод!


  1. Vankir
    18.03.2016 14:02

    Спасибо за классную статью! Планируете какую-нибудь новую игру или что-то ещё?


    1. Mhyhr
      19.03.2016 23:43

      На здоровье! Конечно планирую, но пока без конкретики. :)