(Окончание, начало в МК № 45, 49, 5 (216, 220, 228))
Текстовые поля
Текстовые поля бывают трех типов: Static Text, Dynamic Text и Input Text. Самый простой первый тип, это обычная надпись. Ее свойства из ActionScript изменять нельзя. Переименуем слой Layer 1 сцены в lr_Controls, в него мы будем помещать наши элементы управления. Создаем в этом слое две надписи: fr. X и fr. Y. Напротив них две надписи (точнее, текстовых поля) типа Input Text с параметрами Variable fr_x и fr_y соответственно. Тип текстового поля и имя переменной (Variable), связанной с ним, задаются на закладке Text Options (Ctrl+T) панели Character (Рис. 1). В эти поля мы будем вводить горизонтальные и вертикальные частоты нашей фигуры Лиссажу.
Создадим новый символ Cmv_Cap и сделаем в нем надпись (Static Text) Number of points. Затем выделим нашу надпись и разобьем ее: Modify > Break Apart (Ctrl+B). Это делается для того, чтобы можно было управлять прозрачностью надписи (свойство _alpha). ActionScript позволяет изменять свойства только для символов. Свойства примитивов (фигур), нарисованных на сцене во время проектирования, с помощью ActionScript изменять нельзя.
Создадим еще один символ Cmv_EditNum и поместим в него текстовое поле типа Input Text, свойство Variable которого назовем num_pnt. Сюда мы будем вводить количество точек (шариков) для фигуры Лиссажу вида «кривая». Мы создали эту надпись в виде отдельного символа, чтобы была возможность спрятать ее (убрать за пределы рабочей области), когда фигура будет отображаться в виде «хвоста».
Помещаем объекты на сцену
Перетащим из библиотеки символы (кроме Cmv_TailBall и Cmv_CurveBall) на сцену, в слой lr_Controls, как показано на Рис. 2 (или как сочтете нужным :-)). Двум экземплярам кольца для радио-кнопок дадим имена mv_rTail и mv_rCurve. Экземпляр с надписью Number of Points получит имя mv_Cap, а экземпляр, содержащий текстовое поле с переменной val имя mv_EditNum. Экземпляры кнопок имен не имеют. Надписи не имеют собственных имен, но различаются именами связанных переменных (свойство Variable).
«Подгоните» все элементы по размеру и местоположению, а два экземпляра Cbt_Arrow переверните на 180 (уже знакомая нам закладка Transform панели Info), чтобы получилась кнопка «стрелка вниз».
Выровнять расположение объектов можно, отключив опцию View > Snap to Objects и вызвав панель выравнивая Align (Ctrl+K). Кнопка To Stage: на этой панели указывает, что выравнивать выбранные (черной стрелкой напоминаем на всякий случай :-)) объекты следует относительно центра рабочей области. Эта же кнопка позволяет точно отцентровать символы при их рисовании.
Создадим еще два слоя lr_TailBall и lr_CurveBall и поместим в них (за пределами видимой области) экземпляры символов mv_TailBall и mv_CurveBall соответственно.
Вообще говоря, старайтесь придерживаться такого правила: символы различной природы помещайте в разные слои. Этим вы избежите возможных «глюков». Да и с точки зрения программирования это целесообразно видна логика программы.
Скрипты
Наконец-то мы добрались до скриптов.
Создаем новый слой lr_Actions и вставляем в первых трех кадрах ключевые кадры. Как и в предыдущем примере (см. МК №45, 49 (216, 220)), будем использовать классический трехкадровый цикл. В первом кадре инициализация переменных, во втором собственно динамика, в третьем осуществляется переход на второй с помощью вызова функции gotoAndPlay(2).
Все скрипты мы будем писать самостоятельно, так что давайте сделаем Expert Mode режимом по умолчанию: Edit > Preferences…, поле Mode панели Actions Panel. В редакторе ActionScript переключение между обычным и «экспертным» режимом осуществляется нажатием Ctrl+N/Ctrl+E. Удобное свойство: написав скрипт в режиме эксперта, переключитесь на обычный, а затем опять на экспертный. Ваш текст станет отформатированным, если нет синтаксических ошибок. Кстати, правильность синтаксиса можно проверить, нажав кнопку в правом верхнем углу и выбрав Check Syntax (Ctrl+T) в выпавшем меню.
Нумерация строк и комментарии на русском в ActionScript не предусмотрены (отсутствие русификации один из немногих недостатков Flash ). Тем не менее, некоторые листинги мы приводим с нумерацией и с русскими комментариями для удобства.
В первом кадре слоя lr_Actions пишем:
В третьем кадре пишем :
То есть осуществляется переход на второй (пока еще пустой) кадр.
Давайте напишем скрипты для кнопок. Выделяя кнопки и вообще любые объекты на сцене, вы заставляете Action Panel отображать Object Actions, а при выделении кадра в слое Frame Actions.
Кнопка «Play»:
Кнопка «Pause»:
Кнопка «Restart»:
Давайте разберемся. Скрипт кнопки должен содержать реакцию на события. Обработчик события имеет вид
Так, для кнопки Play скрипт, заключенный в {}, выполнится при нажатии; для Pause при нажатии или отпускании, а для Restart только при отпускании.
Далее, для наших кнопок-«стрелок», стоящих справа от полей ввода частот, пишем следующие четыре обработчика (какой фрагмент для какой кнопки вы, безусловно, разберетесь :-)):
Для радио-кнопок Cbt_Curve и Cbt_Tail пишем вот что:
Кнопка Cbt_Curve:
Кнопка Cbt_Tail:
Теперь можно опубликовать наш ролик, поиграться с кнопками (все работают!), закрыть Projector и вернуться к нашему барашку второму кадру слоя lr_Actions, в котором, собственно, и происходит анимация. Давайте напишем скрипт, а затем его обстоятельно прокомментируем.
В строке 1 проверяется, включен ли флаг Play_On; если нет, то происходит переход на 3-й кадр lr_Action, который, в свою очередь, переводит поток выполнения на 2-й. Так будет продолжаться до тех пор, пока не будет нажата кнопка Play.
В строке 2 с помощью функции parseFloat() выделяется число из переменной phase, связанной с текстовым полем. В строке 3 увеличивается значения таймера на rate условных единиц (не долларов :-)). Затем (строки 45) вычисляются координаты x1, y1 очередной точки (шарика), в соответствии с гармоническим (синусоидальным) законом.
Строки 721 выполняются, если вид отображения фигуры «хвост»; строки 2237, если «кривая». Вид отображения задается переменной PlayMode, которая изменяется при переключении радио-кнопок Cbt_Tail и Cbt_Curve (см. скрипты для них).
В строках 710 определяется номер очередного шарика для «хвоста». При этом в строке 8 используется свойство _totalframes, равное количеству кадров (в нашем случае 15) для данного мувика (см. далее о различии анимации ролика и мувика).
Строки 1116 выполняются, если необходимо стереть «кривую» (NeedKill == true).
Функция
уничтожает экземпляр мувика с именем <Имя_экземпляра> и действует только на экземпляры, созданные динамически с помощью ActionScript. <Имя_экземпляра> это строка. Копии экземпляров мувиков создаются функцией
Здесь <Имя_1> идентификатор уже существующего экземпляра мувика, <Имя_2> желаемое имя нового экземпляра (по аналогии с unloadMovie(), это строка), n номер уровня (не путайте со слоями), в который требуется поместить новый экземпляр.
На сцене находится множество уровней (теоретически их число не ограничено), в каждый из которых можно помещать объекты. При этом объекты, помещенные в «старший» уровень (с большим номером), перекрывают объекты в «младшем» уровне.
В одном уровне может находиться только один объект с данным именем.
Обратите внимание на строку 17. Flash ActionScript позволяет складывать строки с числами; так, "Tail_" + 12 == "Tail_12".
В строке 18 будут создаваться копии мувика mv_TailBall. У них будут имена Tail_1, Tail_2,..., и помещаться они будут в уровни 1, 2,…, в зависимости от значения переменной n_tail.
В строках 19, 20 устанавливаются значения свойств _x, _y для только что созданной копии мувика.
Функция
устанавливает <Свойство> экземпляра с именем <Имя> в <Значение>.
Несколько слов об анимации ролика и анимации объектов (мувиков) этого ролика. Как говорят в Одессе, это две большие разницы. Если вы в 3-м кадре слоя lr_Actions напишете stop() вместо gotoAndPlay(2), вы тем самым остановите выполнение программы. Но анимированные объекты-мувики (их в нашем проекте аж один :-) mv_TailBall) будут «жить» (трансформироваться согласно заложенной нами анимации, т.е. сжиматься) дальше! Проверьте это поместите mv_Tail в пределах видимой области и напишите stop(); в 3-м кадре слоя lr_Actions ролик остановится, а шарик mv_TailBall будет периодически появляться и сжиматься.
Это происходит потому, что анимация мувика mv_TailBall была создана во время проектирования, а скрипты работают во время выполнения проекта. Общее для анимации ролика и анимации его объектов одно количество кадров в секунду (frames per second, fps). Его мы установили равным 60 в самом начале работы.
Поэтому когда фигура имеет вид «хвост», шарики (mv_TailBall) уменьшаются в размере без нашего участия, а на 15-м кадре «самоликвидируются» вызовом removeMovieClip(this);, что было заложено, так сказать, генетически :-).
Вернемся к нашему листингу. Строки 2337 выполняются, когда PlayMode == pm_Curve (фигура имеет вид «кривая»). В целом, операции аналогичны уже описанным: создается копия mv_CurveBall с именем Curve_xx (xx == n_curve) и устанавливаются координаты этой копии.
В строке 23 проверяется, является ли значение mv_EditNum.val числом, и если нет, оно устанавливается в 0. Функция
(is not a number) возвращает false, если строка <value> содержит число, и true в противном случае.
В строках 2428 удаляются все экземпляры-копии mv_CurveBall, если изменилось значение mv_EditNum.val. «Кривая» перерисовывается заново. В 29-й флаг NeedKill устанавливается в true, чтобы в строках 1116 «кривая» была стерта при переключении на «хвост».
Пытливый читатель, взглянув на строки 710 и 1718 (или 3034), вероятно, воскликнет: а как же это мы создаем экземпляр-копию mv_TailBall (или mv_CurveBall) с уже существующим именем?! При достижении переменной n_curve значения max_curve ей присваивается значение 1, а экземпляр с именем Curve_1 у нас уже имеется! Как их потом различать? Сначала надо прибить «тезку»! Delphi, например, на такой кунштюк реагирует незамедлительно и очень грубо Exception, и вся Москва :-)!
Все правильно. В объектно-ориентированном подходе существование двух экземпляров с одинаковыми именами, как правило, недопустимо. Но Flash, равно как и web-браузеры, старается по возможности игнорировать ошибки, а не сообщать о них, прерывая выполнение (кстати, это существенно затрудняет их поиск). В данном случае при создании экземпляра с уже существующим именем старый будет уничтожен автоматически.
Ну вот, наш проект создан, прокомментирован, осталось нажать F12, подобрать фазу, частоты и количество шариков (штук эдак 200) и убедиться воочию, что бесконечно можно наблюдать не только за огнем, прибоем и работающей женщиной :-).
Теперь опубликуем наш проект в виде HTML, и вот страничка со встроенным осциллографом готова.
Можно добавить элементы управления, задающие скорость «развертки» (переменная rate), изменяющие прозрачность шариков (свойство _alpha), их размер (_width, _heigth) и так далее. Попробуйте сделать это самостоятельно.
На очереди drag’n’drop, звук, собственные функции, Smart Clips, обработка «мыши» и еще много чего.
Ваяйте! Слава Уанету!
P.S. Тем, кто был терпелив и последователен, дочитав до этого места, мы приготовили сюрприз: по адресу http://uant.narod.ru/misc/simgirl.swfможно скачать симпатичную флэш-игру (1.4 Mб) от компании EcoPhobia, содержащую все элементы, описанные в статье. Играя, не забывайте об авторских правах :-).