Pull to refresh

Разрабатываем iOS приложение на флэше

Self Promo
Sandbox
Наверное, многие слышали про проект Adobe Air — весьма здравая инициатива от компании Adobe сделать так, чтобы приложение на флэше могло компилиться и запускаться на любых платформах — десктоп, iOS, Android, телевизоры,…

Долгое время ничего толкового на air'е сделать было нельзя. Но в последнее время технология набирает обороты, Adobe внесла ряд оптимизаций в код air'a и теперь вполне можно написать на нем весьма шустрое приложение. В данной статье я расскажу о нашем опыте разработки air-приложения под iOS.

Как мы дошли до жизни такой?...


В данный момент основной проект (социальная игра) нашего маленького стартапа, фирмы из нескольких человек — после года разработки заморожен на финальной стадии на время поиска инвесторов. Так что чтобы не сидеть без дела пока идет поиск/переговоры — нам пришло в голову сделать что-то не очень трудозатратное, а если оно сможет что-то заработать — так вообще шикарно.

Т.к. ни с unity, ни тем более с xcode никто из нас не знаком, зато со флэшом мы на «ты» — то пришла в голову мысль опробовать хваленую технологию Air для создания более-менее презентабельной и динамичной игры.

На данный момент use case'ов эира под iOS — пересчитать по пальцам. Да, Машинариум — неплох. Но, все-таки, — это не показатель. Нам было интересно, как air справится именно с динамичной игрушкой.

Итак, решение было принято. Примерный сроки (1 месяц) — поставлены. И мы сели копаться в новой для нас технологии…

Основной платформой, на которую мы ориентировались — был iPhone 4.

Идея игры.


Здесь мы долго не думали. Задачей было найти что-то, что бы подходило под следующие критерии:
  • Простота => большая скорость разработки
  • Отсутствие большого количества анимации, графики и т.п. (чтобы во-первых — не нагружать художника работой на пол года, а во-вторых — не нагружать процессор телефона)
  • Желательно — незаезжанность темы
  • Отсутствие необходимости создавать 100 сложных уровней-головоломок (что так же — замедлило бы разработку)

Придумывать что-то свое нам не хотелось, да и не на то был расчет. Так что мы начали бороздить интернет в поисках объекта клонирования.

После пары дней поисков — мы остановились на игрушке "Axe in Face". Она удовлетворяла всем нашим требованиям. Суть ее заключалась в том, чтобы рисовать пальцем траекторию полета топора и бросаться им во врагов.



Начало разработки.


Итак, мы начали… Стоит отметить, что представления о технологии Air — у нас не было совсем.

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

Так что начали мы обычную разработку на флэше. Об этом писать не буду — это не тема статьи.

Расскажу лишь о проблемах и трудностях, с которыми мы столкнулись именно при запуске приложения на железе (iPhone, iPad).

Кстати, для тех, кто не понял, что такое Air — скажу в двух словах. Вы разрабатываете игру на флэше. Потом компилите ее под Air iOS и на выходе (в идеале) — получаете готовый .ipa файл для отправки в app store.

Для юзера, программа ничем не отличается от написанных на Objective C или Unity. Точно так же запускается на i-устройствах. Никаких дополнительных настроек или плясок с бубном — не требует.

Быстродействие.


Тема быстродействия — самая важная в нашей разработке. Естественно, нам хотелось получить продукт, который бы по плавности не отличался от других iOS-игр. Ну, или максимально к ним приближался. Обгоняя события, скажу, что это удалось не везде.

Итак, наша игра требовала вывод пары десятков анимированных спрайтов на экран как можно быстрее. Опишу технологии в хронологическом порядке.

Flash engine, bitmap frames.

Конечно же, ни о каком векторе речи быть не может. По этому первое, что мы попробовали — это экспортануть наш вектор в битмапки и вставить их обратно во флэш кадрами.



Получилось неплохо, но хотелось быстрее/плавнее.

Bitmap blitting.

Наверное, многие знакомы с этой технологией. Это случай, когда вы плюете на пайплайн флэша и делаете все сами — генерите пустой прямоугольник и каждый кадр, последовательно спрайт за спрайтом, с помощью copyPixels, копируете их на него.

Далее — выводите получившееся полотно как один Bitmap объект.

Эта технология неплохо себя показывает на десктопах, но на iOS она оказалась фейловой. Движок работал раз в 10 медленнее.

Модифицированный flash engine.

Вот она — золотая середина.

После некоторого гугленья, стало ясно, что позволяет ускорить графику. Суть в том, что когда мы как в 1-м случае делали каждый кадр анимации в новом фрейме — флэшу приходилось каждый фрейм убивать старый кадр из памяти и создавать новый. Что весьма ресурсоемко.

Где-то прочитал о технологии, которая позволяет выжать максимум из мобильного окружения.

Суть ее в том, что вы создаете MovieClip с 1 кадром и бросаете в этот фрейм ВСЕ кадры анимации сразу.

Далее, с помощью visible показываете только нужный. Фишка в том, что все кадры анимации одновременно присутствуют в памяти (и виртуальная машина уже выделила под них память и запихала их туда), а вы лишь включаете/выключаете их видимость. Но при этом не происходит перестроения памяти и все работает максимально быстро.

Как модификация технологии — есть вариант (который и использовали), когда все кадры хранятся в отдельных bitmapData. И вместо того, чтобы дергать visible у кучи Bitmap'ов, вы имеете один, основной Bitmap и переставляете ему bitmapData. Т.е. что-то вроде main_bmp.bitmapData = bd_frame[i];

На этом и остановились. Скорость анимации была где-то в 1,5 раза выше первого случая и позволяла выводить 20-30 спрайтов на 40 fps на iPhone4, что нас вполне устраивало.

Советы по оптимизации производительности.


В ходе разработки, мы столкнулись с граблями, которые хотелось бы просуммировать в виде советов:
  1. Как можно меньше создавайте динамичных объектов.
  2. Чем меньше объектов на экране будет ловить события «мыши» (пальца) — тем лучше. Ставьте всем mouseEnabled, mouseChildren в false.
  3. Лучше не пытайтесь двигать большие объекты и тем более — менять их альфу.
  4. Ставьте cacheAsBitmap для всего, что не анимировано.
  5. Если надо что-то вращать или менять альфу — юзайте cacheAsBitmapMatrix — это позволит ускорить этот процесс.
  6. Не вешайте кучу лисенеров на ENTER_FRAME. Лучше сделайте один, который будет вызывать все необходимые.
  7. Не привязывайтесь к кадрам, а привязывайтесь к таймеру. Т.е. в вашем лисенере на ENTER_FRAME ведите счетчик времени с прошлого вызова и уже исходя из него — производите все калькуляции.

Итак… В сроки мы не уложились и вместо 1 месяца, ушло на все 2. Но очень уж не хотелось выпускать совсем какашку.

Специфика платформы.


Retina vs lo-res.

Как ведет себя air-приложение, запущенное на айфонах с разным экраном? На самом деле, все просто. В настройках вы выставляете, хотите вы ретина-приложение или нет. И в зависимости от этого — ваше приложение будет масштабироваться.

В нашем случае, мы создали ретина приложение и размер сцены 960x640. На iPhone 4/4S оно идет без масштабирования. На 3-й серии оно скейлится на 50%.

Конечно, при большом желании — можно заморочиться и получать scale при инициализации и в зависимости от того, будет ли он 1.0 или 0.5 — выводить разную графику… Но это показалось нам очень сложным (да и не позволило бы собрать сцены в самом флэше, все бы пришлось писать кодом), так что мы плюнули.

iPhone vs iPad.

Тут тоже самое, что и с ретиной. Если вы выставите галочку «iPad», то приложение на айпаде будет запускаться во весь экран, масштабируясь под него (что в случае 960x640 приведет к некратному масштабированию и артефактам). Если же такую галочку не ставить — то оно будет вести себя как обычное iPhone-приложение, запущенное на айпаде — т.е. запускаться в малекьном окошке с кнопкой «х2».



Мы сделали именно так.

В последствии, вероятно, соберем HD версию специально под айпад — на полный экран и с полноценной графикой.


CPU vs GPU.

Флэш под Air можно собрать в двух вариантах — с движком на GPU и на CPU. К моему удивлению, алгоритм движка был такой, что разница между GPU и CPU была очень незначительна (не более 10%). По этому, мы остановились на CPU, т.к. компиляция под GPU не поддерживает эффектов. Т.е. все обводки шрифтов и тенюшки не работали бы. Конечно, выход был — брать шрифт с эффектами, создавать bitmapdata, туда делать draw() этого шрифта, а полученный битмэп — уже добавлять на сцену. В таком случае, все эффекты были бы на месте, т.к. draw() выполняется в любом случае на CPU и по этому не теряет эффектов.

Но это было как-то очень геморно и было решено, что игра не стоит свеч.

Но, думаю, этот вопрос надо рассматривать индивидуально, для каждого проекта.

Проблемы и решения.


Очевидно, не ко всем возможностям iOS мы будем иметь доступ из Air. Например, к возможностям Game Center. Что делать? Тупик?

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

Кроме того, использование native extensions влечет вторую (и даже третью) проблемы — невозможность скомпилить ipa из флэша (необходимо пользоваться командной строкой) и танцы с бубном чтобы это дело заработало на железе.

Также, почему-то новые версии Эира плевать хотели на выключатель звука на телефоне. Чтобы он заработал — тоже нужно воспользоваться native extension'ом. Если будет интересно — могу написать отдельную статью про native extensions.

Плюс ко всему, весь процесс все равно нельзя завершить на PC. Несмотря на то, что даже сертификаты можно создать под windows (опять-таки — если кому интересно — могу описать все пляски с бубном в отдельной статье), но чего нельзя сделать под виндами — это залить приложение в апп стор. С недавних пор — это делается единственным возможным путем — с помощью специальной программы, которая требует минимум Mac OS 10.6.8. И никак иначе. Долгая и упорная пляска с бубном таки позволила поставить эту версию макоси на виртуалку под AMD (если кому интересно, то коротко: работал только образ 10.6.4 (legacy), на него скачал комбо-апдейт до 10.6.8 (руками!), поставил, не ребутил, заменил kext'ы чтобы не висло на PCI configuration begin, загрузил с игнорирование кэшей). Еще немного плясок с бубном — и приложение залито!

Выводы.


Удался ли опыт? Как именно опыт новой технологии — я считаю, да.



Но как платформу для написания динамичных игр — я бы все-таки пока что не советовал флэш. Т.к. тормоза все-таки есть. Например, анимацию передвижения объектов в меню так и не удалось сделать плавной на 4-м айфоне. На 4S и iPad 2 — все летает. Но, с другой стороны, — эти особенности не особо критичны и не мешают геймплею.

Резюмируя — можно сказать так — писать можно. И даже выглядеть это может неплохо. Но по некоторым пунктам все равно пока не дотягивает до нативных приложений.

Хотя, Adobe тоже не стоит на месте. Вчера он анонсировал релиз-кандидат Air 3.2, где есть полное использование GPU (в т.ч. и 3D). Посмотрим…

Результат.


Здесь были картинки, промо-коды и ссылки на продукт, но т.к. я не хочу публиковаться в «я пиарюсь», то я убрал их.

О результатах пока говорить рано — игрушка только несколько дней в аппсторе. Недавно опубликовались на iphones.ru. Так что пока что — все впереди. Если будет интересно — потом могу написать о коммерческих результатах. Правда, уже словили отзыв на 1 балл от «героя», жалующегося на отсутствие ачивок (а они есть, и прямо в главном меню) и физики. Да, именно физики у нас в игре и не хватает.

Как бонус — пара скетчей:

Tags:
Hubs:
Total votes 52: ↑39 and ↓13 +26
Views 1.7K
Comments 36
Comments Comments 36