На Flash (в AS2 проектах), я помещал прелоадер в 1-й кадр и писал его
на AS1, а AS2 классы экспортировались в 2-й кадр.
На Flex, как я вижу, используется атрибут preloader тега mx:Application.
А как сделать в pure AS3 проекте, где не будет использоваться ни Flash, ни MXML?
Если всё-таки предпочтительным способом является внешний прелоадер, то
как передать все параметры из LoaderInfo.parameters прелоадера в
LoaderInfo.parameters основной флешки?
Спасибо.
Для того, чтобы сделать прелоадер на AS3 нужно использовать ту же
технику, что и во Flash: требуется два кадра.
В первый кадр помещается только то, что требуется для прелоадера и
ничего лишнего.
Во второй кадр помещается главный класс и все классы, которые от него
зависят (а вместе с ними - и все прописанное с помощью Embed).
Как же сделать 2 кадра на чистом AS3? Есть несколько способов:
1. Через ключ компилятора -frame
2. Через тэг метаданных [Frame]
3. С помощью <frames><frame> в конфигурационном файле
(предположительно - пока не проверял).
Способ 1.
Если компилятору передать ключ -frame start Main, то автоматически
будет создан второй кадр и класс Main вместе со всеми зависимостями
будет помещён в него.
Таким образом нам нужно 2 класса: Preloder и Main. Preloader будет
главным классом (передаётся компилятору непосредственно), а Main -
второстепенным (передаётся через ключ -frame).
Например так:
mxmlc Preloader.as -frame start Main
В результате получим Preloader.swf, который содержит 2 кадра.
Preloader будет экспортирован в первый (и он же будет document class,
таким образом его экземпляр будет создан автоматически), а Main - во
второй (и его экземпляр автоматически создан не будет).
Способ 2.
В классе Main пишем:
[Frame(factoryClass="Preloader")]
В этом случае компилируем уже Main:
mxmlc Main.as
Опять же будет создано два кадра, опять Preloader окажется в первом, а
Main - во втором, и снова Preloader будет document class (хотя мы и
компилировали Main).
Способ 3.
Чисто гипотетически эквивалентом ключа -frame (полное название:
-frames.frame) является тэг в конфигурационном файле <frame><frame>.
Правда информацию о точно синтаксисе не нашёл, так как что
подробностей пока сказать не могу.
Однако если такой вариант возможен, то во всём остальном он будет
эквивалентен способу 1.
Общее.
Какой бы способ не избрали, в любом случае Preloaader станет document
class и таким образом его экземпляр станет родителем для всех
остальных спрайтов и клипов.
Кроме того, он будет содержать два кадра, отсюда следуют две вещи:
1. Он должен обязательно наследовать от MovieClip, а не от Sprite.
2. Первое, что нужно сделать - это stop()
В этом классе необходимо контролировать процесс загрузки (например по
ENTER_FRAME).
Когда swf полностью загружен, необходимо создать экземпляр класса Main
и добавить его с помощью addChild. Так как мы не можем напрямую
импортировать данный класс (иначе вместе с ним потянутся и все
зависимости и в результате вообще всё попадёт в первый кадр), то
создавать экземпляр надо косвенно - с помощью getDefinitionByName.
Отсюда следствие для структуры класса Main: нельзя в его конструкторе
использовать свойство stage. Мы обязаны обработать событие
ADDED_TO_STAGE и только когда оно произошло, выполнять ту часть
инициализации, которая завязана на stage (например корректировку
размеров и положения элементов в зависимости от размеров сцены).
Ну вот в принципе и всё.
Подробности и примеры кода - в предыдущих сообщениях.
P.S.
Разумеется необязательно делать Preloader корневым классом.
Можно создать какой-то специальный корневой класс-посредник, который
сперва инстанциирует Preloader (который в этом случае будет чисто
визуальным легко заменяемым классом), а по завершении загрузки -
убивает прелоадер и инстанциирует Main.
Когда все кадры загружены, нужно обязательно сделать nextFrame, в
противном случае getDefinitionByName не сможет найти нужный класс.
You wrote:
> Способ 1.
> mxmlc Main.as
> --~--~---------~--~----~------------~-------~--~----~
Если уж на pureAS3 идеальный вариант - контейнер A и main application
B.
Где A -> создает Loader, вешает на него ProgressEvent. и грузит в
Где A -> инстанс лоадера B.
Тогда "однокадровость" и целостность принципов ас3 сохраняются ^_^
______________
Jloa.
Но могут возникнуть заморочки с параметрами, переданными через FlashVars.
> 1. Через ключ компилятора -frame
> 2. Через тэг метаданных [Frame]
> 3. С помощью <frames><frame> в конфигурационном файле
> (предположительно - пока не проверял).
Выяснил интересную особенность. Между 1 и 2 вариантом есть
существенная разница. В одном из проектов мы изначально решили
использовать 2 вариант. Все бы хорошо, но в какой-то момент обратили
внимание на заметно выросший вес приложения. Посмотрели на report.xml
и выяснили, что в приложение зачем-то вкомпилировалось много флексовых
классов, включая, например, UIComponent и UITextField. После
некоторого ковыряния и попыток понять, откуда ноги растут, выяснили,
что виной всему именно тэг [Frame(factoryClass="Preloader")].
Попробовали первый способ - никаких лишних классов. Размер приложения
с ~220KB упал до ~100KB.