Разработка первой игры под Android с применением Adobe AIR и Stage3D
Введение
Давно хотел сделать хоть какую-нибудь игрушку для мобильника. Разработка игр – это одно из моих хобби. Времени я уделяю для этого крайне мало, но делаю это с удовольствием.
Раньше разрабатывал небольшие игрушки на PC (так, друзьям и коллегам поиграть), браузерные игры и игры для социальных сетей. Ничего особо выдающегося в этом направлении я не сделал, но неплохо провел время.
Ах да, еще работал в парочке фирм-разработчиков и издателях компьютерных игр программистом, но быстро понял, что увлечение – это одно дело, а работа в крупной фирме в области геймдева – совсем другое.
Никогда не делал игр для мобильных устройств и вот решил изучить вопрос, попробовать и разработку, и публикацию, и вообще узнать как там все.
Выбор технологии
Два раза устанавливал Unity, сделал тестовый проект и не знаю – что-то не лежит душа к этой технологии, все мне неудобно и навыворот сделано.
Пробовал sdl2 и cocos2d – намного больше понравились эти технологии, но обязательно натыкался на ограничения возможностей движка в некоторых аспектах, без которых можно было и обойтись, но очень хотелось больше пространства для маневров.
Пробовал haxe – очень интересная штука, но собирать приложение долго, часто глючит сборка через Android SDK/NDK (у меня несколько сред разработки по работе со своими хранилищами Android SDK/NDK, возможно они конфликтуют с haxe), да и производительность не сильно лучше Starling для AIR.
Ковырялся я долго в разных движках и в какой-то момент решил просто выпустить ради самого процесса игрушку. Поэтому я обратился к старому другу – AS3 с технологией AIR. Как-то делал небольшие радиоуправляемые игрушки и вместо пульта использовал телефон, на котором были разработаны простенькие интерфейсы джойстика управления по WI-FI. Как раз для этого я использовал AIR, ведь раньше я делал игрушки на Flash, и создание приложения для мобильника на AIR оказалось крайне быстрым и простым.
Stage3D
Векторная анимация никогда не отличалась хорошей производительностью, но небольшое количество анимаций работает отлично. Серьёзной игрушки на этом не сделаешь, да и давно хотел освоить работу с видеокартой через Stage3D. Пробовал еще bitmap blitting как ведет себя на мобильнике – очень не плохо, но так-как это все для личного удовольствия, я решил освоить таки Stage3D.
Сначала я взялся за Starling и Genome2D. Starling оказался очень удобным, но не оправдал моих ожиданий в производительности, если использовать анимации с различными фильтрами отображения, то лучше использовать обычный DisplayList и MovieClip. С Genome2D трудно работать и искать информацию, да и не на много производительнее. Посмотрев исходники, мне стало понятно, что эти движки – очень жесткая реализация возможностей Stage3D. Решил посмотреть на сам Stage3D.
Воодушевил меня на это bunnymark, разработанный на основе примера от Adobe – GPUSprite. Столько спрайтов скачет на экране, мне стало сразу интересно как.
Посмотрел этот небольшой движок (GPUSprite). В принципе почти все для счастья есть (камера, спрайты, вращение, перемещение, масштабирование, прозрачность), плюс все возможности, какие сам допишешь. Не хватало для маломальского движка в примере анимаций, нескольких фильтров отображения, ну и управления всеми возможностями.
Казалось бы, мало, но сделать это не так просто. Есть некоторые проблемы, исходящие из принципа работы с видеокартой. Можно для каждого спрайта выделять свой объект видеокарты, но это работает не так уж быстро, за то можно спокойно накладывать любые пиксельные шейдеры на конкретный спрайт и линейно наращивать количество спрайтов. Побольше спрайтов можно вывести если в одном объекте видеокарты хранить несколько спрайтов, если будем представлять спрайты в виде прямоугольников, то нам понадобится 4 вершины на спрайт. Но есть ограничение в количестве вершин объекта видеокарты, ну и можно привязать ограниченное число текстур (спрайтшитов). Для тех настроек, что применял я для большего охвата устройств получается 16384 спрайтов на объект и ограничился одной текстурой.
Также необходима сортировка по глубине отображения спрайтов. Из этого всего возникает такая картина:
• Перебираем спрайты в очередности прорисовки;
• Для первого спрайта создаем объект видеокарты и привязываем связанный спрайтшит в виде текстуры;
• Смотрим на следующий спрайт: если он из другого спрайтшита, заполнен лимит в 16384 спрайтов в объекте или требует другого пиксельного шейдера для эффектов отображения, то создаем новый объект видеокарты.
Управлять всем этим делом не просто, да и требует времени на обработку. Но можно делать и по-другому – не превращать спрайтшит как есть в текстуру, а создавать текстуру по мере отрисовки необходимыми спрайтами, и здесь свои минусы.
Способов я перебрал много разных, и в каждом были свои плюсы и минусы. В конце концов я убрал почти всю автоматическую обработку ради ручного управления. Сложно в применении, но КПД хороший. Иначе все что-то вроде Starling получается по производительности.
Сделал поддержку покадровой анимации и программной (костной анимации) и небольшие программы для преобразования MovieClip’ов из Adobe Animate в спрайтшиты и файлы описаний программной и покадровой анимации.
Потом хотел для элементов GUI использовать обычный stage, но это тормозило, отвлекся на разработку GPUGUI движка простенького и конвертором в растровые шрифты. С текстом вообще сложно тоже. Для простых редко меняющихся фраз сделал авто формирование спрайта путем отрисовки TextField в BitmapData.
Выводы
Развлекся, конечно, как мог. Десятки велосипедов наделал, но было увлекательно, и это все-таки хобби. Еще было несколько проблем с особенностью поведения Stage3D на Android. Например, при горизонтальной ориентации экрана, если во время игры кто-то позвонит, то после возвращения в игру остается белый экран, ну или такой цвет, какой вы выбрали в настройках фона по умолчанию. Притом можно тыкать на невидимые кнопки, слушать звуки и обычный stage работает, и весь код приложения функционирует, просто ничего не отображается. Об этой проблеме есть статьи в интернете.
Публикация в Google Play тоже веселое занятие, вроде все по-русски написано, но ничего так просто не понять и полезно почитать пояснения на сторонних сайтах опытных людей. Интерфейс китайцы им, наверно, сочиняют.
Для испытания всего этого я разработал простенькую аркаду «Древние Руны» и опубликовал ее на Google Play.
Пока займусь другими увлечениями, а потом интересно разработать небольшую онлайн игрушку для мобильных.
Вот, если интересно, пример apk бенчмарка от старлинга (я поменял только статичные картинки на анимации, возможно, там что-то можно ускорить) и пример движка на основе GPUSprite от Adobe с анимацией
→ starling
→ GPUSprite