Растеризация графики во Flash

Векторная графика хороша, пока её не становится много :] Когда её становится много, то процессор начинает не выдерживать нагрузки и игра начинает заметно тормозить. На помощь приходит растеризация векторной графики!

Есть 2 пути растеризовать векторную графику: перевести всю графику в растровые аналоги (например в .png) или же растеризовать вектор программно.

В этой статье мы рассмотрим второй вариант — программную растеризацию.

Мои наработки основаны на 3-х классах Антона Карлова, о них он пишет в своей статье «Из вектора в растр».

В своей версии я изменил и дополнил по большей части классы AnimCache и Actor.

Рассмотрим все классы подробнее.

Классы модуля

Первый класс MaxAnimCache — это хранилище всех растеризованных клипов. Он выполняет процесс кэширования любых указанных клипов и хранит результаты своей работы, пока не будет очищен. Можно создавать отдельные экземпляры класса, для разных блоков графики.

Методы класса MaxAnimCache

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

Методы класса MaxAnim

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

Рассмотрим основные методы.

Методы класса MaxActor

Остальные методы вы можете посмотреть в коде, большая часть прокомментирована.

Вся разница в том, что я значительно дополнил класс Actor-а, а так же выделил AnimCache из синглтона в обычный класс, что позволяет указывать при создании MaxActor определённый AnimCache. Можно, например, создавать отдельные AnimCache для меню и для игры и кешировать в игровой клипы лишь при необходимости, что разгружает оперативную память, а если ещё учитывать именно те клипы, которые будут использоваться на уровне и не кешировать другие, то вообще супер.

Давайте посмотрим на 2 идентичных проекта. Отличия будут только в том, что во втором мы будем применять растеризацию графических объектов.

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

В первом случае используем векторные изображения: Тест без растеризации.

А во втором случае те же самые векторные изображения растеризуем тем способом, который я хочу вам представить: Тест с растеризацией.

Рассмотрим код первой программы. Он состоит всего из 2-х файлов: главного и объекта, который создаётся и летает по сцене.

Основной файл Main.as

Тут в целом всё должно быть понятно, тем более есть некоторые комментарии.

Рассмотрим класс объекта.

Класс объекта Ashigaru

Коротко опишу логику класса.

В констуркторе сразу создаются все клипы анимаций, которые затем проигрываются случайным образом. Клип _curr является ссылкой на клип, который отображается в данный момент. В функции update() происходит вся логика перемещения, вращения и смены анимации по её завершённости или по таймеру базовой статической анимации.

В общем про код первого теста достаточно сказать, что отображение и анимация в нём сделана обычными способами с векторной графикой.

Куда интереснее рассмотреть код второго теста, посмотреть как именно он изменился и подойти к организации растеризации.

Главный класс Main проекта с растеризацией

Обратим внимание на изменение инициализации. В самом начале создаётся класс MaxAnimCache, это хранилище всех растеризованных клипов, которые мы укажем атрибутом в массиве для функции .addClipsToCacheQueue(), после этого указываем калбэк-функцию завершения кэширования и запускаем процесс кэширования анимации. Так же можно указать калбэк-функцию которая будет вызываться в процессе кэширования — .onProgressCallback. Пригодится, если у вас много клипов для кэширования и вы хотите как-либо отобразить этот процесс.

Далее по завершению кэширования выполняется калбэк-функция onCacheDone() и мы можем продолжать инициализировать игру.

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

Ещё изменился конструктор объекта, теперь в него необходимо передать наш банк кэша, чтобы использовать кэш уже в классе объекта.

Класс объекта Ashigaru с растеризацией

Сам класс Ashigaru будет выполнять роль контейнера, а для отображения кэшированных клипов используется класс MaxActor. Он создаётся сразу в конструкторе и в него добавляются анимации функцией addAnimFromCache(банк анимаций, имя закэшированного клипа, имя анимации). Переключать анимации в MaxActor будем функцией switchAnim(имя анимации), а отслеживать окончание анимации с помощью указания события onCompleteCallback.

Вся логика данного кэширования заключается в 3-х классах: MaxAnimCache, MaxActor, MaxAnim.

Скачать примеры: архив с примерами.

На этом пока всё, но продолжение следует (напишу про рендер в 1 битмап).