简体   繁体   English

ActionScript / Flash - 加载外部,以编程方式创建的SWF?

[英]ActionScript / Flash - Loading External, Programatically Created SWF?

i've never had to do any cross scripting until now and i'm running into a (probably really stupid) error right at the start. 到目前为止我从来没有做过任何交叉脚本,而且我在开始时遇到了(可能是非常愚蠢的)错误。

External SWF: i've created a new ActionScript 3.0 project in Flash Professional CS5. 外部SWF:我在Flash Professional CS5中创建了一个新的ActionScript 3.0项目。 on the first frame i've added the following script: 在第一帧我添加了以下脚本:

//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;
}

save, compile, done. 保存,编译,完成。 this works fine as a stand alone swf, which simply displays a rotating blue square at center stage. 这可以作为一个独立的swf工作,它只是在中心舞台上显示一个旋转的蓝色方块。

Main SWF: i've created a new ActionScript 3.0 file in Flash Professional CS5, which has a document class called CrossScriptTest : 主要SWF:我在Flash Professional CS5中创建了一个新的ActionScript 3.0文件,该文件有一个名为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);
    }
}
}

Error: i receive the following error: 错误:我收到以下错误:

TypeError: Error #1009: Cannot access a property or method of a null object reference. TypeError:错误#1009:无法访问空对象引用的属性或方法。 at Square_fla::MainTimeline/frame1() 在Square_fla :: MainTimeline / frame1()

perhaps i'm misunderstanding the nature of cross scripting or loading external swf files, but i can only seem to make this work if i've manually drawn display objects on the stage and not if the external swf's display objects are generated by code. 也许我误解了交叉脚本或加载外部swf文件的本质,但是如果我在舞台上手动绘制显示对象而不是外部swf的显示对象是由代码生成的话,我似乎只能使这个工作。

is it not possible to load external swfs that are programatically created and add them to the display list of a main swf? 是不是可以加载以编程方式创建的外部swfs并将它们添加到主swf的显示列表中?

the solution is always so obvious after the fact. 事后,解决方案总是如此明显。 the solution is, of course, to assign an Event.ADDED_TO_STAGE event listener in the constructor or initialize method of the external swf's document class. 当然,解决方案是在外部swf文档类的构造函数或初始化方法中分配Event.ADDED_TO_STAGE事件侦听器。

in my defense this was overlooked since it is not required nor common when creating a standard (internal?) document class. 在我的辩护中,这被忽略了,因为在创建标准(内部?)文档类时不需要也不常见。

Main SWF's Document Class: 主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);
        }
    }
}

External SWF's Document Class: 外部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;
        }
    }
}

Yes it can be done, but the way you are doing it doesn't seem right. 是的,它可以做到,但你这样做的方式似乎并不正确。 You could simply use a loader: 你可以简单地使用一个加载器:

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: 编辑:

In general, try not to use frame scripts, especially when loading SWFs within SWFs, because the way they work is not always obvious. 通常,尽量不要使用框架脚本,尤其是在SWF中加载SWF时,因为它们的工作方式并不总是很明显。 For instance, I don't know what the root is in your script - is it the root of your SWF or that of the parent SWF? 例如,我不知道你的脚本中的root是什么 - 它是你的SWF的根还是父SWF的根? (I don't know because, to avoid this kind of problem, I never use frame scripts). (我不知道因为,为了避免这种问题,我从不使用框架脚本)。 To avoid that, you can simply use a document class and put all your code in there. 为避免这种情况,您只需使用文档类并将所有代码放在那里。

Maybe try something like that and see if it works: 也许尝试类似的东西,看看它是否有效:

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;
        }

    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM