2

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

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

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

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

我究竟做错了什么?

4

7 回答 7

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);
    }
}   
}
于 2011-12-29T19:24:17.203 回答
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函数被调用时,如果它是作为事件的结果被调用的,则分离事件处理程序并继续前进。

于 2011-12-30T15:59:47.997 回答
0

stage只要Sprite还没有添加到显示列表中,它将为空 - 这与启动无关。例如

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 建议的那样,要么将阶段传递给构造函数,要么将其作为静态保存在某个地方,比如您的主文档类,以便您可以在任何地方访问它。

于 2011-12-29T19:19:28.007 回答
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);
        }
于 2011-12-29T20:51:19.950 回答
0

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

例如

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);
于 2011-12-29T19:12:41.180 回答
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

希望这会有所帮助

于 2011-12-30T06:36:41.323 回答
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

于 2016-11-19T10:51:12.653 回答