Показать сообщение отдельно
Старый 01.11.2006, 13:56
MerlinTwi вне форума Посмотреть профиль Отправить личное сообщение для MerlinTwi Посетить домашнюю страницу MerlinTwi Найти все сообщения от MerlinTwi
  № 78  
Ответить с цитированием
MerlinTwi
 
Аватар для MerlinTwi

Регистрация: Oct 2003
Адрес: Москва
Сообщений: 328
По умолчанию 84. Доступ к stage и root

Stage (сцена) – это фактически первый контейнер в который загружаются все остальные отображаемые объекты, включая root. Stage может быть только один, а вот root может быть сколько угодно, по одному на каждую загруженную внешнюю флешку.
Все отображаемые объекты (flash.display.DisplayObject) имеют свойства stage и root. До тех пор, пока объект не добавлен на сцену (stage) эти свойства равны null. Свойство stage, когда доступно, всегда ссылается на объект stage. А вот свойство root в разный случаях содержит разные ссылки:
  • Для stage, свойство root всегда ссылается на stage
  • Для всех объектов, расположенных на главной timeline, свойство root ссылается на главную timeline
  • Если объект добавлен прямо на сцену (stage) из любой timeline, свойство root для него и его детей будет ссылаться на stage
  • Для объектов расположенных в подгруженном внешнем SWF-файле, свойство root ссылается на главную timeline этого SWF-файла
  • Для загруженных картинок, свойство root ссылается на экземпляр класса Bitmap, куда была загружена картинка
Помните, что только после добавления на сцену, или к любому другому объекту уже добавленному на сцену, есть доступ к свойствам stage и root. Это серьезное отличие от ActionScript 1 и 2 и на то есть две причины:
  1. В AS1 и 2 мувиклипы в момент своего создания уже были добавлены на сцену. В AS3 это не так. Фактически только document class (см. предыдущий совет) изначально расположен на stage (во Flash 9 еще и объекты, расположенные на timeline в IDE до публикации).
  2. В AS1 и 2 все скрипты и классы были определены внутри timeline или мувиклипов, как результат отовсюду был доступ к свойству _root.В AS3 классы не привязаны к timeline и могут не иметь доступа к root или stage.
Это сильно ограничивает наш доступ к stage или root в скриптах. К примеру, не отображаемый класс в AS3 вообще не может получить доступ к stage или root, только если получит ссылку извне.
Код:
package {
    
    import flash.display.Stage;

    public class CustomObject {
    
        private var stage:Stage;
    
        public function CustomObject(stageRef:Stage) {
        
            // Ссылку на stage нужно передавать как параметр конструктора
            stage = stageRef;
        }
    }
}
Отображаемые объекты в момент создания в конструкторе не имеют доступа к stage и root (если только они не были расположены на timeline до компиляции)
Код:
package {
    
    import flash.display.Sprite;
    import flash.events.Event;

    public class CustomDisplayObject extends Sprite {
    
        public function CustomObject() {
        
            // stage недоступен до тех пор, 
            // пока объект не будет добавлен на сцену
            trace(stage); // null
        }
    }
}
Это создает определенные трудности. Нужно добавлять дополнительный обработчик события добавления на сцену (ADDED_TO_STAGE), из которого уже вызывать функцию init для совершения необходимых действий.
Другой вариант решения создать статичное свойство в каком-либо классе, в которое прописать ссылку на root или stage и уже к этому свойству обращаться из любого места. Лучше всего для этого подойдет document class, т.к. он изначально имеет доступ к stage и сам является root.
Пример:
Код:
package {
    
    import flash.display.DisplayObject;
    import flash.display.MovieClip;
    import flash.display.Stage;
    
    public class TopLevel extends MovieClip {
        
        public static var stage:Stage;
        public static var root:DisplayObject;
            
        public function TopLevel() {
            TopLevel.stage = this.stage;
            TopLevel.root = this;
        }
    }
}
Доступ к stage из неотображаемого класса:
Код:
package {
        
    public class RandomClass {
            
        public function RandomClass() {
            trace(TopLevel.stage); // [object Stage]
        }
    }
}
В идеале стоит писать код так, чтобы не было необходимости в создании классов подобных TopLevel и жесткой привязке к нему. Особенно если в разработке участвуют несколько программистов. Определять доступность stage лучше по событию.
__________________
Создатель: Бойцовский клуб | TimeZero | Sky2Fly
Я возьму сам.