Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   как передать в загруженный swf данные (http://www.flasher.ru/forum/showthread.php?t=182153)

dvrbear 13.07.2012 16:30

как передать в загруженный swf данные
 
Приветсвую!

Есть preloader.swf и его класc Preloader в котором происходит загрузка main.swf в мувик ALL.
Также в Preloader загружается XML.

Сложность в том что main.swf загружается через дополнительный класс MainPrel (в котором я отслеживаю загрузку swf, визуально полосочкой ее отображаю, затем добавляю swf в указанное место и убиваю прелодер)

Все работает отлично поэтому даю лишь кусочек кода:
Код AS3:

MainPrel(path:String, put_in:DisplayObjectContainer)
...
imageLoader = new Loader();
imageUrl = new URLRequest(path);
imageLoader.load(imageUrl);
...
put_in.addChild(imageLoader);
this.parent.removeChild(this);

Тоесть путь получается как бы: Preloader - ALL - main.swf
main.swf имеет также свой класс Main.as из которого диспатчером не могу достучаться до главного Preloader.

1. Вопрос в том как потом (после добавления в указанное место) обратиться к нему из Preloader и передать в main.swf - XML ?

2. Возможно ли вообще достучатсья диспатчером в из main.swf в preloader.swf ?

Wolsh 13.07.2012 16:41

1. Видимо в ДокументКлассе подгружаемой swf надо сделать сеттер, принимающий XML.
2. Что такое "достучаться диспатчером"? Не можете подписаться на событие? Так объясните, что за событие, когда оно диспатчится, откуда (не из конструктора, я надеюсь?) Вы можете только после загрузки swf подписаться из прелоадера на какое-то событие от ДокументКласса этой swf.

Добавлено через 1 минуту
Цитата:

this.parent.removeChild(this);
Ужас(((

dvrbear 13.07.2012 16:57

this.parent.removeChild(this);
по другому почемуто работать не хотел (((

Preloader:
Код AS3:

package  
{
        import com.preloaders.IMGPrel;
        import com.preloaders.MainPrel;
        import com.preloaders.XMLPrel;
 
        import flash.display.DisplayObjectContainer;
        import flash.display.MovieClip;
        import flash.events.Event;
 
        public class Preloader extends MovieClip
        {
                var total:Number;
                var loaded:Number;
                var rootXML:XMLPrel;
                var dataXML:XML;
                var mainBar:MainPrel;
 
                public function Preloader()
                {
                        if (stage)
                        {
                                f_addedStage();
                        }
                        else
                        {
                                addEventListener(Event.ADDED_TO_STAGE, f_addedStage);
 
                        }
                }
 
                public function f_addedStage():void
                {
                        addEventListener(Event.ENTER_FRAME, f_rootCheck);
                        removeEventListener(Event.ADDED_TO_STAGE, init);
                }
 
                public function f_rootCheck(e:Event=null):void
                {
                        var B_loaded:Number = loaderInfo.bytesLoaded;
                        var B_total:Number = loaderInfo.bytesTotal;
                        if (B_total == B_loaded)
                        {
                                this.addEventListener("D_XML", f_xmlDone);
 
                                rootXML = new XMLPrel("xml/data.xml");
                                this.addChild(rootXML);
 
                                removeEventListener(Event.ENTER_FRAME, f_rootCheck);
                        }
                }
 
                public function f_xmlDone(e:Event):void
                {
                        this.removeEventListener("D_XML", f_xmlDone);
 
                        dataXML = rootXML.dataXML;
 
                        mainBar = new MainPrel(dataXML, "main.swf", ALL, stage.stageWidth / 2, stage.stageHeight / 2);
                        this.addChild(mainBar);
 
                        stage.addEventListener(Event.RESIZE, resizeListener);
                        stage.scaleMode = StageScaleMode.NO_SCALE;
                        stage.align = StageAlign.TOP_LEFT;
                }
}

MainPrel:
Код AS3:

package com.preloaders 
{
        import flash.display.DisplayObjectContainer;
        import flash.display.Loader;
        import flash.display.MovieClip;
        import flash.events.Event;
        import flash.events.ProgressEvent;
        import flash.net.URLRequest;
 
        import fl.transitions.Tween;
        import fl.transitions.easing.*;
        import fl.transitions.TweenEvent;
 
        public class MainPrel extends MainPrelBar
        {
                var _put_in:DisplayObjectContainer;
                var per:Number;
                var total:Number;
                var loaded:Number;
                var imageLoader:Loader;
                var imageUrl:URLRequest;
                var tw_Alpha:Tween;
                var tw_Show:Tween;
                var tween_spd:Number = 20;
                var r_XML:XML;
 
                public function MainPrel(d_XML:XML, path:String, put_in:DisplayObjectContainer, pos_x:Number=10, pos_y:Number=10)
                {
                        r_XML = d_XML;
 
                        tw_Show = new Tween(this, "alpha", Regular.easeOut, 0, 1, tween_spd, false);
 
                        imageLoader = new Loader();
                        imageUrl = new URLRequest(path);
                        imageLoader.load(imageUrl);
 
                        imageLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, progressListener);
 
                        _put_in = put_in;
 
                        this.x = pos_x;
                        this.y = pos_y;
 
                }
                public function progressListener (e:ProgressEvent):void{
 
                        total = e.bytesTotal;
                        loaded = e.bytesLoaded;
 
                        per = Math.floor((loaded/total)*100);
                        mc_line.gotoAndStop(per);
 
                        if (total == loaded) {
                                imageLoader.contentLoaderInfo.removeEventListener(ProgressEvent.PROGRESS, progressListener);
 
                                tw_Alpha = new Tween(this, "alpha", Regular.easeOut, 1, 0, tween_spd, false);
                                tw_Alpha.addEventListener(TweenEvent.MOTION_FINISH, onFinish);
 
                        }
                }
                public function onFinish(e:TweenEvent):void {
                        _put_in.addChild(imageLoader);
                        tw_Show = new Tween(imageLoader, "alpha", Regular.easeOut, 0, 1, tween_spd, false);
                        this.parent.removeChild(this);
                }
 
        }
 
}

вот как из preloader обратиться к томуже СЕТТЕРУ Main'a если я вообще не могу понять где он относительно preloader'a распологается?

видимо путаюсь еще изза того что есть сами SWF на физическом уровне - которые нужно загружать и классы которые ими управляют

Добавлено через 4 минуты
приношу извинения за кривизну кода (только начал переходить с AS2 и очень сложно все дается)

если можно не акцентируйте внимание на мелочах и просто укажите как передать XML в main или как сделать так чтоб с main'a можно было к нему обращаться?

Wolsh 13.07.2012 21:58

Цитата:

если можно не акцентируйте внимание на мелочах и просто укажите как передать XML в main или как сделать так чтоб с main'a можно было к нему обращаться?
Не получается. Во-первых, из-за "мелочей" вроде разностильного именования (у Вас все 3 стиля вперемешку — и кошерный кэмел imageLoader, и простреленные tween_spd, и нормальные аббревиатуры dataXML, и ненормальные imageUrl, и приватные переменные то подчеркнутые _put_in как положено, то безо всяких подчерков, как и локальные. Разобраться в таком коде просто нереально, если не сам его писал 15 минут назад.
Во-вторых, Вы постоянно упоминаете некий "мейн", но что это такое — ни слова.
И самое главное (а может это и есть "во-вторых") — Вы задаете вопрос о передаче данных в загружаемую swf, а код приводите чего угодно, но только не этой swf.
Цитата:

видимо путаюсь еще изза того что есть сами SWF на физическом уровне - которые нужно загружать и классы которые ими управляют
Вот. Здесь собака-то зарыта. класс, "который управляет", должен иметь геттер, в который будет передаваться XML. Мало того, класс который будет отдавать эту XML должен знать мейн-класс свфки, чтобы обратиться к этому геттеру (иначе ошибка отсутствия нужного свойства у загруженной свф). Класс загружаемой свф (а лучше все же интерфейс) должен быть импортирован в загрузчик.
Кроме того, не вижу у Вас подписки на событие окончания загрузки (то, что Вы не подписываетесь на возможные ошибки загрузки это, в общем-то, Ваше личное дело). Вы решаете это математикой. Не надо. Есть событие Event.COMPLETE, говорящее об окончании загрузки с точностью до последнего байта :)
После этого контент Лоадера и есть мейн-класс загруженной свфки. Приводите контент к правильному типу (этот самый мейн-класс) и обращайтесь к его свойствам и методам (отдавайте XML).

dvrbear 13.07.2012 22:18

с орфографией полностью согласен (это придет)
main впринципе на важен - так как он может быть даже пустой

геттер и сеттер понимаю - но только на уровне добавления классов
при загрузке swf в мувик ALL сложно понять как к сеттеру обратиться
(присал сеттер но до него не достучаться в swf)

вот сам загрузчик swf
Код AS3:

public function progressListener (e:ProgressEvent):void{
 
                        total = e.bytesTotal;
                        loaded = e.bytesLoaded;
 
                        per = Math.floor((loaded/total)*100);
                        mc_line.gotoAndStop(per);
 
                        if (total == loaded) {
                        _put_in.addChild(imageLoader);
                        this.parent.removeChild(this);               
}

Добавлено через 4 минуты
ну а впрочем - рас я так уж не правильно поступаю (((
как мне в дальнейшем (не засовываю все до кучи в одну флешку) красиво разбить все на swf файлы (содержащие нужные графические иструменты в библиотеке) не просто их классы импортировать и добавлять на сцену но и отслеживать степень загрузки?

что вообще раньше надо делать (как про курицу и яйцо)

импортировать и добавлять классы на сцену(которыя я так понимаю потянут за собой автоматом swf файлы )
или загружать swf файлы в которых библиотечные объекты будут автоматом находить нужные классы ?

опятьже извиняюсь за дебильную постановку вопроса - но абсолютно нескем посоветоваться и самостоятельное изуение очень сложно дается (

Wolsh 14.07.2012 00:05

Как это не с кем? Нас тут много, советчиков)))
Все нормально с свф-файлами. Обычное дело хранить часть функционала в отдельных, подгружаемых по мере надобности, файлах (давайте для краткости будем звать их плагинами). То есть имеем основной свф-файл приложения и дополнительные файлы, расширяющие функционал. Дополнительные локации для игры. Дополнительные шрифты для "открыток". Дополнительные кисточки для рисовалок. Всё это плагины, которые могут понадобиться за "время жизни" приложения, а могут и не понадобиться. Поскольку имеют приличный вес, нет смысла запихивать все это в один файл. Подгружаем по мере надобности.
Далее. Чтобы классы основной флэшки могли вытащить ресурсы из плагинов, или обратиться к их методам и свойствам, основная флэшка должна знать, как это сделать. То есть должна знать названия этих методов и свойств. Для этого она должна знать классы или Интерфейсы документ-классов этих плагинов. Это понятно? Вот Ваши слова:
Цитата:

main впринципе на важен - так как он может быть даже пустой
Теперь вопрос: КАК Вы собираетесь "передать" XML "пустому" мейну загруженной флэшки? Что Вы подразумеваете под этим "передать", если нет никого, кто бы его принял? Кому? Зачем? Когда и для чего? Определитесь сначала с тем, что загружаемые свф-файлы не могут быть из деревни с дедушкой. Они должны быть совершенно определенным образом заточены для использования основной флэшкой. Как и все другие классы. Плагин должен быть готов к использованию, предоставляя конкретный Интерфейс, и основная флэшка должна знать этот Интерфейс.
Вы представляли себе это как-то иначе?

dvrbear 14.07.2012 12:37

Абсолютно с вами согласен!
Всё должно быть расставлено по полочкам.
Про пустой "майн" погорячился (так как там уже многое происходит и просто никак не мог получить xml).

Но всё же если не писать огромных примеров, как мне получить в main из preloader xml?

Я бы конечно мог сразу в майн xml загрузить - но хочется некой универсальности а также понять как всё работает чтоб в дальнейшем передавать нужные кусочки xml в другие подгруженные "плагины" :)

Самым больным вопросом остается то, как именно обратиться к main из preloader если main грузился через вспомогательный класс(прелодер майна)?

В MainPrel - main.swf находится в объекте imageLoader,
и я его поттом методом тыка ))) нашел - ALL.getChildAt(1) (либо если задам имя - то по имени),
попробовал написать геттер и сеттер в майне - но с preloader никак к ним обратиться не удается

в других примерах когда я добавлял классы (с привязанными к ним плагинами из библиотеки)
я удачно это проделывал(get/set, передача в конструктор, получение переменной "Класс.переменная"), но
когда я имею дело с подгуженной swf у меня ничего этого не получается (((

Wolsh 14.07.2012 13:11

Я же говорил — подпишитесь на событие COMPLETE от лоадера вашей второй свфки.
В обработчике события получите ссылку на content через (event.currentTarget as LoaderInfo).content.
Этот content и будет вашей свф-кой, а точнее экземпляром её документ-класса.

Wolsh 15.07.2012 00:06

Вложений: 1
Вот в архиве три файла.
Main.as — документ-класс для основной флэшки.
PluginMain.as — документ-класс для подгружаемой флэшки.
IPlugin.as — Интерфейс.
Поместите все три файла в директорию нового проекта и скомпилируйте сначала плагин с классом PluginMain, переименуйте полученный swf-файл в "LoadedSWF.swf".
Затем скомпилируйте основную флэшку с документ-классом Main.as.
Во флэшке должен отобразиться текст XML. При этом сам XML находится в классе основной флэшки, а текстовое поле, которое его покажет — в классе плагинской свфки.
Удачи..

dvrbear 16.07.2012 13:02

Код AS3:

var loader:Loader = (event.currentTarget as LoaderInfo).loader;
var pluginDO:DisplayObject = loader.content as DisplayObject;
this.addChild(pluginDO);

А если бы к примеру SWF не на главную сцену "this" а во внутрь куда-нибудь закопали (с целью расположения по слоям) - например ALL.LAYER1.addChild(pluginDO);

То как тогда выглядело бы обращение?
Код AS3:

var plugin:IPlugin = pluginDO as IPlugin;
plugin.XMLData = _xmlData;

За пример огромное спасибо!!!
покопаться в живом примере - это то что надо!


Часовой пояс GMT +4, время: 19:02.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.