А что делать, если наш проект компилируется Flex SDK?
Можно сделать маленький модулек, который будет загружать и мониторить загрузку основного SWF. Ну а если требуется наличие только одного SWF?
Люди советуют почитать статью Preloaders in AS3. Читаем.
Основную мысль автору статьи, подсказал Ted Patrick, намекнув на мета-тег [Frame] и поглядеть исходник mx.core.Application.
Поглядим-ка
"...\Flex2SDK\frameworks\source\mx\core\Application.as ".
Как отметил 101 (тот что автор статьи) там и правда есть тег
[Frame(factoryClass="mx.managers.SystemManager")]. А в комментарии, по-моему, ключевой является фраза "Все фреймворки инициализируются SystemManager-ом".Идем смотреть
"...\Flex2SDK\frameworks\source\mx\managers\SystemManager.as".
И правда - видим интересные фразы типа "ВНИМАНИЕ: Минимизируйте не флэшовые классы, которые импортируете здесь, всё что связано с SystemManager будет загружено в 1й фрейм до того, как загрузится прелоадер, и вообще, что-либо отображающееся." Кроме того, несколько ниже, говорится, что "SystemManager - первый визуальный класс, который создается в приложении. Он так же отвечает за создание mx.preloaders.Preloader, который отображает mx.preloaders.DownloadProgressBar до конца загрузки приложения, после чего SystemManager создает mx.core.Application instance". Собственно, вызывается метод SystemManager.create, код которого приводит 101 (автор).
Он пришел к следующим мыслям:
- Сначала создаем основной класс MainClass как обычно и указываем компилятору чтобы он его компилил.
- Затем в этом классе вставляем тег [Frame(factoryClass="MyFactoryClass")], который указывает на некий другой класс MyFactoryClass.
Итак, нам остается всего-навсего создать класс обычного прелоадера, который:
- Делает stop();
- Мониторит загрузку любым удобным для нас способом.
- После полной загрузки делает nextFrame();
Еще одна любопытная особенность этого решения - основной таймлайн представляет MainClass, но в качестве "Document Class" теперь выступает не MainClass, а MyFactoryClass. Из этого следует:
- MyFactoryClass должен наследоваться от MovieClip. И не в коем случае не от Sprite.
- При инстанцировании MainClass, необходимо добавить (addChild) его в дисплей-лист MyFactoryClass.
- MainClass не будет являться корнем дисплей-листа. Он будет чайлдом MyFactoryClass.
- В своем конструкторе, MainClass не должен ссылаться на "stage", так как он будет доступен только после добавления (addChild) MainClass в дисплей-лист.
В основном классе FrameTest - это то что выше называлось MainClass - всё просто. Имбедится и выводится картинка "big_asset.jpg", желательно очень большого размера. Единственное необычное - это фраза
[Frame(factoryClass="MyFactory")].Класс MyFactory - это наш вышеописываемый MyFactoryClass.
- В конструкторе производится остановка тайм-лайна stop(), выставляются параметры stage и добавляется обработчик "ENTER_FRAME".
- Обработчик onEnterFrame() рисует полосу состояния загрузки вычисляя процент загрузки:
var percent:Number = root.loaderInfo.bytesLoaded / root.loaderInfo.bytesTotal; - При выполнении условия framesLoaded == totalFrames, объект отписывается от события "ENTER_FRAME", осуществляет переход на следующий фрейм nextFrame() и производит инициализацию init().
- Метод инициализации init() получает определение основного класса
var mainClass:Class = Class(getDefinitionByName("FrameTest"));и, если такой класс существуетif (mainClass), инстанцирует его и добавляет в дисплей-лист:var app:Object = new mainClass(); addChild(app as DisplayObject);.
Всё. Переходим к практике.
* * *
Не забудем положить картинку "big_asset.jpg" в папку с классами.
Первая коррекция - getDefinitionByName вызывает исключение, в случае если класс не найден. Поэтому проверки if(mainClass) недостаточно. Нужна обработка исключения try ... catch.
* * *
Пробуем trace(this.currentFrame);. Он выдает правильно - 1 из конструктора MyFactory, 2 - из init();.
Попробуем, как это будет работать в интернете. Хм. Прелоадер отрабатывает, но как-то поздно. Мой Naviscope показывает, что SWF загружается больше чем на половину, когда только начинает происходить отрисовка полосы загрузки. Попробую еще утяжелить SWF-ку. Для этого добавляю картинок.
Интересное наблюдение - если накопировать одну и ту же картинку и имбедить копии, размер SWF не изменится - как будто внедрена одна картинка! Вот это сжатие!
Итак, утяжелил до 20 мБ. Теперь всё встало на свои места. Прелоадер аккуратно отрабатывает объем и затем отображается картинка! Всё дело было в слишком быстром интернете.
Итак, подход прост и практичен. Спокойно делаем правильные и эффектные флэшки любого размера!

