Проблема со stage при загрузке внешней swf

Обсуждение и помощь по вопросам взаимодействия с ВКонтакте API в Flash-приложениях (ActionScript)
Ответить
Agiliter
Сообщения: 112
Зарегистрирован: 01 фев 2014, 13:46

Проблема со stage при загрузке внешней swf

Сообщение Agiliter »

Добрый день! Решил сделать к приложению прелоадер. Приложение абсолютно рабочее.
Соответственно, в классе Preloader загружаю Main.swf.

Код: Выделить всё

loader = new Loader(); loader.load(new URLRequest("Main.swf"));
Класс Main имеет вид

Код: Выделить всё

public class Main extends Sprite     {        private var flashVars:Object;                public function Main()         {            trace("Запущен класс Main");                        flashVars = stage.loaderInfo.parameters as Object;                            if (!flashVars.api_id)            {                trace("local testing");                             // -- Your code for local testing:                flashVars['api_id'] = 929974;                flashVars['viewer_id'] = 28294934;                flashVars['sid'] = "9c1993dc6ce456784da785384a42974943b0c8a6427f7dc6d6ae90fe9134aa2e4382addb946357266ba04";                flashVars['secret'] = "6d8190d082";                // -- //            }                       if (stage)                 newGame(flashVars);            else                 trace("Fail in Main!");         }                   private function newGame(vkData:Object):void        {            trace("Запущена функция newGame класса Main");             var model:IModel = new ModelGamer(vkData);            var controller:IController = new Controller(model);                 var view:View = new View(model, controller, this.stage);                        }    }
Выдает ошибку
TypeError: Error #1009: Не удается вызвать свойство или метод со ссылкой на объект "null".
at Main()

Проблема в строчке

Код: Выделить всё

flashVars = stage.loaderInfo.parameters as Object;     
Я интуитивно полагаю, что проблема в том, что Main.swf теперь не главная и stage тоже. Ну или как-то так. Но в целом не понимаю в чем проблема и как поправить.
Аватара пользователя
alexandr_ratush
Сообщения: 94
Зарегистрирован: 05 мар 2014, 21:47

Re: Проблема со stage при загрузке внешней swf

Сообщение alexandr_ratush »

Скорее всего нужно в классе Main подписаться на событие ADDED_TO_STAGE, и уже в обработчике обрабатывать flashVars.
Agiliter
Сообщения: 112
Зарегистрирован: 01 фев 2014, 13:46

Re: Проблема со stage при загрузке внешней swf

Сообщение Agiliter »

Возник другой косяк. Полоса прелоадера не двигается постепенно, а показывает только положение 0 и 100% без промежуточных, текст прогресса аналогично.

Код: Выделить всё

 // слушаем событие окончания загрузкиloader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete); // слушаем событие прогресса загрузкиloader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onProgress); function onComplete(event:Event):void {     addChild(loader);} function onProgress(event:ProgressEvent):void{         var percent:Number;    percent = event.bytesLoaded/event.bytesTotal;        // сообщаем загрузчику текущий процент загруженности    preloaderView.setPercent(percent);    trace((percent * 100) + " %");} 
Исходя из процента меняется scaleX и text. Трейсами проценты хорошо выдает, а вот на сцене в этот момент показывает 0 и полоса на нуле. Меняется только в момент полной загрузки
Аватара пользователя
alexandr_ratush
Сообщения: 94
Зарегистрирован: 05 мар 2014, 21:47

Re: Проблема со stage при загрузке внешней swf

Сообщение alexandr_ratush »

Если трейсы выдает правильные, то значит проблема в самом скейле, я так думаю.
Нужно больше кода.)
Что там в методе setPercent находиться?
Agiliter
Сообщения: 112
Зарегистрирован: 01 фев 2014, 13:46

Re: Проблема со stage при загрузке внешней swf

Сообщение Agiliter »

alexandr_ratush писал(а):Что там в методе setPercent находиться?
Вот целиком класс

Код: Выделить всё

// серый фон загрузчика        private var background:Shape;        // зеленая плашка, которая отображает процесс загрузки        private var fill:Shape;        // текстовое поле которое отображает проценты загрузки        private var textField:TextField;                public function PreloaderView()        {            trace("Запущен класс PreloaderView");            // создаем серый фон загрузчика            background = new Shape();            background.graphics.beginFill(0xFFFF00, 1);            background.graphics.drawRect(0, 0, 300, 40);            background.graphics.endFill();            this.addChild(background);                        // зеленая плашка которая будет отображать прогресс загрузки            fill = new Shape();            fill.graphics.beginFill(0x00FF00, 1);            fill.graphics.drawRect(0, 0, 300, 40);            fill.graphics.endFill();            fill.scaleX = 0;            this.addChild(fill);                        // содаем текстовое поле которое будет отображать проценты загругки                        var format:TextFormat = new TextFormat('Tahoma', 30);            format.align = TextFormatAlign.CENTER;                        textField = new TextField();            textField.defaultTextFormat = format;            textField.width = 300;            textField.height = 60;            textField.mouseEnabled = false;            textField.textColor = 0xFFFFFF;            this.addChild(textField);        }                // Метод который необходимо вызвать извне, чтобы отобразить процент загрузки        public function setPercent(value:Number):void        {            trace("Percent " + value);            if (value < 0) value = 0;            if (value > 1) value = 1;            fill.scaleX = value;            textField.text = Math.floor(value*100)+"%";        }
Аватара пользователя
alexandr_ratush
Сообщения: 94
Зарегистрирован: 05 мар 2014, 21:47

Re: Проблема со stage при загрузке внешней swf

Сообщение alexandr_ratush »

А сколько весит ваша загружаемая флешка? Может она слишком маленькая?

Вот проведите такой тест у себя:

Код: Выделить всё

package  {    import flash.display.MovieClip;    import flash.events.Event;    import flash.display.Loader;    import flash.net.URLRequest;    import flash.events.ProgressEvent;    import flash.utils.getTimer;        public class Main extends MovieClip {        private var preloaderView:TestView;                private var _timeLoad:Number;                        public function Main() {            preloaderView = new TestView();             addChild(preloaderView);                        var loader:Loader = new Loader();                loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeLoad);                loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onProgress);                loader.load(new URLRequest("lib.swf"));                            _timeLoad = getTimer();        }                function completeLoad(e:Event):void {            _timeLoad = getTimer() - _timeLoad;            trace("миллисекунд " + _timeLoad);            trace("секунд " + _timeLoad / 1000);        }                function onProgress(event:ProgressEvent):void        {             var percent:Number;            percent = event.bytesLoaded/event.bytesTotal;            // сообщаем загрузчику текущий процент загруженности            preloaderView.setPercent(percent);        }    }    }
У меня к примеру при загрузке флешки размером 2 мб. выдал трейс

Код: Выделить всё

 миллисекунд 107секунд 0.107
P.S. Если работаете в CS, то там можно имитировать загрузку. После запуска в флеш-плеере "Файл"-"Просмотр"-"Параметры загрузки", и потом Ctrl+Enter.
Последний раз редактировалось alexandr_ratush 25 апр 2014, 20:07, всего редактировалось 1 раз.
Аватара пользователя
alexandr_ratush
Сообщения: 94
Зарегистрирован: 05 мар 2014, 21:47

Re: Проблема со stage при загрузке внешней swf

Сообщение alexandr_ratush »

Да, забыл написать, я тестировал работу метода setPercent с помощью слайдера, у которого мин = 0, максимум 1 с шагом 0.01.
Все работает отлично. :)
Agiliter
Сообщения: 112
Зарегистрирован: 01 фев 2014, 13:46

Re: Проблема со stage при загрузке внешней swf

Сообщение Agiliter »

alexandr_ratush писал(а):Вот проведите такой тест у себя:
миллисекунд 2117
секунд 2.117
alexandr_ratush писал(а):А сколько весит ваша загружаемая флешка? Может она слишком маленькая?
Почти 9 мб
alexandr_ratush писал(а):Да, забыл написать, я тестировал работу метода setPercent с помощью слайдера, у которого мин = 0, максимум 1 с шагом 0.01.
Не понял эту часть)
Вот целиком проект:
class Preloader

Код: Выделить всё

package  {    import flash.display.Sprite;    import flash.display.Loader;     import flash.events.Event;     import flash.events.IOErrorEvent;     import flash.events.SecurityErrorEvent;     import flash.events.ProgressEvent;    import flash.net.URLRequest;    import flash.utils.getTimer;     public class Preloader extends Sprite     {               public var loader:Loader;        private var preloaderView:PreloaderView;        private var _timeLoad:Number;                public function Preloader()         {            trace("Запущен класс Preloader");                        // создаем объект который будет отображать процесс загрузки            preloaderView = new PreloaderView();            // помещаем наш прелоадер на середину флеш-ролика                       preloaderView.x = (stage.stageWidth - preloaderView.width) / 2;             preloaderView.y = (stage.stageHeight - preloaderView.height) / 2;             this.addChild(preloaderView);                        //загружаем ролик и отслеживаем основные события             loader = new Loader();             // слушаем событие окончания загрузки            loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);             // слушаем событие прогресса загрузки            loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onProgress);                        loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onIOError);             loader.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityError);             loader.load(new URLRequest("Main.swf"));                         _timeLoad = getTimer();                 }                /* обработчики событий */        function onComplete(event:Event):void         {             trace("Загружено");            _timeLoad = getTimer() - _timeLoad;            trace("миллисекунд " + _timeLoad);            trace("секунд " + _timeLoad / 1000);                        addChild(loader);        }           function onIOError(event:IOErrorEvent):void         {             trace("IOErrorEvent: " + event.errorID);         }           function onSecurityError(event:SecurityErrorEvent):void         {            trace("SecurityErrorEvent: " + event.errorID);         }           function onProgress(event:ProgressEvent):void        {             var percent:Number;            percent = event.bytesLoaded/event.bytesTotal;                preloaderView.setPercent(percent);            trace((percent * 100) + " %");        }    }}
Класс который будет отображать процесс загрузки

Код: Выделить всё

package  {    import flash.display.BlendMode;    import flash.display.Shape;    import flash.display.Sprite;    import flash.text.TextField;    import flash.text.TextFieldAutoSize;    import flash.text.TextFormat;    import flash.text.TextFormatAlign;     class PreloaderView extends Sprite    {        private var background:Shape;        private var fill:Shape;        private var textField:TextField;                public function PreloaderView()        {            trace("Запущен класс PreloaderView");            // создаем фон загрузчика            background = new Shape();            background.graphics.beginFill(0xFFFF00, 1);            background.graphics.drawRect(0, 0, 300, 40);            background.graphics.endFill();            this.addChild(background);                        // плашка которая будет отображать прогресс загрузки            fill = new Shape();            fill.graphics.beginFill(0x00FF00, 1);            fill.graphics.drawRect(0, 0, 300, 40);            fill.graphics.endFill();            fill.scaleX = 0;            this.addChild(fill);                        // содаем текстовое поле которое будет отображать проценты загрузки                        var format:TextFormat = new TextFormat('Tahoma', 30);            format.align = TextFormatAlign.CENTER;                        textField = new TextField();            textField.defaultTextFormat = format;            textField.width = 300;            textField.height = 60;            textField.mouseEnabled = false;            textField.textColor = 0xFFFFFF;            this.addChild(textField);        }                // Метод который необходимо вызвать извне, чтобы отобразить процент загрузки        public function setPercent(value:Number):void        {            trace("Percent " + value);            if (value < 0) value = 0;            if (value > 1) value = 1;            fill.scaleX = value;            textField.text = Math.floor(value*100)+"%";        }    }}
Я хз в чем проблема.
Может, запустите его у себя?
Последний раз редактировалось Agiliter 25 апр 2014, 20:47, всего редактировалось 1 раз.
Аватара пользователя
alexandr_ratush
Сообщения: 94
Зарегистрирован: 05 мар 2014, 21:47

Re: Проблема со stage при загрузке внешней swf

Сообщение alexandr_ratush »

Запустил, ничего не меняя. Все работает отлично.
Вот скрин на дропбоксе https://www.dropbox.com/s/3r8ss9yi4uqomb6/screen.jpg
Вот так можно имитировать загрузку (если работаете во Flash CS) https://www.dropbox.com/s/uz2d1fj5tepkth6/screen2.jpg
alexandr_ratush писал(а):
Да, забыл написать, я тестировал работу метода setPercent с помощью слайдера, у которого мин = 0, максимум 1 с шагом 0.01.

Не понял эту часть)
Я имел ввиду что ваш метод setPercent правильно работает. :)

Только что выложил все на удаленный сервер, и все отлично отработало, флеш весом 2 мб. загружался порядка 20 сек., с прелоадером и в конце добавилась флешка.
Ответить