Технические аспекты разработки моей первой Android-игры

На мой взгляд, для разработчика, наибольший интерес представляют не примеры кода и конкретная реализация определенных «фич», а именно проектные решения, которые принимались в процессе развития проекта, и тот опыт, что был при этом приобретен.

Именно о таких решениях и будет этот пост (примеров кода на просторах сети более чем достаточно).


Опытные разработчики, скорее всего, это все и так знают. А те, кто только собирается вставать на этот путь, сумеют оценить, с чем им придется столкнуться.


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


Внимание! Много текста :-).


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


Программная часть


Игра писалась на движке AndEngine, про который уже была серия статей на Хабре. Использовалась первая версия движка (GLES1), хотя на данный момент уже вышла вторая версия (GLES2). О причинах такого решения можно прочесть у меня в блоге (не сочтите за рекламу).

Графика


Графическая составляющая делалась полностью самостоятельно.
С самого начала я определился, что рисовать графику буду исключительно в векторе. Это спасает от множества проблем, начиная от неправильно выбранных пропорций объекта и заканчивая необходимостью перерисовки графики при изменении элементов, положенных в основу графического объекта.
Для рисования использовался векторный графический редактор Inkscape.
В принципе, AndEngne поддерживает загрузку графики из SVG, но только на базовом уровне.
Поначалу меня это устраивало, но с увеличением сложности графики (например, применение любого фильтра изображения), базовых возможностей движка стало не хватать, пришлось рендерить ее самостоятельно, средствами Inkscape (операция «Экспорт в растр»).

Звук


Со звуковым сопровождением было труднее всего.
Если программирование — это моя специальность, рисовать мы пробуем с детства и более-менее представляем, как это происходит, то с созданием звукового сопровождения мы не сталкиваемся в обычной жизни вообще, максимум — в аудио-редакторе «шаманим» над записью.
Как возможный выход — воспользоваться готовой музыкой / звуковыми эффектами с последующей их обработкой в звуковом редакторе.

Проблемы


Основная проблема, с которой сталкиваются разработчики под Android — поддержка всего «зоопарка» устройств.

Железо

В своем проекте я придерживался правила, что все должно быть написано на Java, никакого NDK, даже в движке. Отчасти, это объясняет мой отказ от использования GLES2. Эта мера позволила запускать игру не то, что на ARMv6 (от которого многие разработчики уже отказались), а даже на экзотическом MIPS без всяких эмуляторов.

Экран

Еще одной проблемой является «зоопарк» всевозможных экранов.
Здесь я бы хотел остановиться подробнее:
  1. Текстуры.
    Необходимо использовать текстуры, подходящие под данное разрешение экрана. Решается несколькими способами:
    • Использование SVG.
      Текстуры загружаются из формата SVG сразу необходимого размера. Весят такие текстуры относительно немного, но требуют больше процессорной обработки.
    • Рендеринг текстур с запасом (я остановился на данном варианте).
      Позволяет добиться приемлемого качества, но за счет более «тяжелых» текстур, чем могли бы понадобиться. Основной недостаток — большой объем занимаемой памяти (как оперативной — при работе приложения, так и физической — самим приложением).
    • Загрузка кеша с текстурами нужного размера после старта приложения.
      Это сложный сам по себе метод, требует держать свой сервер для загрузки кеша.
    • Ресайз текстур большого размера в кеш.
      Метод относительно прост в реализации, но потребляет двойной объем памяти (для оригиналов и отресайзенных текстур).
    Дополнительно для каждого создаваемого спрайта пришлось вручную задавать его экранные размеры (по умолчанию, они соответствуют размеру текстуры).
  2. Адаптация, собственно, движка под разрешение экрана.
    Во всех примерах по AndEngine разрешение экрана фиксировано, что вызывает «размытость» на бОльшем разрешении экрана и проблемы с отображением на устройствах с другим соотношением сторон. Решается путем определения параметров экрана и инициализацией движка полученными значениями (посмотреть можно здесь).
  3. Адаптация самого приложения под все размеры экрана.
    Для обеспечения правильного отображения на всех экранах я определил базовый размер спрайта, от которого всю графику и строил.
    Этот размер я определил как 1/10 от высоты экрана. Далее, отталкиваясь от краев экрана, расставлял необходимые спрайты.
    Но в некоторых сценах это не помогло, у меня было 2 таких случая:
    • Экран загрузки. На нем выводится надпись одним большим спрайтом. На «узких» экранах она вылазила за края. После расчета требуемого размера спрайта на основе базового размера, я проверял ширину спрайта. Если она оказывалась больше ширины экрана, то соответствующим образом масштабировал спрайт.
    • Экран окончания уровня. На нем выводится много информации, на «узких» экранах местами происходили ее наложения. Для данной сцены сделал пересчет базового размера на основе не только высоты, но и ширины экрана (как 1/15 ширины), использовал меньшее из полученных значений.

Также на некоторых устройствах заметил появление у спрайтов белых полос по бокам.
Изучение проблемы вывело на текстуры. При загрузке текстуры размещаются на нескольких «атласах», не наезжая друг на друга (см. картинку). Фон атласа — белый. Для сглаживания берутся соседние пиксели, в результате чего края текстуры могут приобретать белую полоску. Проблема решилась путем ручной инициализации атласа прозрачной png-шкой и смещением загружаемых текстур на 5 пикселей вниз и вправо (чтобы не сглаживался «мусор» из памяти, были прецеденты).

Человеческий фактор

Следующая проблема не относится к техническим. Это мотивация.
В одиночку разрабатывать игру сложно. И не в плане вопросов / трудностей, возникающих в процессе разработки (тут поможет гугл), а в плане мотивации. Самомотивации определенно не хватает. Очень трудно не забросить игру на полпути, когда уже энтузиазм сошел на нет, а конца-края и не видно.
Поэтому я советую разрабатывать игру совместно с товарищем. В этом случае возникает и некое соперничество (в умеренном количестве — это то, «что доктор прописал»). Да и разработка идет гораздо интенсивнее.

Тем не менее я разрабатывал все один. На определенном этапе, чтобы не затягивать релиз, я решил выпустить самую базовую версию, с минимумом дополнительных «плюшек». В результате моя разработка может быстро надоесть, в силу своей однообразности, но тем не менее я ее выпустил, завершив пусть и простую, но законченную игру. Под законченностью игры я понимаю: придание графике финального вида, доработка всех сцен, звуковое сопровождение, а главное — выполнение всех тех мелочей, которые делаются за секунды, а растягиваются на недели. Тут очень много вещей, о которых на этапе кодинга практически не задумываешься. А объем работ тем не менее остается очень большим.
Различные плюшки в игре потребовали бы много времени на сам кодинг и настройку баланса игры, в то время как на завершение игры сил бы и не осталось. Сейчас же я могу постепенно добавлять новые плюшки или начинать новый проект.

Конечно, тут могут быть сложности. Например, игра может так нахватать отрицательных отзывов, что и после всех доделок популярности не обретет. Как вариант решения — выпуск бета-версии, с явным указанием ее статуса (наймспейс не забываем ставить соответствующий).
Лично я выпустил все планируемые версии (Lite / Free / Standart / HD) сразу. Возможно, это было ошибкой. Сейчас я добавляю то, что было исключено ранее (+ некоторые новые идеи подсказали пользователи).

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

Производительность


Данную проблему можно разбить на две:
  1. Сложная графика.
  2. Сложный игровой ИИ (искусственный интеллект).

Сложная графика

Данные проблемы сложны в обнаружении, т.к. очень сильно зависят от аппарата.
Как правило, новые аппараты не требуют сильной оптимизации. Но всегда найдется аппарат, у которого возникают проблемы.
Общее правило такое: чем больше текстур отображается на экране и чем больше размер этих текстур, тем медленнее идет их отрисовка. Причем какой фактор сильнее скажется предугадать невозможно. Также производительность зависит и от настроек сглаживания текстур. Я решал данные проблемы следующим образом: ввел настройки графики (Low (дополнительно скрывается фон) / Normal / High), в основном менялись настройки сглаживания. Дополнительно выпустил Lite-версию с «урезанными» текстурами.
Не стоит забывать и об альфа-канале. Присутствие его в текстуре может значительно снизить FPS. Но опять же, это проявляется не на всех аппаратах.

Сложный игровой ИИ

Чем больше логики Вы реализовываете, тем дольше она отрабатывает (КО). Дополнительно вносит свои коррективы сборщик мусора.
Тут действуют стандартные правила оптимизации. Например, для минимизации сборки мусора можно использовать пулы объектов. В AndEngine есть специальный класс для этого, GenericPool (прочесть об использовании можно здесь).

Рабочее окружение


Я использовал IDE Eclipse + ADT Plugin. Периодически обновлял SDK.
Проблемы встречались, но оперативно устранялись (спасибо, Google и stackoverflow в частности).
Из того, что понравилось: с выходом Android SDK r17 появился образ Android 2.3.3 на базе Atom. При наличии виртуализации в процессоре (Intel под Windows и Intel / AMD под Linux) работает довольно шустро. Конечно, до реальных устройств далеко, но со всеми оптимизациями периодически выдавал до 20к/с в игре.
При этом отладка происходит существенно шустрее, чем на реальном устройстве (не говоря уже про стандартный эмулятор).

Хитрости реализации


Из того, что я отношу к хитростям, самым интересным было использование большинства объектов одного единого размера. Это позволило значительно упростить расчет физики попаданий в цель.
Также для расчета движения использовались элементы движка, что позволило сократить объем кода. Но на мой взгляд, это не является удачным решением. Ядро игры получается зависимым от самого движка, поэтому при смене движка, придется менять и ядро.

Запись рекордов


На данный момент рекорд запоминается локально. В планах прикрутить сервис Scoreloop.
Об интеграции его в приложение можно почитать здесь.

Падения игры


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

Показ рекламы


Рекламу решил показывать от Mobclix.
Как настроить показ под AndEngine можно почитать здесь.

Маленькая хитрость: Mobclix позволяет показывать пользовательские объявления (насколько знаю, эта функция есть практически у всех провайдеров рекламы).
На данный момент я добавил пару баннеров с рекламой платной версии приложения. В дальнейшем, с появлением новых проектов, собираюсь добавлять и их.

Регистрация в Google Play


Чтобы стать полноценным разработчиком в Google Play, надо зарегистрироваться на 3х сервисах (для России):
  • Google Play — для доступа в Play как разработчику. Для бесплатных приложений этого достаточно.
  • AdSense — если мы собираемся продавать приложения или монетизировать их с помощью AdMob.
  • Google Checkout — если мы собираемся создавать платные приложения.

В целом, регистрация прошла относительно гладко.
Мануалов много, но тем не менее и вопросов при регистрации возникает немало.
Основные из них — это «Как это заполнять» и «Что же делать дальше»?

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

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

Раскрутка приложения


По данному вопросу мне очень сложно что-либо сказать. Я только «набивал шишки», как такового успешного опыта пока нет.

На что можно обратить внимание — это на 4pda.ru или на xda-developers.com (Если кто-то может предложить что-нибудь еще, пожалуйста, отпишитесь).

Пока я работал только с 4pda.ru. На данном ресурсе можно выделить несколько возможностей:
  • Форум разработки, для сбора предварительных отзывов и тестирования.
  • Игровой форум, собственно, для обсуждения игры.
  • «Проект поддержки наших разработчиков». В рамках данного проекта разработчикам из СНГ (или, просто говоря, русскоговорящим) предоставляется возможность опубликовать обзор своего приложения на главной странице данного ресурса.

Еще следует иметь в виду, что Вашу игру могут просто не понять. Особенно актуально для популярных жанров, с широкой целевой аудиторией.
Даже если есть много положительных отзывов, что игра хорошая, тем не менее, она может быть не настолько хороша, чтобы они кричали об этом на каждом углу. А те, кому игра не понравилась, обязательно об этом напишут. К этому нужно относиться спокойно, это вполне естественный процесс.
Как способ бороться — просить оставить отзыв об игре, скажем, при выходе из нее (или лучше в главном меню, после 2-3го запуска).

Заключение


В заключение я бы хотел сказать, что ничего не получается у того, кто ничего не делает. Так что если есть идея, есть желание ее реализовать, то дерзайте! А всякие «нет времени», «не умею», «ни разу не делал» и т.д. — это просто отговорки (кто признается, что ему просто лень? Лучше в Диаблу новую пошпилить :-) ). Как говорится, Viam supervadet vadens (лат. «дорогу осилит идущий»). И не следует забывать, что, в любом случае, даже отрицательный опыт — это тоже опыт.

Удачи всем начинающим и продолжающим игро-создателям :-)!
Источник



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


Блог: http://romanlovetext.blogspot.com/