AS3 не может получить доступ к сцене из пользовательского класса - PullRequest
2 голосов
/ 29 декабря 2011

Как я могу получить доступ к сцене и особенно к ширине и положению мыши во Flash-ролике из пользовательского класса?

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

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

Это вернет только ноль.Я знаю, что объекты DisplayObject не имеют никакого этапа, пока они не были инициированы, поэтому вы не можете получить доступ к этапу в своем конструкторе, но даже если позже я вызову sayStage () как метод экземпляра, он не будет работать.

Что я делаю не так?

Ответы [ 7 ]

7 голосов
/ 29 декабря 2011

Если 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);
    }
}   
}
3 голосов
/ 30 декабря 2011

Самый защитный способ написать это:

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, если она была вызвана как результат события, тогда отсоедините обработчик события и двигайтесь дальше.

0 голосов
/ 19 ноября 2016

вот довольно хорошее решение, вам нужно только сослаться на сцену внутри вашего класса, вы просто передаете его как простой объект, вот как это сделать

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

0 голосов
/ 30 декабря 2011

вы можете получить доступ к этой сцене, когда текущий объект (также спрайт) уже присоединен к сцене.

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

надеюсь, что это может помочь

0 голосов
/ 30 декабря 2011

я думаю, что полезно для Вас создать статическую ссылку на stage:

в вашем основном классе добавить строку и установить stage:

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

, а затем в пользовательском классе:

public function sayStage():void 
        {
            trace(Main.stage);
            trace(Main.stage.stageWidth);
        }
0 голосов
/ 29 декабря 2011

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, либо перейдите на этапе к конструктору, либо сохраните его как статическое где-нибудь, скажем, ваш основной класс документа, чтобы вы могли получить к нему доступ повсюду.

0 голосов
/ 29 декабря 2011

Вы можете передать ссылку на корневой мувиклип (т.е. сцену) в свой пользовательский класс.

, например

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