Macromedia Flash Professional 8. Графика и анимация

Дронов В. А.

Часть IV

Интерактивность

 

 

Глава 18

Основы программирования во Flash

 

Вот мы и добрались до программирования. Путь был долог и тяжел, но мы его преодолели, расправившись по дороге со статичной и анимированной графикой, импортированным видео и звуком. Перед нами высятся неприступные стены и грозные башни крепости под названием ActionScript. Могучие воины-действия натачивают мечи, а грозные маги-объекты извлекают из тайников древние артефакты… Однако пора заканчивать со стратегическими играми!

В четвертой части книги мы научимся создавать сценарии — небольшие программы, являющиеся неотъемлемой частью документа Flash и описывающие поведение какого-либо элемента изображения Flash или самого этого изображения. Мы научимся также привязывать сценарии к кадрам анимации, клипам и кнопкам и, разумеется, научимся создавать сами кнопки.

Сценарии Flash пишутся на языке программирования ActionScript, разработанном в фирме Macromedia специально для пакета Macromedia Flash. Этот язык очень прост в освоении и, вместе с тем, имеет достаточно средств для того, чтобы добавить фильмам Flash "жизни". На нем можно даже писать настоящие программы — так называемые Flash-приложения. И те из вас, кто продолжит изучение Flash 8 по его интерактивной справке или другим книгам, смогут стать настоящими Flash-программистами.

С помощью сценариев с фильмом и его элементами можно сделать все, что душе угодно. Например, можно остановить воспроизведение на каком-то кадре, а продолжить только после нажатия кнопки. Можно заставить фрагмент изображения двигаться по рабочему листу, не пользуясь стандартными средствами создания анимации, описанными в части IIIэтой книги. Можно заставить Flash открыть при щелчке на кнопке какую-либо Web-страницу. Можно… Да много чего можно сделать с помощью сценариев!

Начнем мы, как уже повелось, с теории. Нам нужно поближе познакомиться со сценариями и выяснить, как (или, точнее — когда) они работают. А заодно познакомиться с понятием события.

 

Как работают сценарии. События

Любой сценарий, который мы создаем в документе Flash, должен быть привязан к какому-то его элементу. Привязать сценарий во Flash можно:

□ к кадру анимации (внешней или внутренней, принадлежащей какому-либо образцу);

□ к клипу (в смысле — к экземпляру образца-клипа). О клипах и их создании см. главу 8;

□ к кнопке (к экземпляру образца-кнопки). О кнопках будет рассказано далее в этой главе.

Чтобы привязать к элементу изображения, нужно сначала выделить этот элемент. Далее мы просто открываем панель Actions и пишем в ней текст (или, как говорят профессиональные программисты, — код) сценария. Так, если был выделен кадр анимации, то написанный в панели Actions сценарий будет привязан к нему. Если же был выделен элемент, к которому нельзя привязать сценарий (например, "обычная" графика или экземпляр графического образца), панель Action будет недоступна.

Все сценарии Flash, привязанные к кнопке или клипу, выполняются в ответ на какое-либо событие, произошедшее в фильме Flash или операционной системе. Таким событием может быть щелчок на кнопке, "касание" мышью клипа и пр.; набор событий, к которым можно привязать сценарий, весьма обширен. Сценарии, привязанные к событиям, называются также обработчиками событий.

Сценарии же, привязанные к кадру анимации, выполняются при воспроизведении данного кадра. Поэтому они называются просто сценариями.

А теперь давайте выясним, как написать сценарий и привязать его к нужному событию нужного элемента документа Flash. Первый наш сценарий будет привязан к кадру фильма; заодно мы познакомимся с панелью Actions и научимся с ней работать. А потом перейдем к более сложным случаям — привязке сценариев к клипам и кнопкам. Ну и, конечно, узнаем, как создаются эти самые кнопки.

 

Привязка сценариев к кадрам анимации

 

Привязать сценарий к кадру проще простого. Откроем фильм, демонстрирующий деление клетки, который мы создали в главе 11, и выделим второй ключевой кадр второй сцены. Мы привяжем к этому кадру сценарий, запускающий воспроизведение данной сцены с первого кадра, и таким образом зациклим наш фильм.

На заметку

При воспроизведении фильма в отдельном окне Flash по умолчанию его зацикливает. Но фильм, сохраненный в формате Shockwave/Flash, может и не быть зациклен. Поэтому для зацикливания фильмов часто применяют сценарии, наподобие того, какой мы сейчас напишем.

Этот небольшой сценарий будет выглядеть вот так:

gotoAndPlay(1);

Здесь gotoAndPlay — особая команда языка ActionScript, выполняющая переход на кадр текущей сцены, номер которого указан в скобках, и запускающая воспроизведение фильма уже с этого кадра. В нашем случае она выполняет переход на кадр № 1.

Команды такого типа воздействуют на фильм Flash или часть изображения на рабочем листе, причем результат этого воздействия проявляется немедленно. В терминологии Flash они называются действиями (actions). А номер кадра, указанный в скобках, называется параметром.

Очень часто действия принимают не один параметр, а несколько. В этом случае значения этих параметров разделяются запятыми.

В совокупности действие gotoAndPlay с параметром составляют выражение — минимальную единицу сценария ActionScript. Символ "точка с запятой" служит признаком конца выражения ActionScript и является обязательным.

Наш первый сценарий очень короток — в нем всего одно выражение. Сложные же сценарии могут содержать тысячи, а то и десятки тысяч выражений.

 

Знакомство с панелью Actions

Теперь нам осталось привязать наш сценарий к кадру. А значит, нам понадобится панель Actions. Чтобы вывести ее на экран, нужно:

□ либо включить пункт-выключатель Actions меню Window;

□ нажать клавишу ;

□ нажать кнопку, расположенную в правой части панели Properties:

Панель Actions показана на рис. 18.1. Она разделена на три части, которые мы сейчас рассмотрим.

В левой части панели Actions находится большой иерархический список доступных в языке ActionScript команд (действий, операторов, методов и пр.; с ними мы познакомимся в главе 19), которые мы можем использовать в своих сценариях. Таких команд очень много — так много, что они разбиты на несколько групп, и каждой такой группе соответствует определенное "дерево" иерархического списка. Если в сценарии нельзя использовать какую-либо команду, соответствующий ей пункт списка показан серым цветом и недоступен для выбора.

В данный момент панель Actions показывает все сценарии, привязанные к тому элементу фильма (кадру, кнопке или клипу), который сейчас выделен. Чтобы выяснить, какие сценарии привязаны к другому элементу фильма, достаточно просто выделить его на рабочем листе (для кнопки или клипа) или временной шкале (для кадра).

Есть и другой способ "путешествовать" по элементам фильма и привязанным к ним сценариям — использование другого иерархического списка, расположенного в левом нижнем углу панели Actions. Этот список представляет все элементы страницы, к которым уже были привязаны сценарии. Чтобы просмотреть код сценария, привязанный к тому или иному элементу, достаточно просто выбрать в списке соответствующий ему пункт.

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

Начинающие программисты смогут получить более подробную информацию о командах языка ActionScript. Для этого им сначала нужно будет либо выбрать соответствующий пункт в иерархическом списке доступных команд (верхняя левая часть панели Actions), либо в области редактирования кода установить на нужную команду курсор мыши. После этого им останется нажать кнопку, расположенную в правом верхнем углу панели Actions:

Или выбрать в дополнительном меню панели пункт Help. Также они могут щелкнуть по нужному пункту иерархического списка команд правой кнопкой мыши и выбрать в появившемся на экране контекстном меню пункт View Help. После этого на экране появится панель Help (см. рис. 2.24) с текстом справки по выбранной команде.

Левая (оба иерархических списка) и правая (область редактирования кода) части панели Actions отделены друг от друга тонкой серой линией. Мы можем перетаскивать ее мышью, меняя относительные размеры частей. Можно также дважды щелкнуть на этой линии или нажать расположенную на ней небольшую кнопку с изображением черной стрелки, чтобы убрать с экрана оба списка. Повторный щелчок на этой кнопке восстановит левую часть панели.

Кроме того, толстой серой линией отделены друг от друга оба иерархических списка, расположенные в левой части панели. При двойном щелчке на линии или при нажатии расположенной на ней кнопки с изображением стрелки будет убран верхний список (список доступных команд).

 

Написание сценария

Итак, с панелью Actions мы вкратце познакомились. Конечно, полностью ее возможности (кстати, весьма широкие) мы не рассмотрели, но сейчас нам важнее написать наш первый сценарий, чем выяснять, чем богата эта панель. Позже мы займемся ей более подробно.

Выше уже говорилось, что для перемещения бегунка на другой кадр нужно использовать действие gotoAndPiay. Все действия находятся в "дереве" Global Functions иерархического списка доступных команд (см. рис. 18.1). В этом "дереве" нам нужно раскрыть "ветвь" Timeline Control (в ней содержатся действия, управляющие воспроизведением анимации) и найти пункт gotoAndPiay, "отвечающий" за одноименное действие. Теперь нам нужно добавить это действие в код нашего сценария, который пока что пуст.

Чтобы добавить какую-либо из перечисленных в иерархическом списке команд языка ActionScript в код сценария, следует выполнить любое из перечисленных ниже действий:

□ перетащить соответствующий пункт иерархического списка мышью в область редактирования кода. Нужно только проследить, чтобы он попал в нужное место;

□ дважды щелкнуть на пункте списка;

□ выбрать пункт Add to Script в контекстном меню выбранного пункта;

□ нажать расположенную над областью редактирования кода кнопку со знаком "плюс", раскрытое меню которой показано на рис. 18.2, "проследовать" по иерархии подменю и выбрать соответствующий пункт;

□ нажать комбинацию клавиш, соответствующую требуемому пункту упомянутого выше меню (рис. 18.2).

О комбинациях клавиш, служащих для добавления в сценарий команд языка ActionScript, нужно рассказать подробнее. Эти комбинации состоят из трех клавиш: двух алфавитно-цифровых и клавиши . Нажимать их нужно так: сначала — клавишу , затем — первую клавишу, потом — вторую. И еще: перед тем как пользоваться этими комбинациями, необходимо переключиться в область редактирования кода сценария — в обоих иерархических списках панели Actions эти комбинации не действуют.

Комбинации клавиш — очень полезная вещь. Только по умолчанию они почему-то не отображаются в иерархическом списке доступных команд — наверно, разработчикам Flash это показалось излишним. Чтобы все-таки заставить Flash отображать эти комбинации прямо в этом списке, достаточно включить пункт-выключатель Esc Shortcut Keys в дополнительном меню панели Actions.

Итак, мы выбрали действие gotoAndPlay и добавили его в код сценария одним из описанных выше способов. Это действие тотчас появится в области редактирования кода:

gotoAndPlay()

Осталось ввести значение параметра действия gotoAndPlay, равное 1, возможно, поставить точку с запятой — и первый наш сценарий готов. Он будет таким:

gotoAndPlay(1);

А кадр, к которому мы привязали сценарий, будет выглядеть так, как показано на рис. 18.3. Хорошо заметна буква а — она обозначает, что кадр содержит сценарий, который будет выполнен при достижении этого кадра.

В этом примере мы поместили свой сценарий в тот же слой, в котором находится наша анимация. Но если таких сценариев много, рекомендуется помещать их в отдельный слой под названием сценарии или Actions. Так нам будет проще управляться со всеми созданными нами сценариями, которых в сложном фильме может быть не один десяток.

На этом создание нашего первого сценария можно считать законченным. Проверим его в действии.

 

Воспроизведение фильмов, кадры которых содержат сценарии

Есть одна тонкость, которую необходимо учитывать при воспроизведении фильмов, кадры которых содержат сценарии. Дело в том, что Flash способен выполнять такие сценарии прямо во время воспроизведения, и это обстоятельство может очень помочь при их отладке. Правда, наше замечание касается только простейших сценариев, наподобие того, что мы только что написали.

Если мы сейчас начнем воспроизведение нашего фильма, выбрав пункт Play меню Control или нажав клавишу , то Flash корректно обработает наш сценарий и выполнит переход на первый кадр сцены Фильм по достижении ее последнего кадра. Если же он этого не сделает, нужно проверить, включен ли пункт-выключатель Enable Simple Frame Actions меню Control. Как раз этот пункт при включении предписывает Flash выполнять сценарии, привязанные к кадрам.

 

Привязка сценариев к клипам

Привязать сценарий к кадру, как мы только что убедились, несложно. А как насчет клипа?

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

Для экспериментов возьмем фильм, в котором демонстрировались возможности составной анимации (см. главу 13). (Помните этот фильм: прямоугольник, кувыркаясь, летит по рабочему листу?) Загрузим содержащий его документ. И выполним подготовительные действия.

1. Преобразуем экземпляр графического образца в экземпляр-клип, если не сделали этого раньше. Для чего выберем в раскрывающемся списке, расположенном в верхнем левом углу панели Properties, пункт Movie Clip.

2. Дадим клипу имя, например, clip.

Теперь все готово для написания сценария.

Давайте сделаем так, чтобы при щелчке мышью на вложенном клипе он останавливал свое воспроизведение, переставая крутиться. Конечно, пользы от такой интерактивности никакой, но, по крайней мере, это будет наш первый опыт привязки сценария к клипу. Мы ведь пока только учимся писать сценарии…

Итак, к делу! Выделим клип clip на рабочем листе. И вспомним то, что говорилось в начале этой главы о событиях.

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

Так что нам придется указать, к какому из поддерживаемых клипов событий мы привязываем наш сценарий. Это указание производится с помощью особого действия onclipEvent, в качестве параметра которого задается событие, в ответ на которое будет выполняться сценарий.

Полный "шаблон" для написания сценария-обработчика события будет иметь такой вид:

onClipEvent (<Обозначение события>)

{

<Код сценария-обработчика>

}

Первая строка этого "шаблона" задает событие, на которое "откликается" обработчик, и называется заголовком. Сам же код обработчика помещается в фигурных скобках после заголовка и называется телом.

Давайте же, поглядывая на приведенный выше "шаблон", напишем свой сценарий. Он будет таким:

onClipEvent(mouseDown)

{

stop();

}

В качестве параметра мы передаем действию onclipEvent обозначение события mouseDown. Это событие возникает, когда посетитель щелкает на клипе мышью. А действие stop вызывает немедленную остановку воспроизведения анимации клипа, к которому привязан содержащий это действие сценарий.

Здесь нужно сказать вот еще что. Все действия, помещенные нами в привязанные к клипу сценарии, будут управлять анимацией именно этого клипа. Поэтому действие stop в приведенном выше сценарии остановит внутреннюю анимацию клипа clip, а не анимацию самого фильма.

Теперь выделим наш клип, если еще не сделали этого, и вызовем на экран панель Actions. Введем в область редактирования кода приведенный выше код сценария-обработчика события. И запустим готовый фильм на воспроизведение.

Выше говорилось, что Flash при воспроизведении фильмов может выполнять простейшие сценарии, привязанные к кадрам. Сейчас же мы привязали сценарий к клипу, а не к кадру, а такие сценарии Flash выполнить не сможет. Поэтому нам придется выбрать пункт Test Movie меню Control или нажать комбинацию клавиш < Ctrl>+< Enter>, чтобы запустить воспроизведение фильма в отдельном окне.

Давайте, после того как начнется воспроизведение фильма, попробуем щелкнуть мышью на вращающемся прямоугольнике. Если нам все-таки удастся это сделать, он тотчас прекратит "разваливаться" пополам и "застынет" в таком виде, пока анимация не закончится.

Ура, наш первый обработчик события работает! Давайте его немного усложним. Снова выделим клип clip, откроем панели Actions и допишем в сценарий еще одно выражение. Наш сценарий примет такой вид (добавленное выражение выделено полужирным шрифтом):

onClipEvent(mouseDown)

{

stop();

_parent.stop();

Специальная команда языка ActionScript _parent обозначает клип, в который вложен клип, к которому привязан этот сценарий — в нашем случае это будет основной фильм. (Такие команды, кстати, называются ключевыми словами.) Ну, а записанное после этого слова и отделенное от него точкой действие stop нам уже знакомо.

Что же мы получим в результате? А вот что. Проигрыватель Flash прочитает сначала ключевое слово _parent, а потом — действие stop. И поймет, что действие stop нужно распространить на основной фильм — ведь именно в него вложен клип clip. Так что добавленное нами выражение остановит внешнюю анимацию.

 

Привязка сценариев к кнопкам

 

Кнопки Flash мы пока еще подробно не рассматривали, не считая краткого упоминания в главе 8. Настала пора поговорить о них подробно.

Кнопки (или экземпляры образцов-кнопок) Flash ведут себя подобно обычным кнопкам, которые мы встречаем практически во всех приложениях Windows. Они могут быть нажаты, в результате чего всегда выполняется какой-либо сценарий.

Используются кнопки обычно для того, чтобы предоставить зрителю (в частности, посетителю Web-сайта) возможность выполнить какое-то действие: запустить или остановить воспроизведение анимации, открыть Web-обозреватель и загрузить в него какую-то Web-страницу и пр. В интерактивных фильмах Flash кнопки встречаются очень часто.

 

Создание кнопок

Прежде чем привязывать к кнопке сценарий, ее нужно создать. Займемся этим.

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

Сначала нам нужно создать образец-кнопку. Делается это уже знакомым нам из главы 8 способом. Выберем пункт New Symbol меню Insert, в поле Name диалогового окна Create New Symbol (см. рис. 8.2) введем имя создаваемого образца-кнопки (дадим ему имя Кнопка), включим переключатель Button в группе Behavior и нажмем кнопку ОК. После этого Flash откроет вновь созданный, пока еще "пустой" образец в режиме правки. Нам останется только нарисовать нашу кнопку.

Но не будем спешить это делать. Посмотрим лучше на временную шкалу (рис. 18.4). Она содержит всего четыре позиции, и весьма странных — все они имеют имена: Up, Over, Down и Hit. В позиции Up уже создан ключевой кадр.

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

□ изображение, находящееся в кадре Up, выводится, когда кнопка не нажата и курсор мыши не установлен над ней;

□ изображение, находящееся в кадре Over, выводится, когда курсор мыши установлен над кнопкой, но сама кнопка не нажата;

□ изображение, находящееся в кадре Down, выводится в тот момент, когда пользователь нажимает кнопку;

□ изображение, находящееся в кадре Hit, задает область, которая будет откликаться на касания и щелчки мышью ("горячую область" кнопки). Это изображение никогда не выводится на экран.

Заметим, что обязательным является только изображение в кадре up. Без остальных можно обойтись. Их отсутствие восполнят следующие правила.

□ Если отсутствует кадр Hit, "горячую область" определяет изображение в кадре Up.

□ Если отсутствует кадр Down, для отображения нажатой кнопки Flash возьмет изображение из кадра Over.

□ Если отсутствует кадр Over, для отображения кнопки, которой "коснулся" курсор мыши, Flash позаимствует изображение из кадра Up.

Кнопки Flash имеют еще одну интересную особенность. Дело в том, что "горячая" область кнопки совсем не обязательно должна совпадать с самой кнопкой. Так, иная кнопка может сработать, если пользователь щелкнет совсем в другом месте рабочего листа. Это обстоятельство позволяет создавать весьма забавные и полезные вещи вроде подсказок, "всплывающих" при наведении мыши на какой-либо фрагмент изображения, и пр.

Но давайте все-таки нарисуем нашу кнопку. Не станем особенно мудрить — нарисуем в кадре Up обычный синий прямоугольник. На первый раз этого будет достаточно.

Следующий шаг — рисование изображения в кадре Over. Пусть это будет красный прямоугольник. Создадим в делении Over новый ключевой кадр; Flash автоматически поместит туда изображение из кадра up, и нам останется только перекрасить его в красный цвет.

Нарисуем содержимое остальных двух кадров кнопки. В кадре Down прямоугольник пусть будет темно-синим. А цвет изображения в кадре Hit роли не играет.

Все — образец-кнопка готов. Вернемся в режим правки фильма и откроем панель Library. Создадим новый слой и назовем его Кнопка — именно в него мы и поместим нашу кнопку, иначе анимация в первом слое окажется "оборванной". Найдем в списке образцов только что созданную нами кнопку и поместим в нижний правый угол рабочего листа ее экземпляр. И, наконец, проверим ее в действии.

 

Воспроизведение фильмов, содержащих кнопки

Воспроизведение фильмов, содержащих кнопки, также имеет некоторые особенности. Flash способен сделать так, что мы сможем нажимать кнопки прямо во время работы над фильмом (конечно, привязанные к ним сценарии работать не будут). Это поможет проверить правильность всех наших действий.

Чтобы задействовать режим обработки кнопок на рабочем листе, нам нужно будет включить пункт-выключатель Enable Simple Buttons меню Control. Также можно нажать комбинацию клавиш ++. После этого,

если мы поместим курсор мыши над кнопкой, она сменит свой цвет на красный. Мы даже сможем ее нажать (правда, привязанный к кнопке сценарий в этом случае не будет выполнен).

Единственный недостаток такой кнопки: мы не сможем ее выделить. Для этого нам придется отключить пункт-переключатель Enable Simple Buttons меню Control.

Естественно, при воспроизведении фильма в отдельном окне кнопки будут работать всегда. Также в этом случае будут работать и все привязанные к ним сценарии.

 

Добавление звуков к кнопкам

Мы имеем возможность, кроме всего прочего, привязывать к кнопкам звуки. Звуки могут быть привязаны к разным состояниям кнопки, в результате чего, например, при наведении курсора мыши на кнопку будет воспроизведен один звук, а при щелчке на кнопке — другой. Сейчас мы выясним, как это делается.

Прежде всего, импортируем требуемые звуки в библиотеку. (О том, как это делается, было подробно рассказано в главе 17.) Дадим получившимся в результате импорта образцам-звукам "говорящие" имена, например: касание и нажатие. Все — можно приступать к "озвучке" кнопки.

Откроем нужный образец-кнопку в режиме правки. Создадим новый слой для звуков и назовем его Звук-касание. После этого выделим деление over временной шкалы, создадим в нем ключевой кадр и поместим на рабочий лист экземпляр образца-звука Касание. Результат этих действий показан на рис. 18.5.

Чтобы привязать звук к состоянию Down кнопки, нам нужно будет создать еще один слой — Звук-нажатие. После этого останется только создать ключевой кадр в делении Down и поместить в него звук Нажатие.

Теперь можно вернуться в основной фильм и проверить "озвученную" кнопку в действии. Проще всего это сделать, запустив воспроизведение фильма в отдельном окне.

 

Написание сценариев, привязанных к кнопкам

Уф! Наконец-то кнопка создана. Теперь можно заняться собственно привязкой к ней сценария.

Сценарии привязываются к кнопке точно так же, как и к клипу. Мы выделяем на рабочем листе нужную кнопку, даем ей имя (скажем, button), воспользовавшись панелью Properties, вызываем на экран панель Actions и пишем в ее области редактирования код нужного сценария. Различия имеются только в наименовании событий и синтаксисе заголовков их обработчиков.

Так, "шаблон" для написания сценария-обработчика события кнопки имеет следующий вид:

on(< Обозначение события>)

{

<Код сценария-обработчика>

}

Обратим внимание, что вместо действия onclipEvent в этом случае используется действие on. Это первое отличие. Второе же отличие заключается в том, что для обозначения события нажатия кнопки нам будет нужно использовать Слово press, а не mouseDown.

Учитывая сказанное, напишем сценарий для кнопки. Он будет таким:

on (press)

{

stop();

}

Выражение, записанное в теле этого сценария, нам давно знакомо. Оно остановит анимацию в основном фильме, так как сценарии, привязанные к кнопке, действуют на тот клип, в котором эта кнопка находится (в нашем случае — это основной фильм). Это третье отличие сценариев, привязанных к кнопкам, от сценариев, являющихся "собственностью" клипов.

Введем этот сценарий в область редактирования кода панели Actions и запустим воспроизведение фильма в отдельном окне. После этого щелкнем по кнопке, и вся анимация — и внешняя, и внутренняя — остановится.

 

Работа с панелью Actions

С панелью Actions мы уже знакомы. (Еще бы — сколько сценариев с ее помощью мы уже написали!.. Целых четыре!) Давайте посмотрим, что она нам еще может предложить, продолжим знакомство, так сказать.

Как уже говорилось, мы можем использовать при вводе кода в область редактирования этой панели любые приемы, знакомые нам по работе в программах редактирования текста, в частности — операции с буфером обмена Windows, "откат" последнего совершенного действия и "откат отката".

Кроме того, панель Actions предоставляет нам дополнительные инструменты, которые сильно облегчат наш труд. Рассмотрим самые полезные из них.

Подсказка по коду. Когда мы открываем круглую скобку, готовясь ввести значение параметра какого-либо действия (например, gotoAndPlay), чуть ниже текстового курсора появляется небольшое светло-желтое окошко с текстом, описывающим назначение этого параметра (рис. 18.6). После того как мы введем значение этого параметра и поставим запятую, подсказка выдаст описание следующего параметра, и т. д. Щелкая на небольших стрелках, находящихся в окне подсказки и направленным вправо и влево, можно просмотреть описания соответственно следующего и предыдущего параметров.

Подсказки-списки. Если мы откроем скобку, чтобы задать параметр, значения которого должны выбираться из ограниченного списка, на экране появится этот самый список со значениями (рис. 18.7). Нам останется только выбрать в списке нужное значение либо щелчком мыши, либо выделив его клавишами-стрелками и нажав клавишу .

Любую из этих подсказок можно вызвать на экран, поставив в нужное место кода текстовый курсор и нажав кнопку, расположенную над областью редактирования кода:

Также можно выбрать пункт Show Code Hint в дополнительном меню панели или, что проще всего при работе с клавиатурой, нажать комбинацию клавиш < Ctrl>+<пробел>.

Автоматическое создание отступов при вводе строк кода. (Отступы очень часто применяются, например, для выделения тела обработчика события.) Если мы ввели строку с отступом от ее начала, то при нажатии клавиши новая строка будет иметь такой же отступ. Отступы формируются также, если предыдущая строка заканчивается круглой или фигурной скобкой.

Можно установить отступ вручную, для чего достаточно целиком выделить нужные строки кода и нажать клавишу <Таb>. Чтобы убрать отступ, нужно также выделить строки и нажать комбинацию клавиш +.

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

Также можно выбрать пункт Check Syntax в дополнительном меню панели или нажать комбинацию клавиш +. Flash проверит введенный нами код на правильность и выведет окно-предупреждение с текстом "The script contains no errors" (если сценарий не содержит ошибок) или "This script contains errors. The errors encountered are listed in Output Panel" (если сценарий содержит ошибки).

Если сценарий содержит ошибки, Flash также выведет на экран небольшую панель Output, в которой будут приведены описания всех найденных ошибок (рис. 18.8). Правда, эти описания будут даны по-английски…

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

Для выполнения поиска подстроки нужно нажать кнопку, расположенную над областью редактирования кода:

Можно также выбрать в дополнительном меню панели пункт Find and Replace или нажать комбинацию клавиш +. В результате этого на экране появится диалоговое окно Find and Replace (рис. 18.9).

В поле ввода Find what зададим искомую подстроку, включим флажок Match case, если желаем, чтобы Flash учитывал при поиске регистр символов, и нажмем кнопку Find Next. Flash выделит первую строку кода, в которой имеется заданная нами подстрока. Если подстрока так и не будет найдена, Flash выведет окно-предупреждение с текстом "Cannot find the string "<Искомая подстрока>"".

Чтобы продолжить поиск введенной подстроки далее по тексту сценария, мы снова нажмем кнопку Find Next диалогового окна Find. Если мы уже закрыли это окно (для чего достаточно нажать кнопку Close), то выберем в дополнительном меню панели пункт Find Again или нажмем клавишу .

Для выполнения замены искомой подстроки на другую служит все то же окно Find and Replace. В этом случае после задания искомой подстроки нужно будет ввести в поле Replace with подстроку, которая заменит искомую. Опять же, можно установить флажок Match case, чтобы Flash учитывал при поиске регистр символов. Замена запускается нажатием кнопки Find Next. Flash выделит первую строку кода, в которой встретилась искомая подстрока. После этого мы можем нажать кнопку Replace, чтобы выполнить замену. Для продолжения поиска нужно снова нажать кнопку Find Next.

Мы можем выполнить замену сразу всех найденных в коде подстрок. Для этого сразу же после ввода значений в поля ввода окна Replace следует нажать кнопку Replace All.

Автоматическая нумерация строк сценария. Чтобы воспользоваться этим средством, достаточно включить пункт-выключатель Line Numbers в дополнительном меню панели или нажать комбинацию клавиш + ++.

Быстрый переход на строку кода с заданным номером. Выбираем пункт Go to Line дополнительного меню панели или нажимаем комбинацию клавиш +, вводим номер нужной строки в поле ввода Line number диалогового окна Go to Line (рис. 18.10) и нажимаем кнопку ОК:

Автоматический перенос слишком длинных строк. От него можно избавиться, отключив пункт-выключатель Word Wrap дополнительного меню панели или нажав комбинацию клавиш ++. Правда, в этом случае нам придется часто пользоваться горизонтальной полосой прокрутки, чтобы просмотреть слишком длинные строки кода.

Печать всех сценариев, созданных в документе. Выбираем пункт Print дополнительного меню панели. На экране появится стандартное диалоговое окно задания параметров печати Windows; задаем эти параметры и нажимаем кнопку ОК.

 

Поведения Flash и их использование

Специально для начинающих программистов Flash представляет набор так называемых поведений (behaviors). Это набор сценариев ActionScript, которые мы можем привязать к кадру, клипу или кнопке без необходимости набирать их вручную в панели Actions. Таких поведений в составе Flash поставляется довольно много; они служат для управления анимацией, клипами, звуком и пр.

Работа с поведениями — создание, правка и удаление — выполняется с помощью панели Behaviors (рис. 18.11). Чтобы вывести эту панель на экран, нужно включить пункт-выключатель Behaviors меню Window или нажать комбинацию клавиш +.

Большую часть этой панели занимает список поведений, уже привязанных к выделенному элементу фильма: кадру, клипу или кнопке. (На рис. 18.11 этот список пуст.) Он организован в виде таблицы из двух колонок: Event (событие, которое обрабатывает поведение) и Action (поведение, выполняемое в ответ на событие).

Чтобы создать поведение, привязанное к какому-либо элементу фильма, нужно выделить этот элемент (его имя, равно как и имя образца, на основе которого он был создан, появятся над списком поведений) и нажать на кнопку с изображением знака "плюс" панели Behaviors. На экране появится небольшое меню (рис. 18.12), содержащее все доступные поведения, сгруппированные в категории. Категории представляют собой подменю, а сами поведения — пункты этих подменю.

После выбора пункта, соответствующего нужному поведению, на экране появится диалоговое окно, где нужно будет задать параметры этого поведения. Поведение будет создано после нажатия кнопки ОК этого окна. А в списке панели Behaviors появится соответствующая этому поведению строка.

Если поведение было привязано к клипу или кнопке, нужно будет задать событие, в ответ на которое будет выполняться сценарий этого поведения. Для этого достаточно выбрать нужную строку в списке панели Behaviors и щелкнуть внутри колонки Event этой строки. После этого там появится небольшой раскрывающийся список (рис. 18.13), в котором и выбирается нужное событие.

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

Хоть поведения и создавались для помощи начинающим программистам, но для понимания принципов их создания нужно все же познакомиться с языком программирования ActionScript. Так что мы не будем здесь подробно знакомиться со всеми этими поведениями, а лучше перейдем к рассмотрению этого языка. После знакомства с ActionScript понять, что делает и как создается то или иное поведение, не составит никакого труда.

 

Что дальше?

Ну что ж, мы сделали самый первый шаг в мире Flash-программирования. Мы усвоили новые термины, изучили новые инструменты и были потрясены открывшимися перед нами новыми возможностями. И мы написали целых четыре сценария! Хоть они и очень просты, но ведь это все-таки наш первый шаг…

Для продолжения занятий по программированию во Flash нам не хватает знания самого языка ActionScript. Поэтому всю следующую главу мы посвятим изучению этого весьма мощного языка. А попутно множество других сценариев, на этот раз — более сложных.

 

Глава 19

Язык ActionScript

 

В этой главе мы изучим язык ActionScript, используемый для написания сценариев Flash. Мы подробно разберем принципы написания сценариев и команды языка, которые для этого используются. Также мы познакомимся с механизмами, предоставляемыми Flash для управления различными элементами фильма: клипами, кнопками, полями ввода, звуком и пр.

Эта глава действительно велика. Так что не будем тратить время зря.

 

Начала языка ActionScript

 

В этом разделе мы рассмотрим основные понятия языка программирования ActionScript — то, без чего нельзя приступать к написанию полноценных сценариев.

 

Основные понятия ActionScript

Сценарий — это последовательный набор выражений, которые могут содержать действия — команды, воздействующие непосредственно на фильм. Также в выражениях могут быть ключевые слова — особые слова языка ActionScript, имеющие специальное значение, но не воздействующие на фильм непосредственно. Каждое выражение ActionScript должно завершаться знаком "точка с запятой". Все это нам уже знакомо из главы 18.

Вот типичный пример сценария:

on (press) {

stop ();

}

Это обработчик события press, которое возникает в кнопке при щелчке по ней. Он останавливает воспроизведение анимации.

А вот еще один обработчик события:

onClipEvent(mouseDown) {

b = а + 2;

gotoAndPlay(b);

}

Он выполняется в ответ на событие mouseDown, возникающее при щелчке мышью на клипе. Его второе выражение, содержащее действие gotoAndPlay, нам уже знакомо. (Правда, вместо номера кадра в качестве параметра действию передается нечто непонятное, но об этом потом.) Первое же выражение нам что-то напоминает… Математическая формула?

Да, это математическая формула, записанная на языке ActionScript в вице выражения. Подобные выражения называются математическими выражениями. Выражение b = а + 2, как можно предположить, вычисляет некое значение. Давайте рассмотрим его подробнее.

Очевидно, что данное выражение складывает две величины — об этом говорит знак +. Этим знаком обозначается оператор арифметического сложения ActionScript, выполняющий сложение двух величин. Оператор — это команда, выполняющая действия над данными сценария, а не над элементами фильма. Забегая немного вперед, скажем, что в ActionScript существуют также операторы арифметического вычитания, умножения и деления, обозначаемые соответственно знаками —, * и /.

Слева и справа от оператора сложения находятся операнды — значения, которыми манипулирует этот оператор. Второй операнд (число 2 в нашем примере) является константой — постоянной величиной. Ведь значение числа 2 никогда не изменяется, не так ли?

Первый же операнд в выражении какой-то непонятный — он обозначен буквой а. Что это такое? А это переменная — ячейка памяти, в которую можно на время поместить какое-либо значение, чтобы сохранить его до лучших времен. (Поэтому она и называется переменной, в отличие от константы.) Каждая переменная должна иметь уникальное имя.

Итак, что же делает описанное выражение? Оно берет из переменной а значение первого операнда, складывает его с константой 2 (второй операнд), а результат помещает в переменную b Помещение результата в переменную b выполняется с помощью оператора присваивания, обозначаемого символом =.

Вот еще один пример арифметического выражения, на этот раз более сложного:

у = yl * у2 + х1 * х2;

Здесь операторы выполняются в следующем порядке:

1. Значение переменной y1 умножается на значение переменной у2.

2. Перемножаются значения переменных x1 и х2.

3. Полученные на шагах 1 и 2 произведения складываются.

4. Полученная сумма присваивается переменной у.

Но почему на шаге 2 выполняется умножение x1 на х2, а не сложение произведения у1 и у2 с x1. Дело в том, что каждый оператор имеет приоритет — своего рода номер в очереди их выполнения. Так вот, оператор умножения имеет более высокий приоритет, чем оператор сложения, поэтому умножение всегда выполняется перед сложением.

А вот еще одно выражение:

х = х + 3;

Оно абсолютно правильно с точки зрения ActionScript, хоть и выглядит нелепым. В нем сначала выполняется сложение значения переменной х и числа 3, после чего результат сложения снова помещается в переменную х. Такие выражения используются в сценариях ActionScript очень часто.

Вот и все. Основные принципы программирования на ActionScript мы изучили. В дальнейшем мы вернемся к ним, чтобы пополнить и уточнить наши знания.

 

Данные ActionScript. Типы данных

Любая программа при своей работе оперирует некими данными. Такими данными могут быть координаты клипа на рабочем листе, номер кадра, имя и пароль пользователя, цена какого-нибудь товара в интернет-магазине, величина атмосферного давления и пр. Конечно, не составляют исключения и сценарии ActionScript; мы сами использовали номер кадра, когда писали наши первые сценарии (см. главу 18).

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

Строковые данные (или строки) — это последовательности букв, цифр, пробелов, знаков препинания и прочих символов, заключенные в одинарные или двойные кавычки. Например, это могут быть такие строки:

"Flash 8"

"1234567"

'Строковые данные — это последовательности символов.'

Строки могут иметь любую длину (определяемую количеством составляющих их символов), ограниченную лишь объемом свободной памяти компьютера. Разумеется, теоретически существует предел в 2 Гбайт, но вряд ли в нашей практике встретятся столь длинные строки.

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

Набор всех доступных символов вместе с соответствующими им кодами называется кодировкой. Flash 8 для хранения строк использует кодировку Unicode, в которой каждый символ представлен двумя байтами (можно кодировать до 65 535 символов). Кодировка Unicode содержит практически все символы практически всех языков мира; это позволяет использовать в документах Flash тексты на любых языках мира.

Кроме букв, цифр и знаков препинания, строки могут содержать специальные символы, служащие для особых целей. Все специальные символы, поддерживаемые Flash, приведены в табл. 19.1.

Числовые данные (или число) — это обычные числа, над которыми можно производить все арифметические действия, извлекать из них квадратный корень и вычислять тригонометрические функции. Числа могут быть как целыми, так и дробными; в последнем случае целая и дробная части разделяются точкой (не запятой!).

Примеры чисел:

13756

454.7873

0.5635

Для записи дробных чисел может быть использована экспоненциальная форма вида <мантисса>Е<порядок>. Вот примеры заданных таким образом чисел (в скобках дано традиционное математическое представление):

IE-5 (10 -5 )

8.546Е23 (8,546×10 23 )

Логическая величина может принимать только два значения: true и false — "истина" и "ложь", — обозначаемые соответственно ключевыми словами true и false. Логические величины часто используются в операциях сравнения (о них будет рассказано далее в этой главе).

ActionScript также поддерживает два специальных типа. Эти типы обозначают отсутствие любых данных. Тип null обозначает отсутствие каких-либо данных и обозначается ключевым словом null. А тип undefined указывает на то, что переменной не было присвоено никакое значение, и обозначается ключевым словом undefined.

Внимание!

Undefined — это не то же самое, что null !

Остальные типы данных, поддерживаемые ActionScript и не описанные здесь, мы рассмотрим позже.

 

Константы

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

26756

"Строка"

true

null

ActionScript также предоставляет несколько специальных констант, заданных ключевыми словами. Среди них, например, есть константа infinity, представляющая значение ∞, возникающее при делении на ноль. А константа — infinity представляет значение — ∞.

 

Переменные

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

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

Именование переменных

Как мы уже знаем, каждая переменная должна иметь имя, которое однозначно ее идентифицирует. Другими словами, не должно быть двух переменных с одним и тем же именем (об исключениях из этого правила поговорим попозже). Также не допускается совпадение имени переменной с ключевым словом языка ActionScript.

В имени переменной могут присутствовать латинские и русские буквы, цифры, символы $ (знак доллара) и _ (знак подчеркивания), причем первый символ имени должен быть либо буквой, либо знаком доллара или подчеркивания. Например, FrameNumber, _link, ИмяПользователя — правильные имена переменных, a 67 8vasya и имя пользователя — неправильные.

Нужно сразу сказать, что язык ActionScript чувствителен к регистру символов, которыми набраны имена переменных. Это значит, что framenumber и FrameNumber — разные переменные.

При выборе имен переменных специалисты фирмы Macromedia рекомендуют следовать одному простому правилу: имя должно быть "говорящим". Это значит, что имя должно отражать назначение переменной. Например, переменную, в которой хранится номер кадра, лучше всего назвать frameNumber — так будет сразу понятно, зачем она нужна. Но не стоит слишком усердствовать: имена типа lastVisitedFormFrameNumber очень трудно набирать. Для временных переменных (хранящих данные, необходимые в данный конкретный момент) лучше всего брать однобуквенные имена: i, a, x, y и т. п.

Объявление переменных

Перед использованием переменной в коде сценария обязательно нужно выполнить ее объявление. Для этого используется оператор объявления переменной var, после которого указывается имя переменной. Вот так:

var х;

Теперь объявленной переменной можно присвоить какое-либо значение:

х = 1234;

и использовать в сценарии:

у = х / 2 + 10;

Значение переменной также можно присвоить прямо при ее объявлении:

var х = 1234;

Нужно сказать, что объявлять переменные с помощью оператора var не обязательно. Мы можем просто присвоить переменной какие-либо значение, и Flash сам ее создаст. Просто явное объявление переменных оператором var считается хорошим стилем программирования.

Внимание!

Если обратиться к переменной, еще не получившей никакого значения, она вернет значение undefined .

Область видимости переменных

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

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

А вот сценарии, содержащиеся во вложенных в эту анимацию клипах, не смогут получить доступ к этой переменной. Также ее не смогут использовать сценарии, находящиеся во внешнем по отношению к текущему клипе. Если же мы все-таки попытаемся извлечь значение этой переменной из одного из таких сценариев, то получим значение undefined, с которым каши не сваришь.

Такие переменные называются переменными уровня клипа. Говорят, что такие переменные "видны" только в "своем" клипе.

Но что делать, если нам все же нужно обратиться к переменной, находящейся в другом клипе? Да просто указать имя этого клипа перед именем переменной, разделив их точкой. Вот так:

someClip.someVar = 0;

Глобальные переменные "видны" абсолютно из всех сценариев, находящихся в данном фильме. Они объявляются с помощью модификатора (особого ключевого слова, изменяющего действие какой-либо команды ActionScript) _giobal, который добавляется перед именем переменной и отделяется от него точкой:

_global.someVar = 0;

Существует еще один тип видимости переменных — локальные переменные. Мы поговорим о них, когда начнем изучение функций.

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

Давайте рассмотрим такой пример:

_global.someVar: String = "Value";

var someVar: Integer = 3;

s = someVar;

Мы объявили две переменные someVar, одну — уровня клипа, другую — глобальную, и присвоили им разные значения. Если мы теперь запросим значение переменной someVar, то переменной s будет присвоено число 3 — значение переменной someVar уровня клипа как имеющей более "узкую" область видимости. Глобальная переменная someVar будет "замаскирована".

Внимание!

Всегда проверяйте, к какой переменной вы обращаетесь. Ошибки доступа к переменным — самые трудноулавливаемые.

Но как получить значение глобальной переменной someVar? Очень просто — нужно использовать модификатор _giobal:

s = _global.someVar;

 

Операторы

Ну что ж, с данными, константами и переменными покончено. Пора приступать к рассмотрению операторов, предназначенных для манипуляций с ними.

Арифметические операторы

Арифметические операторы служат для выполнения арифметических действий над значениями констант и переменных. Все арифметические операторы, поддерживаемые ActionScript, перечислены в табл. 19.2.

Арифметические операторы делятся на две группы: унарные и бинарные. Унарные операторы выполняются над одним операндом; к ним относятся операторы смены знака, инкремента и декремента. Унарный оператор извлекает из переменной значение, изменяет его и снова помещает в ту же переменную. Приведем пример выражения с унарным оператором:

++r;

При выполнении этого выражения в переменной r окажется ее значение, увеличенное на единицу. А если записать вот так:

s = ++r;

то же значение будет помещено и в переменную s.

Операторы инкремента и декремента могут ставиться как перед операндом, так и после него. Если оператор инкремента стоит перед операндом, то значение операнда сначала инкрементируется, а уже потом используется в дальнейших вычислениях. Если же оператор инкремента стоит после операнда, то его значение сначала используется в других вычислениях, а уже потом инкрементируется. Точно так же ведет себя оператор декремента.

Бинарные операторы всегда имеют два операнда и помещают результат в третью переменную. Вот примеры выражений с бинарными операторами:

l = r * 3.14;

f = е / 2;

х = х + t / 3;

Внимание!

Операторы инкремента и декремента рекомендуется использовать, если значение какой-либо переменной нужно увеличить или уменьшить на единицу. Эти операторы выполняются быстрее, чем операторы сложения и вычитания.

Оператор объединения строк

Оператор объединения строк + позволяет соединить две строки в одну. Например, сценарий:

s1 = "Flash";

s2 = "8";

s = s1 + s2;

поместит в переменную s строку "FiashS".

Операторы присваивания

Оператор простого присваивания = нам уже знаком. С его помощью переменной присваивается новое значение:

а = 2;

b = с = 3;

Второе выражение в приведенном примере выполняет присвоение значения 3 сразу двум переменным — b и с.

Кроме операторов присваивания, ActionScript поддерживает операторы сложного присваивания. Такие операторы позволяют выполнять операцию присваивания одновременно с другой операцией:

а = а + b;

а += b;

Два этих выражения эквивалентны по результату. Просто во втором был использован оператор сложного присваивания +=.

Все операторы сложного присваивания, поддерживаемые ActionScript, и их эквиваленты приведены в табл. 19.3.

Операторы сравнения

Операторы сравнения сравнивают два операнда и возвращают логическое значение. Если условие сравнения выполняется, возвращается логическое значение "истина" (true), если не выполняется — "ложь" (false). Вот примеры выражений с операторами присваивания:

а1 = 2 < 3;

a2 = -4 > 0;

а3 = r < t;

Переменная a1 получит значение true (2 меньше 3), переменная а2 — значение false (число -4 по определению не может быть больше нуля), а значение переменной а3 будет зависеть от значений переменных r и t.

Все поддерживаемые ActionScript операторы сравнения приведены в табл. 19.4.

С первыми шестью операторами сравнения все понятно. Но на двух последних операторах — "строго равно" и "строго не равно" — нужно остановиться подробнее. Это операторы так называемого строгого сравнения. Обычные операторы "равно" и "не равно", если встречают операнды разных типов, пытаются преобразовать их к одному типу (о преобразованиях типов см. далее в этой главе). Операторы строгого равенства и строгого неравенства такого преобразования не делают, а в случае несовместимости типов операндов возвращают false.

Логические операторы

Логические операторы выполняют действия над логическими значениями. Все они приведены в табл. 19.5. А в табл. 19.6 и 19.7 показаны результаты выполнения этих операторов.

Основная область применения логических операторов — выражения сравнения (о них см. далее в этой главе). Приведем примеры таких выражении:

а = (b > 0) && (с + 1! - d);

flag =! (status — 0);

Оператор typeof

Оператор typeof принимает в качестве операнда переменную или выражение и возвращает строку, описывающую тип данных операнда. Все значения, которые он может вернуть, перечислены в табл. 19.8.

Оператор typeof может использоваться, например, так:

status = typeof (somevar);

Здесь мы присваиваем результат выполнения оператора typeof строковой переменной status. Впоследствии он может быть использован, например, в условном выражении.

Совместимость и преобразование типов данных

И напоследок рассмотрим еще два важных вопроса: совместимость типов данных и преобразование одного типа к другому.

Что получится, если сложить два числовых значения? Правильно — еще одно числовое значение. А если сложить число и строку? Трудно сказать. Тут Flash сталкивается с проблемой несовместимости типов данных и пытается сделать эти типы совместимыми, преобразуя один из них к другому. Сначала он пытается преобразовать строку в число и, если это удается, выполняет сложение. В случае неудачи число будет преобразовано в строку, и две полученные строки будут объединены. Например, в результате выполнения операторов

var а, b, с, d, е, f;

а = 11;

b = "12";

с = а + b;

d = "Flash";

е = 8;

f = d + е;

значение переменной b при сложении с переменной а будет преобразовано в числовой тип; таким образом, переменная с будет содержать значение 23. Но так как значение переменной d не может быть преобразовано в число, значение е будет преобразовано в строку, и результат — значение f — станет равным "FlashS".

Логические величины преобразуются либо в числовые, либо в строковые, в зависимости от конкретного случая. Значение true будет преобразовано в число 1 или строку "1", а значение false — в 0 или "0".

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

Для преобразования типов данных используется следующий синтаксис:

<Переменная нужного типа> = <Ключевое слово, соответствующее этому типу>

(<Преобразуемое значение>);

Ключевые слова, соответствующие тому или иному типу данных, приведены в табл. 19.8. Да, именно эти слова возвращает оператор typeof в качестве результата. Единственное — их нужно указывать с большой буквы.

Например, для того чтобы преобразовать строку в число, нужно написать такое выражение:

n = Number("2004");

Если же Flash не сможет выполнить заданное преобразование типов, будет возвращено значение null.

Приоритет операторов

Последний вопрос, который мы здесь рассмотрим, — это приоритет операторов. Как мы помним, приоритет влияет на порядок, в котором выполняются операторы в выражении.

Пусть имеется следующее выражение:

а = b + с — 10;

В этом случае сначала к значению переменной b будет прибавлено значение с, а потом из суммы будет вычтено 10. Операторы этого выражения имеют одинаковый приоритет и поэтому выполняются строго слева направо.

Теперь рассмотрим такое выражение:

а = b + с * 10;

А в этом случае сначала будет выполнено умножение значения с на 10, а уже потом к полученному произведению будет прибавлено значение b. Оператор умножения имеет больший приоритет, чем оператор сложения, поэтому порядок "строго слева направо" будет нарушен.

Самый низкий приоритет имеет оператор присваивания =. Вот почему сначала вычисляется само выражение, а потом его результат присваивается переменной.

В общем, основной принцип выполнения всех операторов таков: сначала выполняются операторы с более высоким приоритетом, а уже потом — операторы с более низким. Операторы с одинаковым приоритетом выполняются в порядке их следования (слева направо).

В табл. 19.9 перечислены все изученные нами операторы в порядке убывания их приоритетов. Полную таблицу приоритетов можно найти в интерактивной справке Flash.

Внимание!

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

Но что делать, если нам нужно нарушить обычный порядок выполнения операторов? Воспользуемся скобками. При такой записи заключенные в скобки операторы выполняются первыми.

а = (b + с) * 10;

В этом случае сначала будет выполнено сложение значений переменных b и с, а потом получившаяся сумма будет умножена на 10.

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

а = ((b + с) * 10 — d) /2 + 9;

Здесь операторы будут выполнены в такой последовательности:

1. Сложение b и с.

2. Умножение полученной суммы на 10.

3. Вычитание d из произведения.

4. Деление разности на 2.

5. Прибавление 9 к частному.

Если удалить скобки:

a=b+c*10-d/ 2 + 9;

то порядок выполнения операторов будет таким:

1. Умножение с и 10.

2. Деление d на 2.

3. Сложение b и произведения с и 10.

4. Вычитание из полученной суммы частного от деления d на 2.

5. Прибавление 9 к полученной разности.

Получается совсем другой результат, не так ли?

 

Комментарии

Очень часто при написании сценариев возникает потребность поместить в код ActionScript какие-либо примечания для себя или коллег по работе. Для этого используются особые выражения языка ActionScript, так называемые комментарии. Комментарии не обрабатываются Flash и исключаются из сценариев при экспорте фильма, поэтому в них можно писать все что угодно.

Для вставки комментариев в код ActionScript предусмотрены два оператора комментария: // и /*. */. Первый из них позволяет вставить в конец выражения однострочный комментарий:

// Строка комментария

а = b + с; // Это однострочный комментарий

Заметим, что комментарий ставится после точки с запятой, обозначающей конец выражения.

А оператор /*…*/ позволяет вставить в код программы комментарий любого размера:

/*

В этом выражении мы складываем содержимое двух переменных и помещаем результат в третью */

а = b + с;

 

Сложные выражения ActionScript

 

Рассмотрение основных понятий ActionScript мы закончили. Можно приступать к изучению более сложных вопросов. И начнем мы с написания так называемых сложных выражений.

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

 

Блоки

ActionScript позволяет нам объединить несколько выражений в одно. Такое выражение называется блочным выражением или просто блоком. Для выделения блочного выражения составляющие его выражения заключаются в фигурные скобки, например:

{

b = "12";

с = а — b;

}

Как правило, блоки не используются сами по себе. Чаще всего они входят в состав других сложных выражений. Также с их помощью пишутся обработчики событий.

 

Условные выражения

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

Что может служить условием в условном выражении? Значение логической переменной или результат вычисления логического выражения. В качестве же выражений, которые должны быть выполнены или не выполнены, в зависимости от условия, могут быть использованы блоки.

Условное выражение имеет следующий формат:

if

( <Условие>).

<Блок "то">

else

<Блок "иначе ">

"Вырожденный" формат его выглядит так:

if ( <Условие>).

<Блок "то">

Для написания условных выражений используются особые ключевые слова if и else (в приведенных выше примерах они выделены полужирным шрифтом). Условие — это и есть логическое выражение, в соответствии с которым Flash принимает решение, какой блок выполнить. Если условие имеет значение true ("истина"), то выполняется блок "то". Если же условие имеет значение false ("ложь"), то выполняется блок "иначе" (если он присутствует в условном выражении). Если же блок "иначе" отсутствует, выполняется следующее выражение сценария.

Рассмотрим несколько примеров.

if (х == 1) {

а = "Единица";

b = 1;

}

else {

а = "Не единица";

b = 22222;

}

Здесь мы сравниваем значение переменной х с единицей и в зависимости от результатов сравнения присваиваем переменным f и h разные значение. Обратим внимание на условие — именно так записывается оператор сравнения, в скобках.

Условие может быть довольно сложным:

if ((х == 1) && (у > 10))

f = 3;

else

f = 33;

Здесь мы использовали сложное условие, возвращающее значение true в случае, если значение переменной х равно единице и значение переменной у больше десяти. Заметим также, что мы подставили одиночные выражения, так как фрагменты кода слишком просты, чтобы оформлять их в виде блоков.

Если условное выражение совсем простое, мы можем записать его немного по-другому. А именно, воспользоваться условным оператором?:

<Условиe>? <Выражение "то">: <Выражение "иначе">;

Достоинство этого оператора в том, что он может быть частью выражения. Например:

f = (х == 1 && у > 10)? 3: 33;

Фактически мы записали условное выражение из предыдущего примера, но в виде обычного арифметического выражения. Компактность кода налицо. Недостаток же оператора? в том, что с его помощью можно записывать только самые простые условные выражения.

 

Выражения выбора

Выражение выбора — это фактически несколько условных выражений, объединенных в одном.

Его формат таков:

switch ( <Условиe>) {

case <Значение 1>:

<Блок 1>

[break;]

[ case   <Значение 2>:

<Блок 2>

[break;]]

<… Другие секции case>

[ default :

<Блок, исполняемый для остальных значений>]

}

В выражениях выбора используются ключевые слова switch, case и default (выделены полужирным шрифтом).

Давайте выясним, как выполняется выражение выбора. Результат вычисления условия последовательно сравнивается со значением 1, значением 2 и т. д. и, если такое сравнение увенчалось успехом, выполняется соответствующий блок кода (блок 1, блок 2 и т. д.). Если же ни одно сравнение не увенчалось успехом, выполняется блок кода, находящийся в секции default (если, конечно, она есть).

Пример использования выражения выбора:

switch (а) {

case 1:

out = "Единица";

break;

case 2:

out = "Двойка";

break;

case 3:

out = "Тройка";

break;

default:

out = "Другое число";

}

Встретив действие break, Flash прерывает выполнение блока, в котором оно присутствует, и начинает выполнение кода, следующего за выражением выбора. Если его опустить, то будет выполнен следующий блок. Так, если значение условия совпало со значением 1 и был выполнен блок 1, не содержащий действия break, будет также выполнен блок 2.

Давайте уберем все действия break в нашем примере:

switch (а) {

case 1:

out = "Единица";

case 2:

out = "Двойка";

case 3:

out = "Тройка";

default:

out = "Другое число";

}

В этом случае все блоки будут выполняться последовательно, один за другим. И переменной out всегда будет присваиваться строка "Другое число".

 

Циклы

Циклы — это особые выражения, позволяющие выполнить один и тот же блок кода несколько раз. Выполнение кода прерывается по наступлению некоего условия.

ActionScript предлагает программистам несколько разновидностей циклов. Рассмотрим их.

Цикл со счетчиком

Цикл со счетчиком используется, если какой-то код нужно выполнить определенное число раз. Это наиболее часто используемый вид цикла.

Для подсчета того, сколько раз был выполнен этот фрагмент кода, используется переменная, называемая счетчиком цикла. Перед каждым выполнением блока кода производится проверка значения счетчика и, если оно достигло предельного значения, блок выполняется. Сам же этот блок называется телом цикла.

Цикл со счетчиком записывается так:

for ( <Выражение инициализации >; <Условие>; <Приращение>)

<Тело цикла>

Для задания цикла со счетчиком используется ключевое слово for. Поэтому такие циклы часто называют "циклами for".

Выражение инициализации присваивает счетчику начальное значение. Далее проверяется условие цикла, и, если его значение истинно (true), выполняется тело цикла. После этого выполняется выражение приращения, изменяющее значение счетчика, затем снова проверяется условие, и т. д., пока условие не станет ложным (false), т. е. пока счетчик не дойдет до предельного значения.

Пример цикла со счетчиком:

for (i =1; i < 11; i++) {

a += 3;

b = i * 2 + 1;

}

Этот цикл будет выполнен 10 раз. Мы присваиваем счетчику i начальное значение 1 и после каждого выполнения тела цикла увеличиваем его на единицу. Цикл перестанет выполняться, когда значение счетчика увеличится до 11, и условие цикла станет ложным.

Кроме того, допустимо использовать счетчик цикла в одном из выражений тела цикла — как это сделали мы. Счетчик i будет содержать последовательно возрастающие значения от 1 до 10, которые можно использовать в вычислениях.

Приведем еще два примера цикла со счетчиком:

for (i = 10; i > 0; i—) {

a += 3;

b = i * 2 + 1;

}

Здесь значение счетчика декрементируется. Начальное его значение равно 10. Цикл выполнится 10 раз и завершится, когда счетчик i будет содержать 0; при этом значения последнего будут последовательно уменьшаться от 10 до 1.

for (i = 2; i < 21; i += 2) b = i * 2 + 1;

А в этом примере начальное значение счетчика равно 2, а конечное — 21, но цикл выполнится опять же 10 раз. А все потому, что значение счетчика увеличивается на 2 и последовательно принимает значения 2, 4, 6… 20.

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

Цикл с постусловием

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

Причем условие проверяется не до, а после выполнения тела цикла, отчего цикл с постусловием и получил свое название. Такой цикл выполнится хотя бы один раз, даже если его условие с самого начала ложно.

Формат цикла с постусловием:

do

<Тело цикла>

while ( <Условиe >);

Для задания цикла с постусловием используются ключевые слова do и while. Поэтому такие циклы часто называют "циклами do-while".

Цикл с постусловием можно использовать различными способами. Например, так:

do {

а = а * i + 2; i = ++i;

} while (a < 100);

В рассмотренном выше примере проверяется наступление некого отвлеченного условия.

А можно записать такой цикл так:

var а = 0, i = 1; do {

а = а * i + 2;

i = ++i;

} while (i < 20);

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

Цикл с предусловием

Цикл с предусловием отличается от цикла с постусловием тем, что условие проверяется перед выполнением тела цикла. Так что, если оно (условие) изначально ложно, цикл не выполнится ни разу.

while ( <Условиe>)

<Тело цикла>

Для создания цикла с постусловием используется ключевое слово while. Поэтому такие циклы называют еще "циклами while" (не путать с "циклами do-while"!).

Пример цикла с предусловием:

while (а < 100) {

а = а * i + 2;

i = ++i;

}

Прерывание и перезапуск цикла

Иногда бывает нужно прервать выполнение цикла. Для этого Flash предоставляет программистам действия break и continue.

Действие break позволяет прервать выполнение цикла и перейти к следующему за ним выражению.

while (а < 100) {

а = а * i + 2;

if (а > 50) break;

i = ++i;

}

В этом примере мы прерываем выполнение цикла, если значение переменной а превысит 50.

Собственно, мы уже знакомы с действием break. Оно использовалось в выражении выбора, где вело себя точно так же.

Действие continue позволяет перезапустить цикл, т. е. оставить невыполненными все последующие выражения, входящие в тело цикла, и запустить выполнение цикла с самого его начала: проверка условия, приращение счетчика и выполнение тела и т. д.

while (а < 100) {

i = ++i;

if (i > 9 && i < 11) continue;

a = a * i + 2;

}

Здесь мы пропускаем выражение вычисления а для всех значений i от 10 до 20.

 

Функции

 

Функция — это особым образом написанный и оформленный фрагмент кода ActionScript, который можно вызвать из любого места любого сценария. Фактически функция — это повторно используемый участок кода, который, будучи написанным один раз, может быть вызван где угодно, кем угодно и сколько угодно раз. Так что, если какой-то фрагмент кода встречается в нескольких местах вашего сценария или сценариев, лучше всего оформить его в виде функции.

Собственно код, ради которого и была создана функция, называется телом функции. Каждая функция, кроме того, должна иметь уникальное имя, по которому к ней можно будет обратиться. Функция также может принимать один или несколько параметров и возвращать результат, который можно использовать в выражениях.

 

Объявление функций

Прежде чем функция будет использована где-то в сценарии, ее нужно объявить. Объявление функции выполняется с помощью ключевого слова

function.

function <Имя> ( [<Список параметров, разделенных запятыми>])

<Тело функции>

Имя функции, как уже говорилось, должно быть уникально в пределах ее области видимости. Для имен функций действуют те же правила, что и для имен переменных.

Список параметров представляет собой набор переменных, в которые при вызове функции будут помещены значения переданных ей параметров. Мы можем придумать для этих переменных любые имена — все равно они будут использованы только внутри тела функции. Это так называемые формальные параметры функции.

Список параметров функции помещается в круглые скобки, а сами параметры отделяются друг от друга запятыми. Если функция не требует параметров, скобки все равно нужно указать.

В пределах тела функции над принятыми ею параметрами (если они есть) и другими данными выполняются некоторые действия и, возможно, вырабатывается результат. Чтобы вернуть результат из функции в выражение, из которого она была вызвана, используется действие return:

return <Переменная или выражение>;

Здесь переменная должна содержать возвращаемое значение, а выражение должно его вычислять.

Пример объявления функции:

function divide(а, b) {

var с;

с = а / b;

return с;

}

Данная функция принимает два параметра — а и b, — после чего делит а на b и возвращает частное от этого деления. При этом для хранения промежуточного результата она использует собственную (так называемую локальную) переменную с. Такие переменные "видимы" только внутри тела этой функции. При завершении выполнения функции значения всех локальных переменных теряются.

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

Функции, объявленные в сценариях, привязанных к кадрам, кнопкам и вложенным клипам текущего клипа, "видимы" только в пределах этих сценариев (функции уровня клипа). Чтобы сделать функцию доступной во всех сценариях фильма (определить ее как глобальную), нужно использовать модификатор _globai:

function _global.glDivide(a, b) { return a / b; }

 

Вызов функций

После того как мы объявили функцию, мы можем вызвать ее из любого места кода в пределах области видимости. Для этого используется следующий формат:

< Имя функции> ( [<Список фактических параметров, разделенных запятыми>])

Здесь указывается имя нужной функции и в круглых скобках перечисляются фактические параметры, над которыми нужно выполнить соответствующие действия. Функция вернет результат, который можно присвоить переменной или использовать в сложном выражении.

Внимание!

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

Вот пример вызова объявленной нами выше функции divide:

d = divide(3, 2);

Здесь мы подставили в выражение вызова функции фактические параметры — константы 3 и 2.

s = 4* divide (х, r) + у;

А здесь мы выполняем вызов функции с переменными в качестве фактических параметров.

Если функция не возвращает результата, то она вызывается вот так:

initVars (1, 2, 3, 6);

Более того, таким образом можно вызвать и функцию, возвращающую результат, который в этом случае будет отброшен. Такой способ вызова может быть полезен, если результат, возвращаемый функцией, не нужен для работы сценария.

При вызове функции простым указанием ее имени будет вызвана функция уровня клипа. Если же функции с этим именем не будет найдено, Flash вызовет глобальную функцию с таким же именем (если она есть). Чтобы вызвать функцию, находящуюся в другом клипе, нужно, как и в случае с переменной, указать имя этого клипа перед именем функции, отделив его точкой, например:

someClip.initVars(1, 2, 3, 6);

 

Рекурсия

И еще один важный вопрос, связанный с вызовом функций.

Мы уже узнали, что функции могут вызывать другие функции, конечно, если те уже определены. Но функции могут также вызывать и сами себя. Такой прием программирования называется рекурсией и иногда бывает очень полезен.

Если в теле функции написать команду ее вызова, то функция будет вызывать себя до бесконечности (так называемая бесконечная рекурсия). В конце концов, это приведет к аварийному завершению самого Flash, а то и к краху всей операционной системы. Поэтому функция, предназначенная для рекурсивного вызова, должна предусматривать возможность выхода из этого цикла вызовов. Стандартного способа осуществить это нет, поэтому решение для каждого конкретного случая нужно искать особо.

Приведем пример функции, написанной специально для применения ее в рекурсии:

function factorial (а) {

if (а == 0) {

return 1;

else

return (a * factorial(a — 1));

}

Эта функция вычисляет факториал числа а, переданного ей в качестве параметра. Она рекурсивно вызывает сама себя для того, чтобы получить факториал числа а — 1. Также в ее теле выполняется проверка условия равенства а нулю; если это условие истинно, возвращается единица, после чего дальнейших рекурсивных вызовов не производится, а все уже сделанные "хором" завершаются. Таким образом, данная функция имеет защиту от бесконечной рекурсии, ведь когда-нибудь она все равно получит в качестве аргумента ноль.

 

Массивы

 

Мы уже довольно много знаем о переменных и работе с ними. Но наши знания все еще неполны. Так, мы ничего пока не знаем о массивах — особом способе хранения данных, доступном в ActionScript. Давайте же выясним, что это такое.

 

Создание массивов и работа с ними

Массив — это пронумерованный набор переменных одного типа, называемых элементами массива. Доступ к нужному элементу массива выполняется по его порядковому номеру, называемому индексом. А общее число элементов массива называется его размером.

Внимание!

Нумерация элементов массива начинается с нуля.

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

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

var someArray;

someArray = [1, 2, 3, 4];

Здесь мы создали массив, содержащий четыре элемента, и присвоили его переменной someArray. После этого мы можем получить доступ к любому из элементов по его индексу, указав его после имени переменной массива в квадратных скобках:

а = massive [2];

В данном примере мы получили доступ к третьему элементу массива. (Нумерация элементов массива начинается с нуля — помните об этом!)

Определять сразу все элементы массива необязательно:

someArray2 = [1, 2, 4];

Здесь мы пропустили третий элемент массива, и он остался неопределенным (т. е. будет содержать значение undefined).

Если будет нужно, мы легко сможем добавить к массиву еще один элемент, просто присвоив ему требуемое значение. Вот так:

someArray[4] = 9;

При этом будет создан новый, пятый по счету, элемент массива с индексом 4 и значением 9.

Можно даже сделать так:

someArray[7] = 9;

В этом случае будут созданы четыре новых элемента, и восьмой элемент получит значение 9. Пятый, шестой и седьмой останутся неопределенными (undefined).

Мы можем присвоить любому элементу массива другой массив (или, как говорят опытные программисты, создать вложенный массив).

someArray[2] = ["nl", "n2", "n3"];

После этого можно получить доступ к любому элементу вложенного массива, указав последовательно оба индекса:

stг = someArray[2][1];

Переменная str получит в качестве значения строку, содержащуюся во втором элементе вложенного массива, — "n2".

Оператор typeof возвращает для массива строку "object". Это значит, что массив имеет объектный тип (об объектах см. далее в этой главе).

 

Ссылки

Осталось рассмотреть еще один момент, связанный с организацией программного доступа к данным. Это так называемые ссылки — своего рода указатели на массивы и объекты, в действительности хранящиеся в соответствующих им переменных (мы обязательно столкнемся с ними, когда начнем работать с массивами и объектами).

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

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

Рассмотрим такой пример:

var myArray = ["Flash", "MX 2004"];

var newArray = myArray;

Здесь создается массив myArray с двумя элементами и далее он присваивается переменной newArray (при этом данная переменная получает ссылку на массив). Если потом мы присвоим новое значение второму элементу массива myArray:

myArray[1] = "8";

и обратимся к нему через переменную newArray:

s = newArray[1];

то переменная s получит строку "8" — новое значение второго элемента этого массива. Т. е. фактически переменные myArray и newArray указывают на один и тот же массив.

 

Объекты

 

Итак, мы познакомились с типами данных, переменными, константами, операторами, действиями, простыми и сложными выражениями, функциями и массивами. Теперь настала пора узнать о самых сложных структурах данных ActionScript — объектах.

 

Понятия объекта и экземпляра

Объект — это сложный тип данных, включающий в себя множество переменных — свойств — и набор функций для манипулирования значениями этих переменных — методов. Здесь все достаточно просто: свойства хранят некие данные, а методы их обрабатывают, выдавая на выходе другие данные или совершая действия с самим объектом. Каждый объект должен иметь уникальное имя, по которому к нему можно обратиться.

Собственно, сам объект — это всего лишь тип данных, такой же, как числовой или строковый, т. е. некое абстрактное описание, включающее в себя набор свойств и методов. От объекта порождаются конкретные его "представители" — экземпляры объекта. Не правда ли, напрашивается аналогия образца и созданных на его основе экземпляров?

Объект можно представить себе как некий прибор, снабженный набором регуляторов и кнопок. Регуляторы задают значения свойств, а кнопки запускают на выполнение методы. Мы можем заполучить один из приборов данного типа (экземпляр), выставить нужные значения свойств с помощью регуляторов и нажать какую-либо кнопку, инициировав выполнение соответствующего метода. Внутреннее устройство этого прибора от нас скрыто, мы не знаем, что у него внутри, для нас важно только одно — чтобы он выполнял свою задачу.

Теперь давайте вернемся к нашему любимому Flash. Любой клип на его рабочем листе фактически является экземпляром объекта movieClip (об этом объекте мы поговорим далее в этой главе). Пусть имеется клип someClip, обладающий свойством width (ширина) и методом gotoAndPlay, запускающим воспроизведение анимации этого клипа с какого-то кадра. Тогда можно написать такой сценарий:

someClip.width = 200;

someClip.gotoAndPlay(3);

Здесь мы обратились к методу и свойству объекта someClip, использовав уже знакомый нам синтаксис "с точкой". А именно, отделили точкой имя объекта от имени свойства (метода).

Итак, с теорией мы разобрались. Приступим теперь к практической работе с объектами и их экземплярами.

 

Работа с объектами и их экземплярами

Перед тем как начать работу с экземпляром какого-либо объекта, его нужно создать. Создание экземпляра объекта выполняется с помощью оператора new:

<Переменная> = new <Имя объекта>([<Список параметров, разделенных запятыми>] )

После создания экземпляра объекта оператор new возвращает ссылку на него. Эта ссылка, как правило, присваивается какой-либо переменной.

Список параметров может как присутствовать, так и отсутствовать. Обычно он содержит значения, которые присваиваются свойствам экземпляра при его создании. А то, какие значения каким свойствам присваиваются, можно узнать из описания данного объекта в интерактивной справке Flash.

Вот пример создания экземпляра obj некоего объекта someObject:

var obj;

obj = new someObject(a, b);

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

obj.prop1 = 0;

а = obj.prop2 + 2;

obj.method1();

Иногда бывает, что один объект содержит внутри себя другие объекты (так называемые внутренние). Для обращения к свойствам и методам внутренних объектов используется тот же синтаксис, но обладающий, скажем так, "повышенной этажностью":

outerObject.innerObject.prop = 0;

где outerObject — экземпляр внешнего объекта (имеющего в своем составе внутренние объекты), a innerObject — экземпляр внутреннего объекта.

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

obj ectOuter.obj ectInner.obj ectInnerlnner.prop = 10;

Как и в случае массива, мы можем присваивать ссылку на экземпляр объекта другой переменной:

obj 2 = obj;

Чтобы удалить ненужный экземпляр, следует использовать оператор delete:

delete <Переменная, содержащая ссылку на экземпляр объекта >;

Например,

delete obj, obj 2;

Внимание!

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

Оператор typeof возвращает для экземпляра объекта строку "object". Это значит, что экземпляр объекта имеет объектный тип данных.

На заметку

Очень часто Flash сам создает экземпляры каких-либо объектов и сам же их удаляет. В частности, именно так происходит с экземплярами объекта Movieclip, т. е. клипами.

 

Несколько новых операторов и ключевых слов

А теперь самое время рассмотреть несколько новых операторов и действий, применяемых при работе с объектами и их экземплярами.

Оператор instanceof проверяет, является ли экземпляр экземпляром заданного объекта, и возвращает соответственно значение true или false. Формат его записи такой:

<Переменная> = <Экземпляр объекта> instanceof <Объект>;

В приведенном ниже примере экземпляр задается в виде переменной, содержащей ссылку на него, а объект — в виде имени объекта.

if (obj instanceof someObject).

Ключевые слова for и in служат для организации так называемого цикла просмотра, позволяющего просмотреть все свойства экземпляра объекта. Он также называется "циклом for-in" и имеет следующий формат записи:

for ( <Переменная-ссылка на свойство> in < Экземпляр объекта>)

<Тело цикла>

Переменная-ссылка на свойство каждый раз получает значение очередного свойства экземпляра. Эту переменную можно использовать для получения доступа к найденному свойству.

for (k in obj) {

k = ' ' + k + ' ';

}

Приведенный фрагмент сценария просматривает все свойства экземпляра obj и добавляет к значению каждого из них пробелы слева и справа. (Предполагается, что значения всех свойств этого экземпляра имеют строковый тип.)

Ключевое слово with позволяет значительно сократить длину выражений ActionScript, если в них используются свойства или методы какого-либо одного экземпляра объекта. Рассмотрим его применение на примере.

Напишем несколько выражений, обращающихся к свойствам и методам экземпляра какого-либо объекта:

someObject.propl = 1;

someObject.prop2 = 2;

someObj ect.prop3 = 3;

someObj ect.method1;

Какие длинные строки у этих выражений! А теперь перепишем их, использовав ключевое слово with:

with (someObject){

propl = 1;

prop2 = 2;

prop3 = 3;

methodl;

}

Сценарий сразу стал компактнее. И быстрее, кстати говоря.

 

Встроенные объекты ActionScript

Встроенными называются объекты, реализованные в самом языке ActionScript. В этом разделе будут рассмотрены их краткие описания и даны примеры использования. Полное описание всех этих объектов можно найти в интерактивной справке Flash.

Интересной особенностью языка ActionScript является то, что он может представлять обычные типы данных — строковый, числовой, логический — как объекты. Поэтому со строками, числами и логическими величинами можно обращаться как с экземплярами соответствующих объектов, вызывать их методы и использовать их свойства. Львиная доля встроенных объектов ActionScript как раз и "отвечает" за объектное представление обычных типов данных.

Объект String

Объект String представляет собой обычную строку. Пользуясь его свойствами и методами, можно выполнять различные манипуляции над строками.

Создать экземпляр объекта String можно одним из двух способов, как показано в следующих примерах:

var s = new String("Flash");

var s = "Flash";

Как правило, чаще используется второй способ — он и компактнее в записи, и привычнее.

Свойство length объекта String позволяет получить (или, как говорят программисты, "возвращает") длину строки в символах. Например:

1 = s.length;

Метод сharAt объекта String возвращает символ строки, номер позиции которого в строке был передан в качестве единственного параметра метода:

ch = s.charAt(s.length — 1);

Внимание!

Нумерация символов строки начинается с нуля.

После выполнения выражения из приведенного примера в переменной ch окажется предпоследний символ строки s.

Метод indexof возвращает номер вхождения подстроки в строку. Если подстрока не найдена, возвращается — 1. При этом можно вторым параметром передать в метод номер вхождения, с которого начнется поиск:

<Строка>. indexOf (<Подстрока>, [<Номер вхождения >])

Например:

s = "Macromedia Flash 8";

n = s.indexOf("a", 2);

После выполнения этого сценария в переменной п окажется число 13 — именно под таким номером стоит символ "а" в слове "Flash".

Метод last indexOf схож с методом indexOf, только ищет подстроку не слева направо, а справа налево, т. е. с конца строки.

Методы toLowerCase и toUpperCase преобразуют все символы строки соответственно к нижнему и верхнему регистру.

Объект Number

Объект Number представляет собой обычное число. Пользуясь его свойствами и методами, мы можем выполнять различные манипуляции над числовыми данными.

Создается экземпляр объекта Number одним из двух способов:

var n = new Number(232);

var n = 232;

Второй способ нам уже знаком, поэтому будем пользоваться им и впредь. Метод toString объекта Number возвращает строковое представление числа:

s = n.toString ();

Помимо данного метода, объект Number имеет ряд свойств, возвращающих различные "специальные" значения. Так, свойства MIN_VALUE и MAX_VALUE позволяют узнать соответственно минимальное (примерно 5×10-324) и максимальное (примерно 1,79×10308) значения, которые могут быть присвоены числовой переменной ActionScript. А свойства NEGATIVE_INFINITY и POSITIVE_INFINITY возвращают соответственно значения — ∞ и ∞.

Объект Boolean

Объект Boolean представляет собой обычную логическую величину. С его помощью можно выполнять различные манипуляции над логическими данными.

Создается экземпляр объекта Boolean одним из двух приведенных ниже способов:

var b = new Boolean(true);

var b = true;

Метод toString объекта Boolean возвращает строковое представление логической величины — "true" или "false" соответственно:

s = b.toString ();

Объект Date

Объект Date предназначен для хранения значения даты и времени, закодированных особым способом в виде числа.

Экземпляр объекта Date создается так:

var <Имя переменной> = new Date( [<Год>, <Месяц>, [<Число>

[, <Часы >[, <Минуты> [, <Секунды> [, <Миллисекунды >]]]]]])

Вот краткое описание приведенных выше параметров:

□ Год может быть задан двумя или четырьмя цифрами. С четырьмя цифрами все просто; если же год задан двумя цифрами, то значение 0 соответствует 1900 году, а 99 — 1999 году;

□ Месяц задается значением от 0 (январь) до 11 (декабрь);

□ Дата задается значением от 1 до 31;

□ Минуты и Секунды задаются значениями от 0 до 59;

□ Миллисекунды задаются значением от 0 до 999.

Если же ни один из параметров не указан, в экземпляр объекта Date заносится текущая дата.

Объект Date имеет огромное количество методов, возвращающих или задающих различные "части" значения даты. Так, метод getMonth возвращает текущее значение месяца, а метод setMonth позволяет задать месяц, не меняя других "частей" даты. А уже знакомый нам метод toString возвращает строковое представление даты, используя региональные установки операционной системы.

Объект Array

Объект Array представляет собой массив. С его помощью можно выполнять над массивами различные манипуляции.

Создать массив можно одним из четырех приведенных ниже способов:

var arr = new Array();

var arr = new Array (<Размер>) ;

var arr = new Array(< Список элементов, разделенных запятыми>) ;

var arr = [<Список элементов, разделенных запятыми>] ;

Последний способ нам уже знаком — именно так мы создавали наши первые массивы. При использовании первого способа созданный массив будет иметь нулевой размер, т. е. не будет содержать ни одного элемента. При создании массива вторым способом все его элементы будут содержать значение undefined.

Свойство length объекта Array позволяет нам узнать размер массива.

1 = arr.length;

Метод reverse объекта Array изменяет порядок следования элементов массива на противоположный. А метод toString возвращает строку, содержащую значения всех элементов массива, разделенные запятыми.

Объект Math

Объект Math предоставляет доступ к встроенным константам и математическим и тригонометрическим функциям языка ActionScript. Единственный экземпляр этого объекта создается самим Flash.

Методы sin, cos и tan объекта Math позволяют вычислить соответственно синус, косинус и тангенс угла, заданного в радианах. Метод sqrt вычисляет квадратный корень. Метод pow (х, у) возводит х в степень у.

Кроме того, объект Math имеет несколько свойств, возвращающих значение различных математических констант. Так, свойство PI возвращает значение числа π. А свойство Е возвращает значение основания натурального логарифма.

Объект Object

Объект object — простейший из объектов, предоставляемых языком ActionScript. Он обладает минимальным набором свойств и методов и служит для создания на его основе других объектов и различных вспомогательных целей.

 

Работа с клипами

 

Продолжаем изучение языка ActionScript. Поговорим о клипах (в смысле, экземплярах образцов-клипов) и выясним, какие инструменты для работы с ними предоставляет ActionScript. А таких инструментов немало…

Все находящиеся на рабочем листе клипы, для которых было задано имя, равно как и сам фильм, представляют собой экземпляры объекта MovieClip. Их создает сам Flash; нам же остается только использовать их свойства и методы.

Все клипы имеют тип данных "клип". Оператор typeof при передаче ему в качестве параметра клипа вернет строку "movieclip".

 

Доступ к нужному клипу

Прежде чем приступить к изучению объекта movieClip, нам следует выяснить, как же получить доступ к его экземплярам, т. е. клипам и самому фильму.

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

Задав имя клипа, мы можем получить к нему доступ из сценария. Так, если на рабочем листе присутствует клип саг, то для остановки вложенной в него анимации мы можем создать во внешней анимации такой сценарий, привязав его, скажем, к кнопке:

car.stop();

Здесь мы указываем имя соответствующего экземпляра объекта movieClip и, через точку, — метод stop, останавливающий воспроизведение анимации.

Если же мы хотим остановить вложенную анимацию клипа car из самого этого клипа, то нам нужно слегка изменить написанный нами сценарий:

this.stop();

и поместить его в этот клип. Модификатор this указывает на текущий экземпляр объекта, т. е. на клип car.

Мы можем вообще опустить модификатор this и записать наш сценарий коротко:

stop();

Но так делать не рекомендуется.

Если же нам нужно остановить воспроизведение вложенной анимации клипа wheel, являющегося составной частью клипа car, нам следует написать такой сценарий:

car.wheel.stop();

Здесь мы написали последовательно имена клипов car и wheel, разделив их точкой. Фактически мы осуществили доступ к внутреннему объекту.

Подведем итог. Чтобы получить доступ к методу или свойству какого-либо клипа, нужно перечислить имена всех клипов, в которые он вложен, через точку (создав таким образом путь), а уже потом указать нужный метод или свойство. Причем имена клипов указываются в порядке увеличения уровня вложенности в текущий клип (тот, который содержит сценарий). Если же нужно получить доступ к методу или свойству текущего клипа (к которому привязан данных сценарий), достаточно указать только этот метод или свойство.

Если нам нужно обратиться к методу или свойству анимации основного фильма из вложенного в нее клипа, мы воспользуемся модификатором _root. Так, мы можем поместить в клип wheel сценарий

_root.stop();

который остановит воспроизведение внешней анимации.

Чтобы получить доступ к внешнему объекту из внутреннего, используется модификатор _parent. Так, сценарий, помещенный в клип wheel:

_parent.stop();

остановит воспроизведение анимации клипа саг, в который вложен клип wheel.

А теперь необходимо заметить следующее. Пути доступа к клипам могут быть записаны двумя различными способами. И при написании сценариев мы уже использовали оба этих способа.

Во-первых, доступ к клипу можно получить по его абсолютному пути. Абсолютный путь всегда записывается, начиная от внешней анимации, для доступа к которой используется модификатор _root. Вот пример абсолютного пути (выделен полужирным шрифтом):

_root.car.wheel .gotoAndPiay(1);

Этот сценарий будет работать в любом вложенном клипе и в самой внешней анимации, поскольку путь доступа к нужному клипу всегда один и тот же.

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

Во-вторых, мы можем задать относительный путь. Относительный путь записывается относительно текущего клипа, в котором находится сценарий. Так, если нам нужно запустить воспроизведение анимации клипа car из сценария, находящегося в клипе wheel, мы напишем такой сценарий (относительный путь выделен полужирным шрифтом):

_parent .gotoAndPiay ( 1 );

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

Для примера напишем два выражения с разными видами путей и сравним их:

_parent.gotoAndPiay(1);

_root.car.gotoAndPiay (1);

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

_parent._parent.stop();

_root.stop();

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

_root.car.engine.electricPart.ignitor.spark();

Чтобы сократить их, можно использовать уже знакомое нам выражение с ключевым словом with:

with (_root.car.engine.electricPart) {

headlightLeft.on();

headlightRight.on();

ignitor.spark();

}

Для вставки в код сценария путей доступа к клипам панель Actions предоставляет специальные средства, а именно, кнопку, расположенную над областью редактирования кода:

При нажатии этой кнопки на экране появится диалоговое окно Insert Target Path (рис. 19.1).

Большую часть этого окна занимает иерархический список клипов, вложенных в основной фильм. (Сам основной фильм там также присутствует.) Переключатели Absolute и Relative, расположенные под списком, позволяют выбрать способ записи пути, соответствующий их названиям. А в поле ввода, расположенном над списком, мы можем ввести путь доступа к клипу вручную. И, разумеется, после задания нужного пути следует нажать кнопку ОК.

 

Управление воспроизведением анимации

Обычно каждый клип начинает воспроизводиться сразу же после загрузки и воспроизводится до последнего кадра его анимации. Однако, используя сценарии, мы можем управлять этими процессами, в частности, останавливать и запускать воспроизведение, а также воспроизводить фильм, начиная с заданного кадра.

Мы уже знакомы с методом stop объекта movieClip — он останавливает воспроизведение клипа. А чтобы запустить воспроизведение клипа с того места, где он был остановлен, нужно воспользоваться методом play:

car.play();

Для осуществления перехода на какой-либо кадр клипа служат методы gotoAndPlay и gotoAndstop. Первый выполняет переход на заданный кадр и начинает воспроизведение клипа с него. Второй же метод выполняет переход на заданный кадр, но воспроизведение не инициирует. В качестве единственного параметра оба этих метода принимают номер или имя кадра; причем если значение этого параметра имеет числовой тип, то оно трактуется как номер кадра, если строковый — то как его имя. Пример с использованием числового параметра:

car.gotoAndPlay(10);

Для управления текущим клипом можно пользоваться также действиями gotoAndPlay и gotoAndstop объекта movieClip.

Формат записи их вызова таков:

gotoAndPiay|gotoAndStop ([<Имя сцены>,]<Номер или имя кадра >);

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

gotoAndPiay(10);

gotoAndStop("Эпизод 1", х + 1);

Осталось упомянуть еще о двух методах объекта movieClip. Метод prevFrame перемещает бегунок на предыдущий кадр клипа, а метод next Frame — на следующий. Ни один из этих методов не принимает параметров.

Методы prevFrame и next Frame можно использовать, например, для создания средствами Flash презентации или слайд-шоу. Делается это так. Все изображения (слайды), которые должны войти в презентацию, помещают в отдельных кадрах фильма. К первому кадру фильма привязывается сценарий, содержащий одно-единственное выражение — stop (), которое остановит фильм на первом же кадре. После этого остается создать кнопки и привязать к ним сценарии, содержащие выражения this.prevFrame () и this.nextFrame (), которые будут выполнять переход соответственно на предыдущий и последующий кадр фильма, — и простейшее слайд-шоу готово!

 

Обработка событий, возникающих в клипах

Обработчики событий клипов имеют такой формат:

onClipEvent( <Событие>) {

<Тело обработчика>

}

Собственно, нам он уже знаком из главы 18. Вот пример такого обработчика:

onClipEvent(mouseDown) {

this.stop();

}

Этот обработчик выполняется в ответ на щелчок мышью на клипе и останавливает воспроизведение вложенной в него анимации. Его код должен быть привязан к самому клипу.

Внимание!

При написании обработчиков событий клипов крайне желательно использование модификатора this , возвращающего ссылку на текущий клип.

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

onClipEvent(mouseDown, mouseMove) {

stop();

}

Этот обработчик выполнится либо после щелчка мышью на клипе (событие mouseDown), либо после перемещения над клипом курсора мыши (событие mouseMove).

Теперь самое время выяснить, какие события поддерживаются объектом movieClip. Некоторые из них приведены в табл. 19.10; полный же список событий можно найти в интерактивной справке Flash.