AS3 - Почему я не могу использовать сцену вне моего корневого класса? - PullRequest
1 голос
/ 22 августа 2009

У меня есть два следующих класса:

package 
{
    import flash.display.Sprite;
    import flash.events.Event;

    public class Main extends Sprite
    {

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

        private function init(e:Event = null):void 
        {   
            removeEventListener(Event.ADDED_TO_STAGE, init);
            // entry point
            var test:NewClass = new NewClass(); 
        }

    }

}

И

package  
{
    import flash.display.Sprite;

    public class NewClass extends Sprite
    {

        public function NewClass() 
        {
            trace(stage.width);
        }

    }

}

Я получаю следующую ошибку:

TypeError: Ошибка # 1009: Невозможно получить доступ к свойству или методу пустой ссылки на объект. в NewClass () [C: \ Documents and Settings \ Roma \ poo \ src \ NewClass.as: 10] в Main / init () [C: \ Documents and Settings \ Roma \ poo \ src \ Main.as: 23] at Main () [C: \ Documents and Settings \ Roma \ poo \ src \ Main.as: 15]

Почему ???

Ответы [ 2 ]

8 голосов
/ 22 августа 2009

ага, разработчик флэш-памяти ...: D

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

измените свой класс следующим образом:

package {
    import flash.display.Sprite;
    import flash.events.Event;
    public class NewClass extends Sprite {
        public function NewClass():void {
                if (stage) init();
                else addEventListener(Event.ADDED_TO_STAGE, init);
        }
        private function init(e:Event = null):void {       
                removeEventListener(Event.ADDED_TO_STAGE, init);
                trace(stage.width);//you may want to use stage.stageWidth actually
        }
    }
}

и Main :: init следующим образом:

    private function init(e:Event = null):void {       
            removeEventListener(Event.ADDED_TO_STAGE, init);
            var test:NewClass = new NewClass();     
            this.addChild(test);
    }

о, и вы можете изменить Coding Style Type с BraceAfterLine на BraceOnLine в Tools > Program Settings > FlashDevelop > Indenting, на случай, если вы склонны ...;)


редактировать: если вы хотите получить доступ к сцене, в рамках DisplayObject, вы должны быть уверены, что сцена доступна для нее ... если вы хотите получить доступ к сцене как можно скорее, то вам понадобится хитрость при условии ... но если вы, например, получаете доступ к сцене в обработчике кликов, это автоматически подразумевает, что DisplayObject находится в списке отображения ... иначе щелкнуть нельзя ...

небольшое замечание: я не думаю, что особенно разумно получить доступ к сцене из любого места ... когда дело доходит до отображения, иерархия вашего приложения должна следовать иерархии списка отображения, то есть доступ идет от корня вниз по ветви, а не наоборот ... это важно для достижения возможности повторного использования ...


Greetz

back2dos

0 голосов
/ 23 августа 2009

Как правильно говорит back2dos, только элементы из списка отображения имеют действительную ссылку на сцену. Поскольку экземпляр NewClass является просто временной переменной в методе init вашего экземпляра Main, и вам еще не нужно addChild поместить его в список отображения, значение его свойства stage будет нулевым , Примечание: только дети родителей, которые также находятся в списке отображения, получат действительную ссылку на сцену.

Если вам нужна ссылка на этап в классе, который не будет добавлен в список отображения, вам нужно будет передать этап в экземпляр этого класса. В отличие от AS2 нет общедоступной ссылки на стадию (т.е. _root и _level0 устарели)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...