Прелоадер в Pure AS3 проекте.

216 views
Skip to first unread message

Daniil Tutubalin

unread,
Feb 17, 2009, 10:31:06 AM2/17/09
to ruF...@googlegroups.com
Подскажите как принято делать прелоадеры в pure as3 проектах.
Хочется, чтобы прелоадер был внутри основного swf (т.е. не был
отдельном swf-файлом). При этом чтобы он загружался раньше всех
остальных ассетов, классов и прочего.

На Flash (в AS2 проектах), я помещал прелоадер в 1-й кадр и писал его
на AS1, а AS2 классы экспортировались в 2-й кадр.
На Flex, как я вижу, используется атрибут preloader тега mx:Application.
А как сделать в pure AS3 проекте, где не будет использоваться ни Flash, ни MXML?

Если всё-таки предпочтительным способом является внешний прелоадер, то
как передать все параметры из LoaderInfo.parameters прелоадера в
LoaderInfo.parameters основной флешки?

Спасибо.

Roma Oskolkov

unread,
Feb 17, 2009, 10:56:29 AM2/17/09
to ruF...@googlegroups.com
А вы под pure as3 подразумеваете swf скомпиленный во FlashIDE?

Oleg Dolya

unread,
Feb 17, 2009, 10:58:12 AM2/17/09
to ruF...@googlegroups.com
Тоже можно в разных кадрах размещать код прелоадера и основной код, там какие-то директивы компилятора есть для этого...

2009/2/17 Roma Oskolkov <r.osk...@gmail.com>

Daniil Tutubalin

unread,
Feb 17, 2009, 11:00:35 AM2/17/09
to ruF...@googlegroups.com
Pure AS3 - значит компилирую с помощью Flex SDK, но не использую MXML
(и вообще хочу избежать использования Flex Framework).

Oleg Dolya

unread,
Feb 17, 2009, 12:39:10 PM2/17/09
to ruF...@googlegroups.com
http://omar-fouad.net/blog/?p=69
по-моему первая нагугленная ссылка :)

Daniil Tutubalin

unread,
Feb 17, 2009, 1:25:35 PM2/17/09
to ruF...@googlegroups.com
Спасибо!
А я нагуглил вот эту статейку Кейта Питерса: http://www.bit-101.com/blog/?p=946
Правда там написано, что информация почти наверняка устаревшая. Но тем
не менее довольно интересно и позновательно.

Daniil Tutubalin

unread,
Feb 17, 2009, 4:20:49 PM2/17/09
to ruF...@googlegroups.com
Итак, что я выяснил по этой теме.

Для того, чтобы сделать прелоадер на 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.

Daniil Tutubalin

unread,
Feb 18, 2009, 3:51:20 AM2/18/09
to ruF...@googlegroups.com
Маленькое дополнение (на которое я угробил несколько часов).

Когда все кадры загружены, нужно обязательно сделать nextFrame, в
противном случае getDefinitionByName не сможет найти нужный класс.

xia...@yandex.ru

unread,
Feb 18, 2009, 5:14:29 AM2/18/09
to ruFlash
Еще добавлю от себя.
Таким способом можно создать любое кол-во кадров, для каждого кадра
нужен свой класс и все кадры будут загружаться последовательно. Таким
образом можно разнести ресурсы по нескольким кадрам и обращаться к
классам в них по мере загрузки.
После загрузки кадров обязательно нужно вызвать stop() главного
мувика, иначе постоянно будут вызываться импорты класса и лишние
загрузки, в итоге вы получите лишний расход памяти и через некоторое
время могут появиться тормоза из-за лишних расчетов.

Julius [gmail]

unread,
Feb 18, 2009, 8:00:22 AM2/18/09
to Daniil Tutubalin
Hello, Daniil.

You wrote:

> Способ 1.

> mxmlc Main.as

> --~--~---------~--~----~------------~-------~--~----~

Если уж на pureAS3 идеальный вариант - контейнер A и main application
B.

Где A -> создает Loader, вешает на него ProgressEvent. и грузит в
Где A -> инстанс лоадера B.
Тогда "однокадровость" и целостность принципов ас3 сохраняются ^_^

______________
Jloa.

Daniil Tutubalin

unread,
Feb 18, 2009, 10:51:24 AM2/18/09
to ruF...@googlegroups.com
> Тогда "однокадровость" и целостность принципов ас3 сохраняются ^_^

Но могут возникнуть заморочки с параметрами, переданными через FlashVars.

Racer

unread,
Feb 18, 2009, 6:03:04 PM2/18/09
to ruFlash
Пользуй FlashDevelop. У него уже в шаблонах AS3 проекта есть готовый
вариант с предзагрузчиком. Всё очень просто.

prof

unread,
Mar 2, 2009, 8:16:08 AM3/2/09
to ruFlash
Daniil Tutubalin:

> Итак, что я выяснил по этой теме.

> 1. Через ключ компилятора -frame


> 2. Через тэг метаданных [Frame]
> 3. С помощью <frames><frame> в конфигурационном файле
> (предположительно - пока не проверял).

Выяснил интересную особенность. Между 1 и 2 вариантом есть
существенная разница. В одном из проектов мы изначально решили
использовать 2 вариант. Все бы хорошо, но в какой-то момент обратили
внимание на заметно выросший вес приложения. Посмотрели на report.xml
и выяснили, что в приложение зачем-то вкомпилировалось много флексовых
классов, включая, например, UIComponent и UITextField. После
некоторого ковыряния и попыток понять, откуда ноги растут, выяснили,
что виной всему именно тэг [Frame(factoryClass="Preloader")].
Попробовали первый способ - никаких лишних классов. Размер приложения
с ~220KB упал до ~100KB.

Reply all
Reply to author
Forward
0 new messages