Создание игровой анимации на примере Pudding Monsters



Всем привет!
Сегодня я расскажу, как мы упростили процесс создания анимации в играх, используя возможности Adobe Flash.

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

Так что же делать, если в приложении нужна красивая и сложная анимация? Правильно, нужно автоматизировать процесс создания программной анимации. Создание анимации необходимо полностью переложить на плечи художника, программист же должен заниматься написанием логики ее отображения.

Исторически сложилось, что Adobe Flash стал практически стандартом в области создания 2D анимации, а начиная с версии CS5, исходный файл с анимацией .fla — это обычный zip, внутри которого находится Flash документ в формате XFL. Именно его мы и используем для экспорта трансформаций на этапе подготовки ресурсов приложения.

Внутреннее устройство .fla файла

image
Не смотря на то, что документации по формату XFL до сих пор нет в открытом доступе, не составляет труда разобраться в его устройстве (об этом уже писали на хабре). ФайлDOMDocument.xml содержит описание всех трансформаций с использованием символов из библиотеки (директория LIBRARY). Все остальное в нашем случае не потребуется.

Каждый ключевой кадр в файле DOMDocument.xml представлен следующим образом:

<DOMFrame acceleration="100" index="39" keyMode="22017" motionTweenSnap="true" tweenType="motion">
    <elements>
        <DOMSymbolInstance libraryItemName="body_2" loop="single frame" symbolType="graphic">
            <matrix>
                <Matrix a="0.999252" b="0.038650" c="-0.038665" d="0.999481" tx="441.15" ty="890.95"/>
            </matrix>
            <transformationPoint>
                <Point x="-2.4" y="33.6"/>
            </transformationPoint>
        </DOMSymbolInstance>
    </elements>
</DOMFrame>

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

Обработка данных

Для воспроизведения трансформаций на движке игры проводится декомпозиция матрицы трансформации. Чтобы получить значения наклона (skew) и масштаба (scale) по каждой оси координат, воспользуемся формулами:
skewX = atan(-c/d)
skewY = atan(b/a)
scaleX = sqrt(a2+b2)
scaleY = sqrt(c2+d2)

Ресурсы приложения

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

Изображения, которые находятся внутри .fla файла, не используются во время отрисовки, а получаются из соответствующих слоев отдельных .psd файлов. Это позволяет использовать один .fla файл при создании анимации для нескольких разрешений. Организация библиотеки .fla файлов отражает эту зависимость:

image

Преимущества данного подхода

На примере продемонстрирую преимущества описанного метода, который был успешно опробован в нашей игре Pudding Monsters. Подсказки игроку реализованы в виде анимированных диалоговых пузырей, которых только в первом наборе уровней появляется 7 различных штук. Вот, как это выглядит в Adobe Flash:

image

Если бы мы пошли по простому пути и использовали покадровую анимацию, то кадры для каждой анимации подсказки разместились бы на атласе текстур с разрешением в среднем 4016x2086 (для экрана iPhone 4), например, на таком:

image

В результате, в памяти потребовалось бы держать порядка 16 МБ для каждой анимации, и это определенно перебор для такого второстепенного графического элемента. Пришлось бы упрощать анимацию и искать пути оптимизации.
image
С автоматизированным экспортом трансформаций, все что нужно для воспроизведения анимаций, — это атлас с разрешением 518x942 пикселей и файл с описанием объемом 284 КБ. Помимо того, что требуется так мало ресурсов, анимация проигрывается с частотой кадров 60 fps.

Такой подход позволил существенно уменьшить трудозатраты на создание анимации для всех наших игр, но это всего лишь один из вариантов автоматизации процесса.

Буду рад обсудить, как вы решали подобные задачи в своих проектах.