Опубликован: 23.12.2005 | Уровень: специалист | Доступ: платный | ВУЗ: Московский физико-технический институт
Лекция 3:

Клипы и ролики. Специальные возможности языка

Иерархия клипов, способы ее модификации

В этой главе мы будем говорить, в основном, о создании клипов "вручную", хотя несколько слов будет сказано и о программном дублировании имеющихся клипов - весьма полезной возможности, с которой имеет смысл познакомиться поскорее.

Напомним еще раз, как быстрее всего сделать произвольный клип и правильно написать внутри него код. Итак, выбираете инструмент для рисования эллипсов или прямоугольников. Рисуете. Выделяете нарисованный объект или несколько объектов (кстати, имейте в виду, что граница и заливка прямоугольника или эллипса - это разные графические примитивы, причем граница может состоять из нескольких отдельных отрезков). Выбираете из контекстного (по правой кнопке мыши) меню пункт Convert to Symbol (появится диалог создания нового символа, с которым вы уже знакомы). И в правой части панели Properties вводите имя экземпляра.

Дальше вас подстерегает следующая "ловушка". Если вы прямо сейчас приметесь писать в панели Actions код, то, скорее всего, получите не то, что хотели. Дело в том, что после всех только что произведенных действий у вас выделен экземпляр вновь созданного символа. И код, вводимый в панели Actions, будет относиться к этому конкретному экземпляру (и может представлять собой только описание его реакции на события ). Соответственно, в выпадающем списке, расположенном в верхней части панели Actions, вы увидите надпись вроде " Actions for clip1 (Symbol 1) ". Здесь Symbol 1 - это имя символа, а clip1 - имя экземпляра. А вы, скорее всего, хотите написать код, относящийся либо к корневому клипу, либо к вновь созданному символу. Чтобы выполнить первую задачу, еще раз выделите в линейке времени нужный кадр, даже если он и выглядит уже выделенным. Вы увидите (пример приведен для случая, когда вы редактируете первый кадр ), что надпись в верхней части панели Actions заменится на следующую: Actions for Frame 1 of Layer Name Layer 1 (то есть код относится к первому кадру и к слою по имени Layer 1 ). Чтобы выполнить вторую задачу, вам нужно будет либо открыть панель Library и дважды щелкнуть на нужном символе, либо выделить экземпляр на сцене и в контекстном меню выбрать Edit или Edit in Place (во втором случае вы по-прежнему редактируете именно символ, но видите, хотя и не можете редактировать, все, что расположено вокруг выбранного экземпляра). Надпись в верхней части панели Actions, опять-таки, будет иметь вид: Actions for Frame 1 of Layer Name Layer 1 (в случае, если вы выделяете первый кадр слоя Layer 1, что и происходит само собой по умолчанию при первом редактировании символа). То есть, никакой разницы с надписью, которая у нас была при аналогичном редактировании корневого клипа, нет. Как же быстро определить, какой клип мы редактируем? Взглянуть на строку непосредственно под линейкой времени. В последнем случае там написано Scene 1 Symbol 1, а при редактировании корневого клипа было написано просто Scene 1. Понятно, что в случаях клипов большой вложенности (о чем мы сейчас поговорим) в этой строке будет приведен более длинный путь от вершины до листа дерева владения. А о том, что означает надпись Scene 1, будет сказано в подразделе данного параграфа, посвященном работе со сценами.

Отношения владения для клипов и объектов

Под отношением владения для клипов мы здесь понимаем весьма простую вещь: "кто в кого вложен". Сделать вложенные друг в друга клипы несложно (а, зачастую, это совершенно необходимо). Мы уже говорили, что делается это следующим образом: экземпляр одного клипа вкладывается в символ другого (что полностью аналогично семантике владения в объектном языке). Впрочем, если говорить более подробно, семантика владения может быть устроена по-разному: с помощью ссылок или с помощью хранения одного объекта внутри другого. Скажем, для объектов (не встроенных типов) языка Java мы имеем вариант со ссылками. Для С++ возможны оба варианта. Наконец, можно представить себе и некий промежуточный вариант: некоторая часть данных, относящихся ко вложенному объекту, действительно явным образом хранится в объекте-владельце, в то время как другая (более объемная) часть данных доступна по ссылке.

В случае Флэш МХ мы как раз можем наблюдать либо вариант со ссылками, либо промежуточный вариант (а разобравшись в деталях, мы поймем, что в основном имеем дело именно с промежуточным вариантом; вариант со ссылками - всего лишь его крайний случай).

Давайте же посмотрим, какая именно информация о вложенном экземпляре хранится в символе-владельце (а когда будет создан экземпляр этого символа - то и в экземпляре-владельце). Создадим в новом документе два символа: один с изображением круга, а другой - квадрата. Затем вытащим на сцену три экземпляра круга и три - квадрата. В панели Properties поменяем двум кругам и двум квадратам ширину и высоту - так, чтобы они выглядели вытянутыми по горизонтали или по вертикали. Еще одному кругу и одному квадрату поменяем прозрачность (для этого в правой части панели Properties в выпадающем списке Colors выберем пункт Alpha и в появившемся рядом поле установим значение в 30%). А теперь - самое интересное. После всех этих манипуляций мы можем щелкнуть правой кнопкой мыши на вытянутом полупрозрачном круге, выбрать пункт контекстного меню Swap Symbol (четвертый снизу), и на экране появится диалог подмены символа.


В этом диалоге будут перечислены все символы, имеющиеся на данный момент в библиотеке вашего ролика. Если теперь вы в этом диалоге вместо круга выберете квадрат и нажмете OK, то увидите, что, действительно, на месте круга на сцене теперь находится квадрат. Однако настройки, которые вы устанавливали для круга, никуда не пропали! Так что "квадрат" теперь является, скорее, прямоугольником, поскольку круг ранее тоже был вытянут и превращен в эллипс. И настройки прозрачности тоже никуда не делись (а если вы их измените и поменяете символ обратно на круг - вы увидите и в круге те же изменения). Подчеркнем, что настройки относятся именно к экземпляру, поскольку все остальные круги и квадраты на сцене не меняются, когда вы растягиваете один из них. (Но они изменятся, если вы отредактируете символ. Для чего, напомним, надо просто дважды щелкнуть на значке символа в библиотеке или же, щелкнув правой кнопкой мыши по экземпляру, выбрать из контекстного меню Edit или Edit in place. Не забудьте, как вернуться назад - для этого служит полоса с иерархией клипов. Если что, посмотрите, как это делается, в первой лекции.)

Таким образом, отношения владения между клипами во Флэш МХ хорошо описываются следующей схемой.


Для сравнения здесь изображено владение объектов во Флэш МХ, с которым мы подробнее познакомимся позднее. Вы можете убедиться, что нижняя строчка схемы вполне отображает картину, с которой мы только что познакомились. В самом деле, в экземпляре-владельце хранится вложенный экземпляр, содержащий в себе настройки размеров, прозрачности и местоположения. А кроме того, содержащий нечто вроде ссылки на символ, в котором уже хранится основная информация о том, что собой данный экземпляр представляет. Но это именно ссылка, поскольку при необходимости она может быть перенаправлена и указывать на другой символ.

Почему мы уделяем столько внимания отношению владения? А потому, что с ним мы будем напрямую иметь дело из ActionScript и нам важно показать, в каком именно смысле к клипам можно относиться как к объектам языка ActionScript. Мы уже кратко упоминали об этом в первой главе, но повторим еще раз, поскольку это весьма важно: вы не можете обратиться к символу из ActionScript. По крайней мере, до тех пор, пока вы не связываете с ним класс при помощи механизма регистрации классов (речь об этом пойдет в девятой главе). А вот к экземпляру обратиться ничего не стоит; только для этого вы должны присвоить ему определенное имя. Делается это, как обычно при работе с экземплярами, в панели Properties. В левой ее части, над полями ввода, определяющими размеры и месторасположение экземпляра, имеется поле, куда вводится имя (кстати, справа от него находится кнопка, вызывающая диалог подмены символа). Имя должно удовлетворять требованиям, предъявляемым к идентификатору (иначе вы не сможете удобным образом использовать его из ActionScript). Далее, если вы присвоите вложенному экземпляру имя slave, а затем экземпляру-владельцу - имя master, то к вложенному экземпляру вы сможете обращаться вот так: master.slave. Если вы вытаскиваете экземпляр на основную сцену, он автоматически попадает в корневой экземпляр по имени _root (так что если master лежит на основной сцене, то обратиться к нему можно так: _root.master ). При этом, если вы пишете код в кадре определенного клипа, по умолчанию все объекты, переменные и экземпляры клипов, к которым вы обращаетесь, считаются лежащими именно в этом клипе. В нашем примере, если вы пишете код в кадре основной сцены (то есть в корневом клипе ), обращаться к вышеназванным клипам можно master и master.slave. А если код пишется в каком-то постороннем клипе, вам придется написать _root.master и _root.master.slave.

Чуть выше мы упомянули, что в клипе могут лежать объекты и переменные ActionScript. Что это означает? А то, что экземпляр клипа является объектом в смысле ActionScript и, следовательно, к нему может быть добавлено в качестве полей любое количество ссылок на примитивные или не примитивные объекты ActionScript (в том числе другие клипы ). Поскольку объектом является именно экземпляр, то все упомянутые поля создаются именно в нем. С другой стороны, что означает код, который мы пишем в кадрах линейки времени? Ведь это мы делаем при редактировании символа? Верно, однако выполняется этот код в каждом экземпляре отдельно; причем, если экземпляр существует ограниченное число кадров (в линейке времени владельца), то именно такое число кадров (и, связанный именно с этими кадрами код) будет выполнено во время существования экземпляра. После чего он будет выгружен. Этот код может заводить ссылки на объекты (примитивные или нет) - они размещаются в экземпляре, выполняющем код (если явным образом не указать иного; например a = 5; означает создание переменной в текущем клипе, а _root.a = 5; - в корневом клипе. Кстати, здесь и в дальнейшем мы называем клипами как экземпляры, так и символы; но чаще - экземпляры. Уточнять, что имеется в виду, мы будем только в тех случаях, когда смысл не понятен из контекста).

К настоящему моменту должно вполне проясниться следующее: почему на схеме владения владельцем вложенного клипа назван экземпляр, а не символ клипа -владельца? Ведь при редактировании ролика мы вкладываем экземпляр "подчиненного" клипа внутрь символа владельца? Дело в том, что обратившись из ActionScript к экземпляру-владельцу, а через него - к вложенному экземпляру, мы можем изменить какие-то параметры вложенного клипа (например, строчка кода наподобие master.slave._width = 50; меняет ширину клипа slave ). При этом изменение коснется именно экземпляра master. Если, к примеру, существует еще один экземпляр того же символа (под названием, скажем, master1 ), то в его вложенном клипе master1.slave все останется как было. То есть при создании экземпляра класса-владельца создаются новые экземпляры всех клипов, вложенных в него.

Все это вполне соответствует тому, что мы можем сконструировать класс, в поле которого будет храниться некоторый вложенный объект (заметьте, что в этой фразе мы применили вариант семантики владения, соответствующей C++, а не Java или ActionScript: в поле хранится объект, а не ссылка на него). Чтобы сделать аналогию с клипами более точной, нам следовало бы сказать так: в поле хранится все-таки ссылка, но при создании нового объекта класса-владельца создается и новый объект, находящийся во владении. Итак, мы конструируем класс такой, что в некотором его поле хранится ссылка на (всякий раз вновь создаваемый) объект, находящийся во владении. Мы даже можем установить этому объекту параметры по умолчанию. Однако, создав объект класса-владельца, мы сможем затем получить доступ к вложенному объекту и его изменить. И эти изменения коснутся только того вложенного объекта, которым владеет именно данный конкретный объект-владелец. Таким образом, реальным владельцем является все-таки объект, а не класс (в случае клипов - экземпляр, а не символ).

Итак, мы увидели весьма глубокую аналогию между тем, как клипы владеют экземплярами других клипов, и тем, как объекты владеют другими объектами. Вспомним теперь, что еще мы производили некоторую очень странную операцию: замену символа для данного экземпляра. Взглянем еще раз на рисунок, схематически описывающий владение во Флэш МХ, и спросим себя: означает ли выявленная аналогия то, что мы в состоянии заменить объекту базовый класс? Как это ни удивительно, да, означает! Подробнее мы познакомимся с такими фокусами в лекции 7 и, особенно, 8 (где на этом принципе базируется эмуляция множественного наследования).

алексеи федорович
алексеи федорович
Беларусь, рогачёв
Тамара Ионова
Тамара Ионова
Россия, Нижний Новгород, НГПУ, 2009