События

Создать стройную классификацию событий клипов непросто по нескольким причинам. Во-первых, существует два подхода к реализации обработчиков — использование конструкций onCIipEvent и on (стиль Flash 5) и создание специальных методов (стиль Flash 6). Данные подходы достаточно радикально отличаются друг от друга (так, для них различно даже число потенциально доступных событий), и единообразно их описать невозможно. Во-вторых, события клипов чрезвычайно разноплановы. Некоторые из них генерируются плейером при изменениях, возникающих при проигрывании фильма, другие основываются на действиях со стороны пользователя. Формально лишь часть событий, которые доступны клипам, являются «родными» для их класса. Остальные же относятся к классу Button, объекту Mouse, объекту Key. Впрочем, подобное деление справедливо, лишь если обработчики создаются в стиле Flash 6.

Учитывая описанные особенности, мы поступим следующим образом. Характеристику же каждому отдельному событию дадим исходя из современной модели событий ActionScript. Это оправданно, так как концепция событий Flash 5 довольно неудачна, и использовать ее, работая во Flash MX 2004, не имеет никакого смысла.

Создание обработчиков событий в стиле Flash 5
Исходя из модели событий Flash 6 (см.


главу 8) генератором события или его листенером может быть любой объект. Совсем иначе дело обстоит во Flash 5 ~ события присущи только клипам и кнопкам, причем обработчик события некоторого экземпляра должен размешаться строго на нем.

Создать обработчик в виде метода кода кадра было невозможно.

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

onClipEvent(event) {
Substances
}
где:

• onClipEvent — ключевое слово, объявляющее обработчик;
• event — идентификатор одного из 9 доступных событий (см. список ниже);
• substances — код, который должен быть проделан при наступлении события.Bo Flash MX клипам стали присущи «кнопочные» события. Причем их обработчики можно создавать не только в виде методов, но и используя ключевое слово on. Например:

// Этот код может располагаться не только на кнопке, но и на клипе
on (press) {
_xscale=_уscale+=10;

Таким образом, на клипе могут размешаться как обработчики onClipEvent(event), так и on(event).

Кнопкам же могут быть присущи только обработчики on(event).

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

• При применении модели событий Flash 5 для вас будут недоступными как часть событий самих клипов (onSetFocus и onKillFocus), так и события других объектов, листенером которых можно сделать клип при условии использования современной концепции событий.

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


Например, чтобы с каждым новым кадром менять значение некоторой переменной, придется создать отдельный клип, единственной целью существования которого будет слежение за событием enterFrame, Невозможно добавить обработчик события, основываясь на onClipEvent, на программно созданный клип или, тем более, пустой клип, «изготовленный» при помощи метода creareEmptyMovicClip().

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

Событие смены кадров (onEnterFrame)
Событие onEnterFrame происходит при смене кадров клипа. Точнее, ему соответствует момент времени, когда период, отведенный на показ одного кадра, заканчивается, после чего, если это возможно, должен осуществиться переход на новый кадр. Это означает, что событие onEnterFrarae возникает и тогда, когда реальной смены кадров не происходит (например, если клип содержит только один кадр или его проигрывание остановлено при помощи метода stop()).


Например:

createEmptyMovieClip("clip", 0); // Создаем пустой клип
// Проверяем, через какой промежуток времени сменяются кадры
clip.onEnterFrame = function():Void {
trace(getTimer()-time); // Выводит: 789 1086 1000 1000 1000 1000
time=getTimer();
};

Частота возникновения события onEnterFrame одинакова для всех клипов фильма и напрягшую зависит от установленной частоты смены кадров. Динамически изменить ее, равно как задать различной для разных клипов, невозможно. Частота смены кадров определяется при разработке фильма в окошке Frame Rate Инспектора Свойств рабочего поля. Максимальное ее значение составляет 120, минимальное — 0,01 кадра в секунду.

Момент смены кадров един для всех клипов фильма. Более того, он един и для всех проигрываемых в плейере фильмов. Из этого факта можно сделать несколько важных выводов:

• У всех клипов событие onEnterFrame будет происходить практически одновременно. Это справедливо и в том случае, если клипы были созданы с разницей во времени, даже приблизительно не делящейся нацело на период смены кадров.

• Частота смены кадров, характерная для проигрываемых в плейере фильмов, будет одинакова, даже если изначально для них были определены разные величины fps. Для всех фильмов будет использоваться частота, присущая тому из них, который располагается на нулевом уровне плейплейера. Следовательно, событие onEnterFrame для всех клипов всех фильмов будет наступать синхронно.

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

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

Во Flash 5 событие onEnterFrame было основным инструментом, позволяющим периодически выполнять некоторый код. Слабым его конкурентом были только циклы временной диаграммы. Во Flash MX появилась функция setInterval(), являющаяся более мощным (за счет отсутствия жесткой привязки к частоте кадров) средством для осуществления периодического выполнения кода. Однако, несмотря на это, обычно все равно используется соответствующее событие. Дело в том, что обноачение экрана плейера по умолчанию производится лишь при переходе на новый кадр. Следовательно, в большинстве случаев не имеет смысла пересматривать некоторую характеристику чаще, чем происходит смена кадров: все равно внесенное изменение не будет отображено. Использование же функции updateAfterEvent(), внепланово обновляющей экран, это роскошь, которую, ввиду резкого снижения производительности, можно позволить лишь при крайней необходимости. По причине более сложного синтаксиса и склонности к сбоям setInterval() применяется, лишь если вызов некоторой функции должен производиться объективно чаше, чем происходит смена кадров (например, если отслеживается момент начала движения указателя мыши), или же если активации функции должны осуществляться с частотой, существенно меньшей частоты смены кадров.

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

Событие загрузки клипа (onLoad)
Событие onLoad происходит при загрузке в клип или на уровень плейера внешнего swf-фильма с использованием функции loadMovie() или loadMovieNum(). Данное событие может быть чрезвычайно полезно, если некоторый код должен быть выполнен при появлении нового фильма или обновлении содержимого клипа.

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

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

createErTiptyMovieClip("mov", 0); // Создаем клип-контейнер
mov.loadMovie("1.swf"); // Загрузка фильма проходит успешно
mov.onLoad = function{) {
trace("Клип загружен"); // В Output ничего не появляется

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

createEmptyMovieClip("mov", 0); // Создаем клип-контейнер
//Делаем обработчик наследуемым
MovieClip.prototype.onLoad = function():Void {
if (this == mov) { // Проверяем, в нужный ли клип был подгружен фильм
trace("Клип загружен");
}
};
mov.loadMovie("1.swf"); // Выводит: Клип загружен (событие успешно
// зарегистрировалось)

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

// Создайте клип с именем mov и "повесьте" на него следующий код
onClipEvent (load) {
trace("Клип загружен");
}
// На кадр, на котором расположен клип mov, добавьте следующую строчку
mov.loadMovie{"1.swf"); // Подгружаем в клип фильм
// При тестировании в Output появляется: Клип загружен Клип загружен

В приведенном примере событие load было зарегистрировано дважды — это связано с тем, что при размещении обработчика на самом клипе фиксируется его собственное первое появление на временной шкале. Проще говоря, событием load клипа считается и его «рождение». Зарегистрировать первое появление клипа на рабочем поле (или его создание при помощи методов attachMovie(),duplicatcMovieClip() или createEmptyMovieClip()), используя наследуемый обработчик события onLoad, невозможно. Данное событие, задействованное в стиле Flash 6, способно «отлавливать» лишь загрузку в клип фильма.

Способность обработчиков onClipEvent(load) регистрировать первое появление клипа вряд ли может быть хоть как-то использована на практике. Скорее, это привнесет лишь дополнительные сложности при их применении с целью определения момента завершения загрузки в клип фильма.

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

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

Во Flash MX 2004 у события onLoad класса MovieClip появился мощный конкурент — событие onLoadComplete класса MovieClipLoader. Оно также позволяет фиксировать окончание закачки фильма в клип, однако существенно проще в использовании.

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

• Текущий кадр не содержит клипа, который имелся в кадре предыдущем.
• Клип был удален при помощи метода removeMovieClip().
• Клип удалился из-за создания на занимаемой им глубине другого клипа.
• Содержимое клипа было выгружено при помощи метода unloadMovie().
• В клип было подгружено новое содержимое при помощи метода loadMovie().

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

// Создайте клип и назовите его rnov. На том же кадре наберите следующей код:
// Обработчик для события cnLoad (наследуемый)
MovieClip.prototype.onLoad = function():Void {
if (this == mov) {
trace{"Клип загружен");
}
mov.onUnload = function() { // Обработчик для события onUnload
trace("Клип выгружен");
};
mov.loadMovie("1.swf"); // Подгружаем в клип внешний фильм
// В Output появляется: Клип выгружен Клип загружен

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

Создавать обработчики события onUnload в стиле Flash 5, в отличие от обработчиков события onLoad, нет никакого смысла. Обработчики-методы в данном случае обладают всеми теми же возможностями и столь же просты для задания, что и обработчики на базе onClipEvent.

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

Событие поступления данных (onData)
Событие onData возникает при поступлении в клип данных, импортируемых функцией loadVariables() или loadMovie(). Рассмотрим эти случаи по отдельности.

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

Импорт переменных осуществляется при помощи функции loadVariables(), Главная сложность ее использования заключается в том, что она не срабатывает моментально. То, когда поступят переменные, определяется только скоростью соединения и загруженностью сервера. А это означает, что код. который должен обработать переменные, нельзя набрать непосредственно после строчки с loadVariables(). Чтобы он не был проделан впустую, активизировать его надо тогда, когда переменные будут полностью загружены. Такому моменту соответствует событие onData того клипа, в который они импортируются.

Совсем с другими целями, чем в случае loadVariables(), используется событие onData при загрузке в клип внешнего фильма при помощи loadMovie(). При этом оно возникает не единожды, как при импорте переменных, а многократно — по мере поступления данных. Это позволяет применять событие onData, например, для создания прелоадеров. Впрочем, это не лучшее решение во Flash MX 2004. Сложности возникают из-за того, что событие onData регистрирует загрузку только целого кадра. Это означает, что даже если фильм занимает мегабайты, но в нем имеется только один кадр, то событие onData возникнет один раз. Из-за этого качественный анимированный предварительный загрузчик можно создать лишь в том случае, если в фильме достаточно много кадров и объекты распределены по ним относительно равномерно. Более технично применять для создания прелоадеров событие on Load Progress класса MovieClipLoader (или хотя бы обновлять его по событию onEnterFrame). Событие onData может пригодиться, если необходимо реагировать на окончание загрузки кадров (например, переводя на закачанный кадр проигрывающую головку).

Основная трудность в применении события onData по отношению к подгружаемому в клип фильму та же, что и в случае события onLoad: соответствующий обработчик при зачистке содержимого клипа попросту удаляется. Обойти эту проблему можно или сделав обработчик наследуемым, или создав его в стиле Flash 5.

События мыши (onMouseDown, onMouseUp, onMouseMove)
Если использовать терминологию современной модели событий, то все клипы по умолчанию являются листенерами трех событий, генерируемых объектом Mouse —onMouseDown (нажатие левой кнопки мыши), onMouseUp (отпускание левой кнопки мыши) и onMouseMove (перемещение указателя мыши) (новое событие onMouseWheel, соответствующее прокрутке колеса мыши, клипам недоступно). Впрочем, приведенное утверждение верно лишь формально. «Мышиные» события «слушались» клипами еще во времена Flash 5 — задолго до того, как стали атрибутом объекта Mouse. Поэтому фактически они являются собственными событиями клипов.

Так как в свое время мы посвятим рассмотрению объекта Mouse целую глазу, то сейчас ограничимся лишь кратким описанием соответствующих событий:

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

• onMouseUp. Данное событие неразрывно связано с onMouseDown. Оно происходит, когда нажатая левая клавиша мыши отпускается. Важным условием является нахождение указателя мыши в пределах окна плейера. Если курсор располагается вне его, onMouseUp зарегистрировано не будет.

• onMouseMove. Событие возникает при перемещении указателя мыши. Оно характеризует не начало движения курсора, а изменение его позиции. По этой причине при перемещении указателя событие onMouseMove генерируется непрерывно с чрезвычайно высокой частотой (до 100 и более вызовов в секунду). При «вылете» курсора за пределы окна плейера отслеживание изменения его положения прекращается.

На практике «мышиные» события играют огромную роль. Они позволяют реагировать на действия со стороны пользователя, обеспечивая пресловутую интерактивность Flash-фильмов. Без них невозможно было бы создание большинства игр, многих эффектов и компонентов.

События клавиатуры (onKeyDown, onKeyUp)
К событиям клавиатуры относятся:

• onKeyDown. Происходит при нажатии любой клавиши (кроме управляющих клавиш плейера);

• onKeyUp. Возникает при отпускании клавиши.

В отличие от «мышиных» событий, клипы по умолчанию не являются листенерами событий объекта Key. Тот факт, что onKeyDown и onKeyUp во встроенном словаре ActionScript внесены в список событий клипов, имеет исторический характер. Дело в том, что во Flash 5 события были присуши только клипам и кнопкам. Так как потребность в реагировании на нажатие или отпускание клавиш клавиатуры возникает очень часто, то соответствующие события были доступны при создании обработчиков на базе onClipEvent. Во Flash MX, за счет внедрения новой концепции событий, стало возможным сделать генератором событий onKeyDown и onKeyUp объект Key. Однако, так как обратная совместимость со старой моделью событий поддерживается, данные события принято считать присущими клипам и при использовании модели Flash 6, хотя фактически это не так.

Чтобы клипу были доступны события объекта Key, предварительно он должен быть зарегистрироан в качестве его листенера. Сделать это можно, используя метод addListener():

Key.addListener(mov); // Без этой строчки обработчик
// активизироваться не будет
mov.onKeyDown = function() {
trace ("Клавиша нажата");
};
Если обработчик создастся в стиле Flash 5, то клип способен «слушать» события клавиатуры изначально. В этом проявляется существенное различие между двумя моделями событий, для внешнего сглаживания которого onKeyDown и onKeyUp были внесены в список событий клипов.

Событие onKeyDown позволяет определить только факт нажатия клавиши, но не то, какая это кнопка. Чтобы узнать код задействованной клавиши, нужно обратиться к методу getCode() объекта Key.

В отличие от события onMouseDown, onKeyDown генерируется многократно, если клавиша удерживается. Период ето вызова приблизительно равен 50 мс. Наоборот: для одного нажатия клавиши событие onKeyUp возникает только один раз.

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

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

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

«Кнопочные» события
Замечательным нововведением Flash MX является то, что любой клип может рассматриваться как кнопка. Соответственно, клипам присуши все «кнопочные» события (всего их 7). Так как в следующей главе данные события будут описаны весьма обстоятельно, сейчас дадим им лишь краткую характеристику;

• onPress. Происходит при нажатии левой клавиши мыши при условии, что ее указатель располагался над клипом. Пожалуй, самое важное из «кнопочных» событий.

• onRelease. Данное событие возникает, если левая клавиша мыши была нажата и отпущена над клипом.

• onReleaseOutside. Событию соответствует ситуация, когда левая клавиша мыши была нажата над клипом, а отпущена вне его.

• onRollOver. Событие происходит при появлении указателя мыши над клипом.

• onRolIOut. Событие, обратное предыдущему. Возникает при выходе указателя за пределы клипа.

• onDragOver. Событие возникает, если указатель при нажатой левой клавише мыши выходит за пределы области клипа, а потом возвращается в нее.

• onDragOut. Данное событие происходит, если пользователь, нажав левую клавишу мыши над клипом, уводит указатель за его пределы, не отпуская ее.

«Кнопочные» события можно использовать не только при создании обработчиков-методов. Соответствующие обработчики можно задать и в стиле Flash 5.

Правда, для обработчиков на базе onClipEvent события кнопок недоступны. Чтобы их «слушать», нужно использовать обработчики on(event):

on(press){ // При щелчке по клипу он будет удален
this.removeMovieClip();
}

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

mov.useHandCursor=false;

При необходимости можно заблокировать восприимчивость клипа к «кнопочным» событиям. Для этого нужно использовать свойство enabled:

mov.enabled=false;

В отличие от всех остальных описанных событий, «кнопочные» события неприменимы к основной временной диаграмме. И это не всегда удобно. Например, если необходимо регистрировать выход указателя мыши за пределы окна плейера, нельзя использовать событие onRollOut по отношению к _root. Чтобы решить эту задачу, придется создать прозрачный клип, располагающийся над всей областью фильма.

«Кнопочные» события полезны не только тогда, когда клип выступает в роли кнопки. Например, используя событие onPress, можно зарегистрировать щелчок пользователя по клипу более просто, чем обратившись к событию onMouseDown. Событие onRollOver помогает реагировать на наведение на клип указателя мыши техничнее, чем если бы использовался метод hitTest() в обработчике onMouseMove и т. д.

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

События фокуса (onSetFocus, onKillFocus)
Очень часто во Flash приходится создавать такие элементы интерфейса, как меню, списки, формы. Так как по своему назначению (и чисто визуально) они весьма схожи с аналогичными элементами Windows, возможностями они должны обладать теми же. Так, многие пользователи привыкли работать с меню или списками при помощи клавиш движения. Чтобы реализовать подобную возможность в случае Flash-компонента, нужно сделать его элементы помещаемыми в фокус.

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

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

• onSetFocus. Данное событие происходит, когда клип помещается в фокус.
• onKillFocus. Событие возникает при потере клипом фокуса.

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

Оцените статью: (0 голосов)
0 5 0

Статьи из раздела Action Script на эту тему:
Виртуальные слои клипов
Задание формулы цвета
Имена экземпляров клипов
Импорт внешних фильмов и изображений
Клипы как носители кода

Вернуться в раздел: Action Script / 10. Клипы