ActionScript / Flash - загрузка внешнего, программно созданного SWF? - PullRequest
0 голосов
/ 23 августа 2011

Мне никогда не приходилось делать кросс-скриптинг до сих пор, и я сталкиваюсь с (возможно, действительно глупой) ошибкой в ​​самом начале.

Внешний SWF: Я создал новый проект ActionScript 3.0 во Flash Professional CS5. На первом кадре я добавил следующий скрипт:

//Square.fla frame script

import flash.display.Shape;
import flash.events.Event;

var s:Shape = new Shape();
s.graphics.beginFill(0x0000FF, 1.0);
s.graphics.drawRect(-100, -100, 200, 200);
s.graphics.endFill();

s.x = stage.stageWidth / 2;
s.y = stage.stageHeight / 2;

addChild(s);

addEventListener(Event.ENTER_FRAME, enterFrameEventHandler);

function enterFrameEventHandler(evt:Event):void
{
    s.rotation += 2;
}

сохранить, скомпилировать, готово. это прекрасно работает как отдельный SWF, который просто отображает вращающийся синий квадрат в центре сцены.

Основной SWF: я создал новый файл ActionScript 3.0 во Flash Professional CS5, в котором есть класс документа с именем CrossScriptTest :

//CrossScriptTest.as

package
{
//Imports
import flash.display.StageScaleMode;
import flash.display.StageAlign;
import flash.display.Sprite
import flash.display.Loader;
import flash.events.IOErrorEvent;
import flash.net.URLRequest;
import flash.events.Event;

//Class
[SWF(width = "1000", height = "500", backgroundColor = "0x444444")]
public class CrossScriptTest extends Sprite
{
    //Constants
    private static const SQUARE_SWF_URL:String = "Square.swf";

    //Variables
    private var SWFLoader:Loader;

    //Constructor
    public function CrossScriptTest()
    {
        stage.scaleMode = StageScaleMode.NO_SCALE;
        stage.align = StageAlign.TOP_LEFT;
        stage.frameRate = 60;

        init();
    }

    //Initialize
    private function init():void
    {
        SWFLoader = new Loader();
        SWFLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, IOErrorEventHandler);
        SWFLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, loaderCompleteEventHandler);
        SWFLoader.load(new URLRequest(SQUARE_SWF_URL));
    }

    //IOError Event Handler
    private function IOErrorEventHandler(evt:IOErrorEvent):void
    {
        trace(evt);
    }

    //Loader Complete Event Handler
    private function loaderCompleteEventHandler(evt:Event):void
    {
        evt.currentTarget.removeEventListener(IOErrorEvent.IO_ERROR, IOErrorEventHandler);
        evt.currentTarget.removeEventListener(Event.COMPLETE, loaderCompleteEventHandler);

        var squareSWF:Sprite = Sprite(evt.currentTarget.content);
        addChild(squareSWF);
    }
}
}

Ошибка: я получаю следующую ошибку:

TypeError: Ошибка # 1009: невозможно получить доступ к свойству или методу с нулевым значением ссылка на объект. at Square_fla :: MainTimeline / frame1 ()

возможно, я неправильно понимаю природу кросс-скриптинга или загрузки внешних SWF-файлов, но мне кажется, что это можно сделать, только если я нарисовал экранные объекты вручную на сцене, а не если внешние объекты SWF генерируются код.

нельзя ли загрузить внешние SWF-файлы, созданные программным способом, и добавить их в список отображения основного SWF-файла?

Ответы [ 2 ]

2 голосов
/ 23 августа 2011

решение всегда так очевидно после факта. Конечно, решение состоит в том, чтобы назначить Event.ADDED_TO_STAGE прослушиватель событий в конструкторе или инициализировать метод класса документа внешнего swf.

в мою защиту это было упущено, поскольку это не требуется и не является общим при создании стандартного (внутреннего?) Класса документов.

Класс основного документа SWF:

package
{
    //Imports
    import flash.display.StageScaleMode;
    import flash.display.StageAlign;
    import flash.display.Sprite
    import flash.display.Loader;
    import flash.events.IOErrorEvent;
    import flash.net.URLRequest;
    import flash.events.Event;

    //Class
    [SWF(width = "1000", height = "500", backgroundColor = "0x444444")]
    public class CrossScriptTest extends Sprite
    {
        //Constants
        private static const SQUARE_SWF_URL:String = "Square.swf";

        //Variables
        private var swfLoader:Loader;

        //Constructor
        public function CrossScriptTest()
        {
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align = StageAlign.TOP_LEFT;
            stage.frameRate = 60;

            init();
        }

        //Initialize
        private function init():void
        {
            swfLoader = new Loader();
            swfLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, IOErrorEventHandler);
            swfLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, loaderCompleteEventHandler);
            swfLoader.load(new URLRequest(SQUARE_SWF_URL));
        }

        //IOError Event Handler
        private function IOErrorEventHandler(evt:IOErrorEvent):void
        {
            trace(evt);
        }

        //Loader Complete Event Handler
        private function loaderCompleteEventHandler(evt:Event):void
        {
            evt.currentTarget.removeEventListener(IOErrorEvent.IO_ERROR, IOErrorEventHandler);
            evt.currentTarget.removeEventListener(Event.COMPLETE, loaderCompleteEventHandler);

            addChild(evt.currentTarget.content);
        }
    }
}

Класс документа внешнего SWF:

package
{
    //Imports
    import flash.display.Sprite;
    import flash.display.Shape;
    import flash.events.Event;

    //Class
    public class Square extends Sprite
    {
        //Constructor
        public function Square()
        {
            init();
        }

        //Initialize
        private function init():void
        {
            addEventListener(Event.ADDED_TO_STAGE, addedToStageEventHandler);
        }

        //Added To Stage Event Handler
        private function addedToStageEventHandler(evt:Event):void
        {
            removeEventListener(Event.ADDED_TO_STAGE, addedToStageEventHandler);

            var s:Shape = new Shape();
            s.graphics.beginFill(0x0000FF, 1.0);
            s.graphics.drawRect(-100, -100, 200, 200);
            s.graphics.endFill();

            s.x = stage.stageWidth / 2;
            s.y = stage.stageHeight / 2;

            addChild(s);

            s.addEventListener(Event.ENTER_FRAME, enterFrameEventHandler);
        }

        //Enter Frame Event Handler
        function enterFrameEventHandler(evt:Event):void
        {
            Shape(evt.currentTarget).rotation += 2;
        }
    }
}
0 голосов
/ 23 августа 2011

Да, это можно сделать, но то, как вы это делаете, кажется неправильным. Вы можете просто использовать загрузчик:

var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener("complete", loader_complete);
loader.load(new URLRequest("yourfile.swf"));

function loader_complete(event:*):void {
    var loadedObject:* = event.target;
    // Access the properties of the loaded SWF here
}

Edit:

В общем, старайтесь не использовать фрейм-сценарии, особенно при загрузке SWF-файлов внутри SWF-файлов, потому что способ их работы не всегда очевиден. Например, я не знаю, что корень в вашем скрипте - это корень вашего SWF или родительского SWF? (Я не знаю, потому что, чтобы избежать такой проблемы, я никогда не использую фрейм-скрипты). Чтобы избежать этого, вы можете просто использовать класс документа и поместить туда весь свой код.

Возможно, попробуйте что-нибудь подобное и посмотрите, работает ли оно:

package some.unique.path {

    import flash.display.MovieClip;
    import flash.display.Shape;
    import flash.events.Event;

    public class YourClass extends MovieClip {

        public function YourClass():void {
            var s:Shape = new Shape();
            s.graphics.beginFill(0x0000FF, 1.0);
            s.graphics.drawRect(-100, -100, 200, 200);
            s.graphics.endFill();

            s.x = stage.stageWidth / 2;
            s.y = stage.stageHeight / 2;

            addChild(s);

            addEventListener(Event.ENTER_FRAME, enterFrameEventHandler);
        }

        function enterFrameEventHandler(evt:Event):void
        {
            s.rotation += 2;
        }

    }

}
...