AS3无法从自定义类访问阶段

时间:2011-12-29 19:01:39

标签: actionscript-3 sprite stage

如何从自定义类访问舞台,尤其是flash影片的宽度和鼠标位置?

package classes
{
   import flash.events.*;
   import flash.display.*;

   public class TableManager extends Sprite
   {
        public function TableManager() {
            sayStage();
        }
        public function sayStage():void 
        {
            trace(stage);
        }
  }   
} 

这只会返回nill。我知道DisplayObjects在启动之前没有任何阶段,因此你无法访问构造函数中的阶段,但即使我稍后调用sayStage()作为实例方法也无法工作。

我做错了什么?

7 个答案:

答案 0 :(得分:7)

如果TableManager在舞台上,您可以使用this.stage访问舞台。

诀窍是你必须等待将实例添加到舞台上。您可以收听ADDED_TO_STAGE事件,以便了解发生的时间。

package classes {
import flash.events.*;
import flash.display.*;

public class TableManager extends Sprite {
    public function TableManager() {
        this.addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
    }

    private function onAddedToStage(e:Event):void {
        this.removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
        sayStage();
    }

    public function sayStage():void {
        trace(this.stage);
    }
}   
}

答案 1 :(得分:3)

最防守的方式是:

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

private function init(e:Event = null):void {
    if(e != null) this.removeEventListener(Event.ADDED_TO_STAGE, init);
    sayStage();
}

如果初始化时对象已经在舞台上,则立即调用init函数,不带参数。如果不等到它被添加到舞台上。然后,当init函数被调用时,如果它被调用为事件的结果,则分离事件处理程序,然后继续。

答案 2 :(得分:0)

您可以将根影片剪辑(即舞台)的引用传递给自定义类。

e.g。

package classes
{
   import flash.events.*;
   import flash.display.*;

   public class TableManager extends Sprite
   {
       private var _rootMC:MovieClip; 

       public function TableManager(rootMC:MovieClip) {
            _rootMC = rootMC;
            sayStage();
        }
        public function sayStage():void 
        {
            trace(_rootMC.stage);
            trace(_rootMC.stage.stageWidth);
        }
  }   
} 

然后从根时间轴实例化TableManager实例时:

//the keyword 'this' is the root movieclip.
var newTM:TableManager = new TableManager(this);

答案 3 :(得分:0)

只要stage没有添加到显示列表中,

Sprite就会为空 - 它与启动无关。 E.g。

var t:TableManager = new TableManager;
stage.addChild( t ); // or your root class, or any class that's already on the displaylist
trace( t.stage ); // [Stage stage]
t.parent.removeChild( t );
trace( t.stage ); // null

正如@ crooksy88建议的那样,要么将阶段传递给构造函数,要么将其保存为静态某处,比如你的主文档类,以便你可以随处访问它。

答案 4 :(得分:0)

我认为有用的你应该创建阶段的静态引用:

在您的主类中添加行并设置阶段:

public static var stage:Stage;
...
public function Main():void { // constructor
     Main.stage = stage;
     ...

而不是自定义类:

public function sayStage():void 
        {
            trace(Main.stage);
            trace(Main.stage.stageWidth);
        }

答案 5 :(得分:0)

当当前对象(也是一个精灵)已经附加到舞台上时,你可以访问this.stage。

public class TableManager extends Sprite{
    public function TableManager()
    {
    }
    public function sayStage():void 
    {
        trace(stage);
    }
}
TableManager tm=new TableManager();
//tm.sayStage();  // no
addChild(tm);  
tm.sayStage();  // fine
希望这可以帮助

答案 6 :(得分:0)

这是一个非常好的解决方案,你只需要引用你的类中的阶段,你只需将它作为一个简单的对象传递,在这里如何做到

package  {

    public class Eventhndl{

        private var obj:Object;

        public function Eventhndl(objStage:Object):void{
            obj = objStage;

            trace(obj); // now the obj variable is a reference to the stage and you can work as normal you do with stage (addChild, Events Etc..)

        }

}

这是你运行实例的方法,我使用了构造函数方法,但你可以根据需要将其更改为任何函数,并在需要时调用它。

import Eventhndl;

var EH:Eventhndl = new Eventhndl(stage);

以下是一些如何从类

访问舞台的示例

https://stackoverflow.com/a/40691908/1640362

https://stackoverflow.com/a/40691325/1640362