Adding to Stage in ActionScript 3 from a .as file

2019-08-25 13:50发布

Note: Yes, I know that similar questions have been asked before. However, after following the answers in such questions I'm still stuck and can't find a solution to my problem.

I'm having a problem which requires adding DisplayObjects to the Flash stage. Since I have to Display elements of several different classes, I decided to create a class to work as an intermediary between the .as files and the addChild function called "Displayer" as shown below:

package
{
    import flash.display.DisplayObject;
    import flash.display.Sprite;
    import flash.display.Stage;

    public class Displayer extends Sprite //I read somewhere that DisplayObject
//as an extension can't be used for this, so Sprite will have to do.
    {
        private var _stage:Stage;

        function Displayer()
        {
            _stage = new Stage;
        }

        public function displayElement(displayable:DisplayObject)
        {
            _stage.addChild(displayable);
        }
    }
}

I compile it and there appears a problem that I don't understand: Error #2012: Can't instantiate Stage class. Evidently, something in this code is either missing or out of place, but since it's so straightforward I fail to see what the problem can be. I'm sure that it's not very complicated, I probably just need an outsider's perspective.

4条回答
该账号已被封号
2楼-- · 2019-08-25 13:57

Ok, I think instantiating a stage class won't do because as the as3 documentation says: "The Stage object is not globally accessible. You need to access it through the stage property of a DisplayObject instance."

You should instead pass a reference to the Stage object to your Displayer class and you can get a reference to the stage object, as the docs say, via a display object instance.

So the constructor might now look like:

function Displayer( stage:Stage )
{
    _stage = stage;
}

Assuming that the object which instantiates your Displayer is a child of the stage you can instantiate the Displayer by

displayer = new Displayer( stage );

If you use this approach there is no need for the Displayer class to extend anything or be added to the stage ( which is required btw in the approach of bitmapdata.com ).

查看更多
男人必须洒脱
3楼-- · 2019-08-25 14:15

The Stage object is not globally accessible. You need to access it through the stage property of a DisplayObject instance.

refer a following docs.

http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/Stage.html

package
{
    import flash.display.DisplayObject;
    import flash.display.Sprite;
    import flash.display.Stage;

    public class Displayer extends Sprite
    {
        var isAddedToStage:Boolean;

        public function Displayer()
        {
            if(stage) init();
            else      addEventListener(Event.ADDED_TO_STAGE, init);
        }

        private function init(e:Event=null):void
        {
           removeEventListener(Event.ADDED_TO_STAGE, init);
           isAddedToStage = true;
        }

        public function displayElement(displayable:DisplayObject):void
        {
            if(isAddedToStage)
              this.stage.addChild(displayable);
        }
    }
}
查看更多
虎瘦雄心在
4楼-- · 2019-08-25 14:17

You don't instantiate the Stage class, as the error says. Just like you cannot instantiate the DisplayObject class (which is why you have to extend Sprite).

Basically, you have two options here:

1) You add the child from a DisplayObjectContainer instance.

var displayerInstance:Displayer = new Displayer();
this.addChild( displayerInstance );

You would run this from a DisplayObjectContainer object that has already been added to the global stage. There is only a single stage in every project, even if you embed SWFs, the stage property of the SWF is actually the stage property of the top level application. So if you have this Displayer instance nested inside a class which is nested inside another class that is created in your main application, you would have to run "addChild" in each of those classes to get the Displayer to show.

2) You cheat. This is not recommended, at all. Basically, you pass in the stage object of an object when you instantiate the Displayer class.

var displayerInstance:Displayer = new Displayer( this.stage );
public function Displayer( stage:Stage ) {
    this.stage = stage;

    if ( this.stage ) {
        this.stage.addChild( this );
    }
}

This is a method that is good for adding Singletons to the stage (except there is not constructor for a Singleton). I created a profiler just before Christmas that was a Singleton (And later found Scout, damnit) that used this method for adding things to the stage when appropriate.

Again, that second option is not recommended for this situation, but it is a possibility.

As an aside, you should never add things directly to Stage, unless there is a clear reason for doing so (such as a popup). You should follow the display list methodology, where a DisplayObjectContainer adds another DisplayObject or DisplayObject container as a child and so on and so forth so that they are all connected to the TopLevelApplication.

查看更多
forever°为你锁心
5楼-- · 2019-08-25 14:23

There is always a simple solutions.if you need to add a child element into a stage from your class you can just pass the stage into your class as a object and add the child element into it, i did this for adding an image into my stage like this.

package {
    import flash.display.Loader;
    import flash.display.Sprite;
    import flash.net.URLRequest;
    import flash.display.Bitmap;

    public class ImageLoader extends Sprite{


        private var stageObj:Object; //create local variable to refarance stage

        public function loadeimage(StageObject:Object, Url:String){ //StageObject will bring the stage refarance into the class

            var reQuest:URLRequest = new URLRequest(Url);
            loader.load(reQuest);

            stageObj=StageObject; //make local refarance for stage inside the class

            var image:Bitmap;
            image=Bitmap(loader.content);

            image.x = 100;
            image.y = 100;

            stageObj.addChild(image); // add whatever object into stage refarance and this means the real stage..

        }
    }

}

only the things with comments are important and you can save this file as ImageLoader.as and import it and use it like this.

import ImageLoader;

var IL:ImageLoader = new ImageLoader();
IL.loadeimage(this,"img.jpg");

its simple as that. i think this is what you have search for... good luck. (you can pass any container or parant container this or this.stage it doesn't matter your child will be a part of it.

查看更多
登录 后发表回答