【问题标题】:Adding to Stage in ActionScript 3 from a .as file从 .as 文件添加到 ActionScript 3 中的舞台
【发布时间】:2013-01-20 12:09:46
【问题描述】:

注意:是的,我知道以前有人问过类似的问题。但是,在遵循此类问题的答案后,我仍然陷入困境,无法找到解决问题的方法。

我遇到了一个问题,需要将 DisplayObjects 添加到 Flash 阶段。由于我必须显示几个不同类的元素,因此我决定创建一个类来充当 .as 文件和名为“Displayer”的addChild 函数之间的中介,如下所示:

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

我编译它,出现一个我不明白的问题:错误 #2012:无法实例化 Stage 类。显然,此代码中的某些内容要么丢失,要么不合适,但由于它非常简单,我看不出问题出在哪里。我敢肯定这不是很复杂,我可能只是需要一个局外人的观点。

【问题讨论】:

    标签: actionscript-3 sprite stage addchild displayobject


    【解决方案1】:

    Stage 对象不可全局访问。您需要通过 DisplayObject 实例的 stage 属性来访问它。

    参考以下文档。

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

    【讨论】:

    • 这似乎是一个有趣的解决方案,但是为了添加和删除EventListeners,我不需要扩展EventDispatcher吗?还没有尝试过,所以也许我错了。
    • 您不需要扩展 EventDispatcher。解释上面的代码,其实和FlashFlash builder的概念阶段略有不同。我们不关心Flash 的阶段。因为基本上是在屏幕上。舞台总是闪烁舞台自动先到,因为没有问题。但是,在 Flash builder 中必须调用 First Stage,然后调用 Main Class 构造函数。但始终没有采取行动这一步。通常建议始终继续使用上面的代码。如果您与遇到运行时错误相关联,您将能够理解我的评论。
    【解决方案2】:

    您没有实例化 Stage 类,如错误所示。就像你不能实例化 DisplayObject 类一样(这就是你必须扩展 Sprite 的原因)。

    基本上,您有两种选择:

    1) 您从 DisplayObjectContainer 实例添加子级。

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

    您可以从已添加到全局舞台的 DisplayObjectContainer 对象运行它。每个项目中只有一个stage,即使你嵌入了SWF,SWF的stage属性实际上是顶级应用程序的stage属性。因此,如果您将这个 Displayer 实例嵌套在一个嵌套在主应用程序中创建的另一个类中的类中,则必须在每个类中运行“addChild”以显示 Displayer

    2) 你作弊。不建议这样做,完全。基本上,您在实例化Displayer 类时传入一个对象的舞台对象。

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

    这是一种非常适合将单例添加到舞台的方法(除非没有单例的构造函数)。我在圣诞节前创建了一个分析器,它是一个 Singleton(后来发现 Scout,该死的),它使用这种方法在适当的时候向舞台添加东西。

    同样,不建议在这种情况下使用第二个选项,但这是可能的。

    顺便说一句,您应该永远不要将内容直接添加到Stage,除非有明确的原因(例如弹出窗口)。您应该遵循显示列表方法,其中 DisplayObjectContainer 添加另一个 DisplayObject 或 DisplayObject 容器作为子容器,依此类推,以使它们都连接到 TopLevelApplication。

    【讨论】:

      【解决方案3】:

      好的,我认为实例化舞台类是行不通的,因为 as3 文档说:“舞台对象不可全局访问。您需要通过 DisplayObject 实例的舞台属性访问它。”

      您应该将 Stage 对象的引用传递给您的 Displayer 类,并且您可以通过显示对象实例获取对舞台对象的引用,正如文档所说的那样。

      所以构造函数现在可能看起来像:

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

      假设实例化您的 Displayer 的对象是舞台的子对象,您可以通过以下方式实例化 Displayer

      displayer = new Displayer( stage );
      

      如果您使用这种方法,则不需要 Displayer 类扩展任何内容或添加到舞台(顺便说一句,在 bitmapdata.com 的方法中这是必需的)。

      【讨论】:

      • 没有语法错误。将创建相同的实例。只有 Stage 类类似于不能实例化的 Singleton 模式。不是问题的语法。
      【解决方案4】:

      总是有一个简单的解决方案。如果您需要将一个子元素添加到您的类中的阶段,您可以将阶段作为对象传递到您的类中并将子元素添加到其中,我这样做是为了添加一个像这样进入我的舞台。

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

      只有带有cmets的东西很重要,你可以把这个文件保存为ImageLoader.as,然后导入并像这样使用它。

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

      就这么简单。我认为这就是您要搜索的内容...祝您好运。 (您可以传递任何容器或同级容器 this 或 this.stage 并不重要,您的孩子将成为其中的一部分。

      【讨论】:

        猜你喜欢
        • 2011-08-03
        • 2013-03-21
        • 2011-09-05
        • 1970-01-01
        • 1970-01-01
        • 2015-07-11
        • 1970-01-01
        • 2011-01-07
        • 2013-09-07
        相关资源
        最近更新 更多