Список отображения (display list) в ActionScript 3
Во флеш-роликах, созданных с помощью ранних версий языка ActionScript (до 3-ей версии) можно было создавать различные типы визуальных объектов: movieclip, графику, текстовые поля, компоненты и т.д. Все эти объекты не были организованы иерархически, a также создавались, удалялись и управлялись различными способами.
Например, movieclip мог быть взят из другого источника, дублирован и затем помещен на сцену в IDE (среда разработки, Flash Professional, например) или создан абсолютно с нуля с помощью ActionScript. C текстовыми полями та же история. Когда дело доходило до растровых объектов (bitmap), видео, компонентов и прочего, то возникало чувство, что все они создавались на разных планетах, а затем помещались во Flash, чтобы как-то работать с другими. Словом, царил некоторый беспорядок, с которым нужно было что-то делать.
На этом уроке Вы узнаете как была решена эта проблема в ActionScript 3, а также:
- Что такое список отображения (display list) в ActionScript 3
- Вспомните, что такое объект отображения (display object)
- По какому принципу устроен список отображения
- Как поместить один объект в другой объект с помощью AS 3
Итак, все эти различия были устранены в ActionScript 3. Практически любой тип объекта, который Вы видите на сцене создается с помощью класса, расширяющего класс DisplayObject
. Другими словами, все эти объекты теперь являются частью одной большой семьи и при их создании, размещении на сцене, удалении и управлении они ведут себя во многом сходным образом.
Cоздание объектов типа sprite
, movieclip
или текстового поля
в ActionScript 3 происходит одинаково. Все они создаются с помощью оператора new
. Например:
var myTextfield:TextField = new TextField(); var myMovieClip:MovieClip = new MovieClip(); var mySprite:Sprite = new Sprite();
Как видите все просто!
В предыдущих уроках было показано, что после создания movieclip
или sprite
можно рисовать непосредственно в них, т.е. наполнять их определенным содержанием. Например:
mySprite.graphics.beginFill(0xff0000); mySprite.graphics.drawCircle(0, 0, 40); mySprite.graphics.endFill();
Но, если делать только так, то Вы мало что сможете увидеть. Поэтому сейчас самое время поговорить о списках отображения (display list).
Что такое список отображения (display list) в ActionScript 3
Для AS3 список отображения (display list) — это новый термин. Но, если у Вас уже есть опыт работы во Flash, то, наверняка, Вы успели с ним познакомиться. Представляйте его в виде дерева визуальных объектов, которые находятся в Вашем флеш-ролике.
В основании этого дерева находится сцена, которая по умолчанию всегда видима. На ней могут находиться несколько movieclip или других визуальных объектов (текстовые поля, геометрические формы, импортированные картинки и т.д.). После добавления их на сцену они тоже становятся видимыми. Внутри этих movieclip могут быть другие movieclip или визуальные объекты, а внутри этих еще и т.д. Это и есть список отображения (display list).
Для примера рассмотрим простую композицию из 4-х объектов: строчки текста и трех фигур.
На самом деле, во Flash, структурно, я организовал все это чуть сложнее, чем мы видим. Каждая фигура помещена в отдельный movieclip со своим именем: star
, rect
и circle
, а они, в свою очередь, находятся внутри movieclip figures
. На рисунке ниже это показано.
Такая внутренняя организация объектов иногда оправдана теми задачами, которые выполняет флеш-ролик. В данном случае — это просто пример для лучшего понимания того, как устроен список отображения.
В ActionScript 3, созданный movieclip, sprite или другой объект отображения НЕ добавляется на сцену автоматически.
В примере, показанном выше (mySprite), у объекта типа sprite нет родителя, т.е. объекта в который он помещается. Мы можем управлять им и без включения в список отображения.
Если сцену во Flash вообразить как реальную, то все эти объекты можно представить себе в виде актеров за кулисами. Их не видно, но они все там, в любую секунду готовые выйти и сорвать аплодисменты.
До настоящего момента мы использовали две метафоры: дерева и сцены. Но для того, чтобы разобраться со списком отображения еще лучше давайте воспользуемся еще одной. О нем также можно думать и в терминах семьи: родитель, потомок, брат/сестра. Когда Вы что-то добавляете в список отображения, то объект, к которому Вы добавляете будет родителем, а сам добавляемый объект — потомком. В таком контектсте название метода addChild()
имеет смысл и ставит все на свои места.
Класс документа (document class) представляет из себя основание дерева или прадедушку всех объектов отображения (display object). Он виден по умолчанию и при работе, практически, над любым флеш-роликом Вы начинаете с того, что добавляете ему потомков. В предыдущих примерах было показано, что для того чтобы сделать sprite или любой другой визульный объект видимым нужно вызвать метод addChild()
и передать ему в виде параметра вновь созданный объект:
var mySprite:Sprite = new Sprite(); mySprite.graphics.beginFill(0xff0000); mySprite.graphics.drawCircle(0, 0, 40); mySprite.graphics.endFill(); addChild(mySprite);
Если Вы хотите увидеть этот код в работе, то поместите его в базовый класс, о котором рассказывалось в предыдущих уроках. Заметьте, что sprite будет помещен в точку 0,0
на осях координат. Чтобы изменить его положение на сцене используйте его свойства x
и y
.
Также заметьте, что пока мы не упоминали глубину расположения объекта. Во многом это автоматический процесс, хотя, конечно же, существуют методы точного добавления объекта на определенный уровень в общей иерархии дерева. Мы вернемся к этому в свое время.
Чтобы удалить объект из списка отображения нужно вызвать метод removeChild()
, которому в виде параметра передается имя объекта.
О чем нужно помнить и знать
Первое. Удаление объекта со сцены НЕ уничтожает его! Он продолжает существовать точно в таком же состоянии, что и до удаления, и будет делать это после добавления его в список отображения снова. Другими словами, если Вы нарисовали или поместили что-то в объект отображения (display object), а затем удалили, то это не значит, что Вам нужно снова рисовать или загружать те же объект(ы) для помещения в список отображения. Они продолжают там находиться.
Второе. Когда Вы повторно помещаете объект в список отображения у Вас есть выбор размещения его на нужную глубину в общей иерархии этого списка. Это значит, что Вы можете сделать для него родительским другой объект. В действительности, Вам даже не нужно удалять его, Вы просто прикрепляете объект к другому родителю и все. У потомка может быть только один родитель, поэтому прикрепление его к другому автоматически удаляет его из предыдущего.
Следующий пример демонстрирует взаимосвязь родитель-потомок:
package { import flash.display.Sprite; import flash.events.MouseEvent; public class Reparenting extends Sprite { private var parent1:Sprite; private var parent2:Sprite; private var ball:Sprite; public function Reparenting() { init(); } private function init():void { parent1 = new Sprite(); addChild(parent1); parent1.graphics.lineStyle(1, 0); parent1.graphics.drawRect(-50, -50, 100, 100); parent1.x = 60; parent1.y = 60; parent2 = new Sprite(); addChild(parent2); parent2.graphics.lineStyle(1, 0); parent2.graphics.drawRect(-50, -50, 100, 100); parent2.x = 170; parent2.y = 60; ball = new Sprite(); parent1.addChild(ball); ball.graphics.beginFill(0xff0000); ball.graphics.drawCircle(0, 0, 40); ball.graphics.endFill(); ball.addEventListener(MouseEvent.CLICK, onBallClick); } public function onBallClick(event:MouseEvent):void { parent2.addChild(ball); } } }
Как видно из кода этот класс создает три объекта типа sprite: parent1
, parent2
и ball
. Sprit'ы-родители непосредственно добавляются на сцену и в них рисуются квадраты. Sprite с именем ball
добавляется в parent1
. В результате он находится на сцене и мы его видим.
Когда мы кликаем мышью на объекте ball
, он добавляется к parent2
. Заметьте, что мы перемещаем его не с помощью свойств х
и у
, а помещая его внутрь другого родителя, а у того, как Вы понимаете, другое местоположение. Также заметьте, что динамически нарисованный круг продолжает существовать не смотря на то, что был удален и добавлен снова.
Если немного усовершенствовать код, то можно заставить красный мячик прыгать туда-сюда из одного квадрата в другой, кликая на нем мышью. Как это сделать попробуйте догадаться сами.
Подсказка: удалив один слушатель события для oбъекта Вы можете назначить ему другой. Если самостоятельно найдете решение, то поделитесь им в комментариях. Напишите и оно будет опубликовано.
Итоги
В этом уроке Вы узнали о том, что такое список отображения (display list) и для чего он нужен. Это важный момент. В своей дальнейшей практике программиста Вы будете сталкиваться с этим постоянно, поэтому должны четко понимать как с этим работать. Чтобы закрепить изученный материал ответьте на несколько вопросов.
Контрольные вопросы по материалу урока
- В чем разница между списком отображения и объектом отображения в AS3?
- Как поместить один объект в другой?
- Что происходит с объектом после удаления его со сцены?
- Нужно ли создавать заново или импортировать объект, если Вы его удалили, а затем снова хотите поместить на сцену?
Жду вопросов. Задавайте в комментариях. Постараюсь ответить на все.