Страница 1 из 1
Проблема со stage при загрузке внешней swf
Добавлено: 24 апр 2014, 18:16
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 тоже. Ну или как-то так. Но в целом не понимаю в чем проблема и как поправить.
Re: Проблема со stage при загрузке внешней swf
Добавлено: 24 апр 2014, 18:43
alexandr_ratush
Скорее всего нужно в классе Main подписаться на событие ADDED_TO_STAGE, и уже в обработчике обрабатывать flashVars.
Re: Проблема со stage при загрузке внешней swf
Добавлено: 25 апр 2014, 18:29
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 и полоса на нуле. Меняется только в момент полной загрузки
Re: Проблема со stage при загрузке внешней swf
Добавлено: 25 апр 2014, 18:36
alexandr_ratush
Если трейсы выдает правильные, то значит проблема в самом скейле, я так думаю.
Нужно больше кода.)
Что там в методе setPercent находиться?
Re: Проблема со stage при загрузке внешней swf
Добавлено: 25 апр 2014, 18:51
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)+"%"; }
Re: Проблема со stage при загрузке внешней swf
Добавлено: 25 апр 2014, 20:03
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 мб. выдал трейс
P.S. Если работаете в CS, то там можно имитировать загрузку. После запуска в флеш-плеере "Файл"-"Просмотр"-"Параметры загрузки", и потом Ctrl+Enter.
Re: Проблема со stage при загрузке внешней swf
Добавлено: 25 апр 2014, 20:05
alexandr_ratush
Да, забыл написать, я тестировал работу метода
setPercent с помощью слайдера, у которого мин = 0, максимум 1 с шагом 0.01.
Все работает отлично.
Re: Проблема со stage при загрузке внешней swf
Добавлено: 25 апр 2014, 20:21
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)+"%"; } }}
Я хз в чем проблема.
Может, запустите его у себя?
Re: Проблема со stage при загрузке внешней swf
Добавлено: 25 апр 2014, 20:45
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 сек., с прелоадером и в конце добавилась флешка.