Professional Documents
Culture Documents
O'REILLY
С&ППТЕР Шам Бхангал
F L A S H
H A C K S
Sham Bhangal
O ' R E I L L T
Beijing • Cambridge • Farnham • Kbln • Paris • Sebastopol > Taipei • Tokyo
F L A S H .
ТРЮКИ
Шам Бхангал
Бхангал Ш.
Б94 Flash. Трюки. 100 советов и рекомендаций профессионала — СПб.:
Питер, 2005. — 460 с : ил.
ISBN 5-469-00763-4
Сборник предложенных экспертами советов и трюков, предназначенных для оптимизации
ваших Flash-приложений, создания интересных эффектов, программ на ActionScript, звуковых
и видеоэффектов, и т. п. Трюки ранжированы по степени сложности.
В книге описаны технологии Flash MX, Flash MX 2004 и Flash MX Professional 2004. Для
широкого круга программистов: от любителей до профессионалов.
ББК 2.973-044
УДК 04.92
Предисловие 13
Благодарности 16
Введение 19
От издательства 26
интерфейса 289
Предисловие 13
Благодарности 16
Участники проекта 16
Прочее 17
Введение 19
О чем эта книга? 19
Для кого написана книга 20
Как пользоваться книгой 21
Структура книги 22
Примеры кода 23
ActionScript 1.0 и ActionScript 2.0 24
От издательства 26
1
Весьма интеллектуальное развлечение — игрок лупит молотком кротов, неожиданно выскакивающих
из пор. — Примеч. перев.
Предисловие 15
Шам Бхангал сделал первые шаги к веб-дизайну в 1991 году, когда занялся про-
ектированием экранов для выдачи информации в компьютерных системах с осо-
быми требованиями к обеспечению безопасности (вроде тех, что используются
на диспетчерских пультах атомных электростанций). Вскоре он открыл для себя
более традиционные средства разработки интерфейсов, анимации и мультиме-
диа, такие как 3D Studio Max, Photoshop и Flash. Он пишет книги о них с начала
нового столетия.
Участники проекта
Ниже перечислены люди, которые делились идеями, участвовали в написании
книги или вдохновляли ее автора.
• Энтони «Ant» Идеи (a.k.a. arseiam) (Anthony Eden) работал на многих се-
рьезных заказчиков, в том числе Microsoft, Disney и Adobe. В свободное
время увлекается созданием причудливых и странных эффектов на Action-
Script. С примерами его работ можно ознакомиться на сайте http://
www.arseiam.com.
• Зе Фернандо (Zeh Fernando) работал с Macromedia Flash, начиная с версии
2. В настоящее время он трудится в бразильской дизайн-студии Grafikonstruct
(http://www.grafikonstruct.com.br), занимается созданием веб-сайтов на базе
Flash и придумывает новые способы заниматься тем же самым в свободное
время.
• Эдвин «XemonerdX» Хейджмен (Edwin Heijmen) - профессиональный Flash-раз-
работчик из Нидерландов; также является модератором на нескольких фору-
мах, посвященных ActionScript. Увлекается объединением математики с программи-
рованием, с результатами можно ознакомиться на сайте http://www.poeticterror.com.
Кроме ActionScript, также программирует на PHP, ColdFusion, Python и всех ма-
лопонятных языках, которые попадаются под руку. Другие увлечения - его заме-
чательная подруга, андеграундный металкор, программы с открытым кодом,
русская литература и друзья.
• Адам Филипс (Adam Phillips), обладатель призов за анимацию в сериях Flash-
роликов biteycastle.com, hitchHiker и Brackenwood. Победитель в номинации
Flash Forward Cartoon на NYC 2003, финалист SF 2004. После более 10 лет
работы в области традиционной 2О-анимации для Walt Disney Company Адам
продолжает создавать свои собственные короткие фильмы. Тринадцать из них
можно найти на сайте http://www.biteycastle.com.
Прочее 17
Прочее
Работ над книгой продолжалась довольно долго. Благодарю всех, кто был рядом
со мной все это время.
Разумеется, прежде всего я благодарю фирму Macromedia за создание Flash и уча-
стников проекта, поделившихся своими идеями.
Спасибо Колину Муку (Colin Moock) (http://www.moock.org) за его великолеп-
ные книги, техническую помощь и за введение к книге.
Спасибо группе рецензентов за замечания и исправления. В их числе: Марк Гар-
ретт (Mark Garrett), Дэвид Хамфрис (David Humphreys), Шафик Казун (Chafic
Kazoun), Марк Майхер (Mark Majcher), Сэм Нефф (Sam Neff), Дэррон Шалл
(Darron Schall), Джесси Уорден (Jesse Warden) и Эдуардо Зублер (Edoardo Zubler).
Спасибо всем сотрудникам O'Reilly, в том числе Тиму О'Рейли (Tim O'Reilly) за
первоначальные комментарии и Раэлу Дорнфесту (Rael Dornfest) за идею разде-
ления материала на «трюки». Я благодарен Брайану Сойеру (Brian Sawyer) и Клэр
Клутье (Claire Cloutier) за помощь в работе, Робу Романо (Rob Romano) за обра-
ботку многочисленных иллюстраций и Норме Эмори (Norma Emory) за подроб-
ную корректуру. Отдельное спасибо Брюсу Эпстейну (Bruce Epstein) за желез-
ную выдержку, за сверхъестественное искусство редактуры и за то, что у него
находилось время для дружеской беседы. Я также благодарен своему агенту Кэ-
рол Макклендон (Carole McClendon) из Waterside Production.
Спасибо всем разработчикам сообщества Flash, которые помогли мне советом по
работе со сторонним инструментарием: Игорю Когану (Igor Kogan), Дэйву Хей-
дену (Dave Hayden), Дэмьену Мортену (Damian Morten) (Flasm) и Алексу Блуму
(Alex Blum) (Flash Plugin Switcher). Благодарю Алессандро Капоццо (Alessandro
Capozzo) за разрешение воспроизвести некоторые изображения, созданные в Proces-
sing. Я также благодарен многочисленным разработчикам, проектировщикам и меч-
тателям, чья работа прямо или косвенно вдохновляла меня при работе над раз-
ными частями книги. Среди них стоит упомянуть Джоша Дэвиса (Josh Davis)
18 Благодарности
Структура книги
Flash - универсальный инструмент творческой разработки, состоящий из целого
ряда аспектов, которые обычно приходится комбинировать для получения жела-
емого эффекта или результата, поэтому названия глав и краткие обзоры стоит
воспринимать в широком смысле. Например, анимация в той или иной степени виде
присутствует во многих главах, а большинство трюков содержит код ActionScript,
позволяющий сделать много интересного. Тем не менее, 100 трюков пришлось
организовать в более или менее разумную структуру. Так в книге появились гла-
вы, посвященные графике, звуку, оптимизации и другим темам.
• Глава 1. Визуальные эффекты. В этой главе показано, как сделать графичес-
кое оформление сайта более интересным за счет добавления впечатляющих
эффектов и переходов.
• Глава 2. Цветовые эффекты. Грамотный дизайнер использует не только ани-
мацию, но и цвет. Его часто недооценивают, но, как будет видно из этой главы,
при помощи цвета можно изменить общий настрой или реализовать такие
эффекты, как растворение и вытеснение.
• Глава 3. Рисование и маски. Объединение средств графической анимации
Flash с ActionScript существенно расширяет творческие горизонты. В этой
главе представлены графические эффекты, создаваемые как на стадии постро-
ения, так и на стадии использования сайта. Также объясняется принцип рабо-
ты масок, часто используемых во многих операциях с графикой.
• Глава 4. Анимация. Трюки этой главы демонстрируют пути ускоренного созда-
ния анимационных последовательностей, а также способы оптимизации ани-
мации, созданной под контролем ActionScript.
• Глава 5. Трехмерная графика и физика. В этой главе представлен ряд трю-
ков, позволяющих обойти ограничения Flash по быстродействию и включить
в ваш репертуар имитацию физических процессов и трехмерных эффектов.
• Глава 6. Текст. Глава посвящена способам хранения, отображения и обработ-
ки текста, а также применения к нему анимационных эффектов.
• Глава 7. Работа со звуком. Без звукового сопровождения даже тщательно
проработанный контент выглядит уныло и обыденно. В этой главе показано,
как создать и изменить звуковые эффекты и музыку.
Примеры кода 23
Примеры кода
Примеры текстов программ вы сможете найти на сайте O'Reilly (http://
www.oreilly.com). Для этого найдите ссылку на книгу (например, по названию
Flash Hacks или по оригинальному ISBN 0-596-00645-4) и следуйте гипер-
ссылкам на соответствующей книге веб-странице сервера.
function myFunction(x:Number):Number {
var у:Number = 2 * x:
return y;
}
var myString:String = "hello";
var myClip:MovieClip = this.createEmptyMoveClipC'myClip".0);
var double:Number = myFunction(2);
trace(double);
А вот как выглядит эквивалентная версия ActionScript 1.0 без типов данных:
// ActionScript 1.0 (без типов)
// Пример работает в среде Flash MX (и выше)
function myFunction(x) {
var у = 2 * х;
return у;
}
var myString = "hello":
var myClip = this.createEmptyMoveClipC'nyClip".0):
var double = myFunction(2):
trace(double);
В книге часто используется код временной диаграммы, поддерживаемый как
в ActionScript 1.0, так и в ActionScript 2.0 (хотя его применение не всегда явля-
ется оптимальным). Такое решение объясняется тем, что многие примеры плохо
преобразуются к схеме с пользовательскими классами ActionScript 2.0. Кроме
того, это упрощает анализ и реализацию примеров как в Flash MX, так и в Flash
MX 2004.
Некоторые объектно-ориентированные примеры на базе классов, написанные
на ActionScript 2.0, не компилируются в ActionScript 1.0 и требуют Flash MX
2004 (в стандартном или профессиональном издании). Если вы продолжаете
использовать ActionScript 1.0 в Flash MX 2004, подумайте, не пора ли расширить
свой кругозор. Дополнительная информация и перечень ресурсов, посвящен-
ных различиям между Flash Player 6 и Flash Player 7, приводится в главах
10 и 12.
Регистр символов
Многие разработчики до сих пор путаются в правилах регистра символов в Flash
MX 2004. Прежде всего следует понять, что речь идет о двух разных вещах: ре-
гистре символов на стадии компиляции и регистре символов на стадии выпол-
нения. Компилятор ActionScript 1.0 игнорирует регистр символов, тогда как
компилятор ActionScript 2.0 его учитывает. Тем не менее, учет регистра символов
на стадии выполнения определяется версией формата SWF, в который экспор-
тируются данные, и не зависит ни от версии ActionScript, использованной на ста-
дии компиляции, ни от версии модуля Flash Player, в которой файл воспроиз-
водится.
Сводка правил учета регистра приведена в табл. В.1, позаимствованной из отлич-
ной книги Колина Мука «Essential ActionScript 2.0» (с разрешения автора).
26 Введение
1
В идентификаторах (то есть именах переменных и свойств), именах функций, метках кадров и эк-
спортных идентификаторах символических имен в файлах .swf формата Flash Player 7 регистр сим-
волов не учитывается. С другой стороны, в зарезервированных словах вроде if регистр символов учи-
2
тывается даже в Flash Player 6.
Flash Player 6 не может воспроизводить файлы .swf формата Flash Player 7.
От издательства
Ваши замечания, предложения, вопросы отправляйте по адресу электронной почты
comp@piter.com (издательство «Питер», компьютерная редакция).
Мы будем рады узнать ваше мнение!
На веб-сайте издательства http://www.piter.com вы найдете подробную информа-
цию о наших книгах.
Г Л Д В Д 1
Визуальные эффекты
Трюки № 1-7
Предполагается, что читатель уже знаком с основными концепциями примене-
ния Flash для создания визуальных эффектов и анимации на временной диа-
грамме. Но даже если ваш опыт работы с Flash еще недостаточен, описанные
в настоящей главе приемы все равно покажутся вам интересными. После того
как вы освоите азы Flash (по учебнику или по электронной документации), по-
пробуйте вернуться к тем трюкам, которые вас особенно заинтересовали. Снача-
ла я хотел открыть книгу советами по оптимизации, безопасности и другим те-
мам того же плана. Но затем я решил отложить эти темы до более позднего
времени в надежде, что трюки этой главы заинтересуют читателя и расширят
его кругозор, не нарушая принципов хакерской этики: «Сначала показывать са-
мое интересное».
Итак, в настоящей главе собраны трюки, показывающие, как реализовать эф-
фекты, которых вы либо вообще не видели, либо видели, но не знали, как их
воспроизвести. Они, как и весь остальной материал книги, научат вас чему-то
новому, а в конечном счете и вдохновят - причем не так, как нас вдохновляют
бессмертные произведения искусства, а, скорее, стимулируют к дальнейшей ра-
боте. Надеюсь, что вам захочется опробовать их в деле и создать что-нибудь
похожее самостоятельно.
Трюки этой главы были объединены из-за того, что все они имеют отношение
к визуальным эффектам. В дальнейших главах будут описаны визуальные эф-
фекты, основанные на переходах и колоризации, трехмерности, применении ма-
сок и использовании API графического вывода. В данной главе рассматривают-
ся пиксельные эффекты, преобразования анимированных изображений GIF
и файлов Photoshop в файлы Flash .fla и .swf (исходные форматы документиро-
вания и распространения, используемые Flash). Глава завершается двумя трю-
ками, в которых мы сгенерируем дерево и заставим его качаться на ветру.
Хотя маски интенсивнее всего используются в главе 3, из-за своей исключитель-
но важной роли в Flash (см. трюк 1) они также неоднократно встречаются в дру-
гих главах. По этой причине я привожу краткое введение для читателей, не зна-
комых с масками.
Анимации Flash создаются посредством наложения одного или нескольких сло-
ев (аналогичных слоям Photoshop и других графических программ). На панели
28 Глава 1. Визуальные эффекты
Рис. 1.2. Маски для имитации перехода на уровне пикселов (шаги 1-4)
Создание пикселов
Создать маску из пикселов ненамного сложнее, чем обычный прямоугольник.
1. Создайте новый документ Flash (File • New • Flash Document).
2. Выполните команду Modify • Document, задайте размеры сцены более чем
200 х 200 пикселов, выберите белый цвет фона (подойдет любой светлый отте-
нок, на котором будет хорошо виден черный прямоугольник из шага 3).
3. Нарисуйте черный прямоугольник без контура (контур все равно останется
незаметным, но замедлит обработку эффекта).
4. На панели свойств (Window • Properties) задайте высоту и ширину прямоу-
гольника равными 4. Задайте координаты X и Y равными 0. Итоговый вид
панели показан на рис. 1.3 рядом с точкой регистрации.
5. Преобразуйте прямоугольник в символ анимационного клипа. Для этого выде-
лите его (при помощи инструмента Selection) и нажмите клавишу F8 (Modi-
Имитация переходов на уровне пикселов 31
Shape
+ II
0.0
ПРИМЕЧАНИЕ
Эксперт ActionScript может предложить построение маски средствами Drawing
API, но у Flash уйдет слишком много времени на динамическую прорисовку всех
прямоугольников, необходимых для этого эффекта.
drawGrid(200. 200):
Приведенный фрагмент создает квадрат 200 х 200 пикселов, состоящий из «то-
чек» - анимационных клипов 4 x 4 (изменяя параметры drawGridQ, можно соз-
дать квадрат других размеров). Каждый экземпляр размещается в позиции (i, j)
на глубине k с именем dotz_j. Первому экземпляру (находящемся в левом верх-
нем углу квадрата) соответствует имя dotO_0, а последнему (в правом нижнем
углу) - имя dot199_199. Чтобы просмотреть созданные анимационные клипы,
выполните код в отладочном режиме (Control • Debug Movie), но учтите: для ото-
бражения всех клипов отладчику может потребоватьея некоторое время. Даже
если вам покажется, что Flash «висит», подождите несколько секунд.
ПРИМЕЧАНИЕ
Эффект создает большое количество анимационных клипов: (200/4) 2 = 2500.
Если на экране одновременно находится от 3000 до 4000 клипов (даже не пере-
мещаемых), работа Flash заметно тормозится, поэтому превышать порог в
2500 пикселов не рекомендуется. Если маскируемая область больше той, кото-
рая используется в нашем примере (квадрат со стороной 200 пикселов), то
вместо добавления новых прямоугольников лучше увеличить их размеры.
Управление пикселами
Возникает следующий вопрос: как заставить точки исчезать по нашему жела-
нию? Для этого лучше всего воспользоваться вызовом setlnterval {объект, «ме-
Имитация переходов на уровне пикселов 33
}
drawGrid(200. 200, imagel_mc);
Итак, все «точечные» клипы находятся внутри другого анимационного клипа
с именем mask. Последний назначается маской для клипа, имя которого переда-
ется в параметре функции drawGrid(). В данном примере используется клип с име-
нем image1_mc; мы создадим его позднее, в разделе «Использование эффекта».
Но сначала нужно позаботиться об уничтожении клипов-«точек».
Создание таймеров
Для каждого «точечного» клипа уже установлено свойство timer. Теперь давайте
напишем код, обеспечивающий исчезновение «точек».
Отредактируйте символ клипа dot и добавьте новый слой с именем actions (тра-
диционно первый слой временной диаграммы называется scripts или actions и ис-
пользуется исключительно для хранения сценариев).
34 Глава 1. Визуальные эффекты
п
функция отменяет интервал отсчета и удаляет текущий клип. Тем самым созда-
ется эффект перехода «исчезающих пикселов».
ПРИМЕЧАНИЕ
Если при вызове setlnterval() в первом параметре передается ссылка на функ-
цию (как при вызове setlnterval(removeMe,timer)), значение ключевого слова this
в функции removeMe() не определено. По этой причине мы используем альтер-
нативную форму setlnterval(this,"removeMe",timer), у которой в первых двух па-
раметрах передаются объект и имя метода (в этом случае ключевое слово this
представляет объект, переданный в первом аргументе). При вызове removeMe()
ключевое слово this находится в области видимости, поэтому мы можем ис-
пользовать вызов this.removeMovieClip() для уничтожения клипа.
Использование эффекта
Разместите два изображения/видеоклипа, связываемых переходом, на двух раз-
ных слоях; первое изображение (или видеоклип) должно находиться на верхнем
слое, как показано на рис. 1.5. На панели свойств присвойте ему имя экземпляра
image 1_mc. Второе изображение может называться как угодно, поскольку оно
нигде не упоминается в программном коде.
:
5 • 10 15 3 . 2s 33 ;S .
Усовершенствования
Изменяя интервалы между исчезновением «точек», можно имитировать разные
эффекты переходов. Например, изменяя интервал на основании позиции точки,
вы сможете реализовать многие стандартные переходы:
// Вытеснение слева направо
initDot.timer = 1000 + (Math.random()*(initDot._x)*10);
// Вытеснение по диагонали
initDot.timer = 1000 + (Math.random()*(initDot._x + initDot._y)*5);
Итоги
Многие Flash-разработчики недооценивают возможности масок. На первый
взгляд, маскам трудно найти реальное применение, но если вникнуть поглубже,
вы измените свое мнение. Вполне естественно, что маски широко применяются
в самых замечательных эффектах, описанных в книге (см. трюк 21)!
№2 пикселов
Создание текстовых эффектов и переходов на уровне пикселов.
Основной недостаток имитации пиксельных эффектов в Flash состоит в том, что
потенциальное ухудшение быстродействия ограничивает количество используе-
мых фиктивных пикселов. Существует два способа сохранить их количество на
достаточно низком уровне: ограничиваться небольшими изображениями (как
при имитации переходов на уровне пикселов - см. трюк 1) или же применять
эффекты к изображениям с многочисленными фоновыми пикселами, которые
могут игнорироваться при обработке эффекта.
Теперь это кажется очевидным, но когда-то мне понадобилась целая вечность,
чтобы понять, что текст подходит под описание «изображения с многочислен-
ными фоновыми пикселами». После непродолжительных поисков в Веб напра-
шивается предположение, что этот факт действительно неочевиден - похоже,
больше никто не использует этот трюк.
В настоящем разделе мы сделаем так, чтобы текст формировался из пикселов,
разбросанных по экрану. Конечно, применение других вычислений с учетом по-
зиций пикселов маски позволяет реализовать и другие эффекты.
Трюк делится на две части:
• преобразование текстового блока в квадраты 1 x 1 («фиктивные пикселы» из
предыдущего примера);
• анимация фиктивных пикселов.
36 Глава 1. Визуальные эффекты
Й • - — • • •
Н:: IS. 6
Трюк работает лишь в том случае, если текст был преобразован в примитивную
фигуру командой Modify • Break Apart (вскоре вы поймете, почему это необходи-
мо). Вообще говоря, эта операция нежелательна, поскольку она увеличивает раз-
мер файла. При большом объеме текста прирост получается довольно значи-
тельным. Одно из возможных решений проблемы - включение каждой буквы
шрифта в виде отдельного клипа, содержащего примитивную фигуру, и форми-
рование предложений на стадии выполнения. На первый взгляд кажется, что
файл SWF перегружается множеством лишних байтов, но стоит вспомнить, что
практически то же самое происходит при сохранении в SWF контуров шрифтов,
а эта операция должна выполняться всегда, когда буквы шрифта должны ис-
пользоваться в качестве графических элементов.
Нам также понадобится второй анимационный клип с идентификатором компо-
новки dot. Клип dot представляет собой прямоугольник 1 х 1, у которого обе
координаты, X и Y, равны 0, как показано на рис. 1.7 (для задания свойств следует
использовать панель Properties, так как точка получается слишком маленькой).
Программный код дублирует эффект «проявления с размывкой», но на этот раз
текст действительно размыт (обычно размывка имитируется при помощи аль-
фа-канала), как показано на рис. 1.8, поскольку разбиение текста на пикселы
является одной из составляющих эффекта.
Текстовые эффекты на уровне пикселов 37
function moverО {
this._x -= (this._x - t h i s . x ) / 4;
this._y -= (this._y - t h i s . y ) / 4:
function lastMoverO {
this._x -= (this._x - t h i s . x ) / 4;
this._y -= (this._y - t h i s . y ) / 4;
i f ( ( t h i s . _ x - t h i s . x ) < 0.1) {
dotHolder.removeMovi eCli p();
t e x t C l i p . _ v i s i b l e = true;
ПРИМЕЧАНИЕ
Проверка выглядит несколько неестественно, но она требует гораздо меньших
ресурсов, чем «правильное» выполнение аналогичной проверки для каждого
пиксела.
Имитация зернистости старой пленки 39
Итоги
Текстовые эффекты на базе Flash часто встречаются во Всемирной паутине, но
я не знаю ни одного сайта, на котором бы применялись текстовые эффекты уровня
пикселов. Самая замечательная особенность трюка с фиктивными пикселами
состоит в том, что функция перемещения пикселов позволяет реализовать мно-
жество других эффектов: снег, водопад, летящие звезды (см. трюк 33) и т. д.
1 :.,.,'•,...У&:.;,;.: ,JJ:'
I pixels
I pixels
1 pixels/inch
| ;© Background Co lor; •; ; : : . : ; :
... ;
•:j О Transparent :- : . \ •'
6. Добавьте новый слой при помощи кнопки Create a New Layer в нижней части
вкладки Layers. Вывод будет осуществляться только на новом слое, поэтому
следите за тем, чтобы на вкладке Layers всегда оставался выделенным только
слой Layer 1 (рис. 1.10).
• точки и пятна, возникающие из-за попадания частиц грязи или других ве-
ществ на пленку. Светлые пятна появляются из-за царапин или отпадения
частиц покрытия пленки;
• царапины, появляющиеся из-за физического повреждения пленки, стираю-
щего часть изображения.
Используя инструментарий Photoshop (вернее всего, инструменты Pencil и Brush),
добавьте три типа эффектов на слой Layer 1. На рис. 1.11 слева находятся ма-
ленькие точки, в середине - большие пятна, и справа - царапины. Сверху и снизу
расположены волосяные линии.
f
Рис. 1.13. Имитация выпадения фрагментов поверхности
• :'.••••"••
: g r a h
OK
Сфосип-ients and SettjngsAgham
Cancel
1S;39;2O Update
ПРИМЕЧАНИЕ
Обратите внимание: созданное нами изображение содержит как сжатие JPEG,
так и альфа-канал! Создать автономный файл в формате JPEG с ассоциирован-
ным альфа-каналом не удастся, но Flash не возражает против таких файлов.
Данная особенность чрезвычайно полезна для наложения векторов Flash на ра-
стровые изображения.
i
u
^• , « • •<•%!£:. Mliu ., .
1iiiii-i
.... т.
Итоги
Область применения представленной методики не ограничивается «созданием
атмосферы» в видеоклипах. Эффект «старой кинопленки» также позволяет
• маскировать недостатки видеоматериала (например, артефакты, обусловлен-
ные слишком высоким коэффициентом сжатия);
Создание SWF на базе анимированного формата GIF 45
O ' R E I L L Y
этого SWF маскируется (см. трюк 98) в кэше браузера, где пользователи обычно
ищут загруженные SWF.
Если открыть GIF-файл O'Reilly в графическом редакторе (например, Fireworks
или Photoshop/ImageReady), вы увидите, что анимация подмигивания воспро-
изводится каждые 12 секунд (первому кадру назначена 12-секундная задержка),
а ее общая продолжительность равна 12 секундам. Первое, на что следует об-
ратить внимание, - на то что абсолютное большинство пикселов изображения
не изменяются между кадрами; меняются только глаза. Следовательно, преобра-
зование ролика в Flash и анимация одних глаз позволит заметно сократить раз-
мер файла.
Также следует помнить, что анимация не интерактивна. В данном случае отсут-
ствие интерактивности вполне уместно (выходки зверька не должны отвлекать
читателя), но для интереса мы добавим интерактивность и убедимся в том, что
SWF все равно получается меньше исходного GIF-файла.
followMouse = function О {
this.startX = this._x;
this.startY = this._y;
this.onEnterFrame = animateEye;
animateEye = function () {
var distX = (_xmouse - t h i s . j O / 50;
var distY = (_ymouse - this._y) / 50;
i f (Math.abs(distX) < 5) {
this._x = this.startX+distX;
}
i f (Math.abs(distY) < 5) {
this._y = t h i s , startY+distY;
leftEyejnc.onEnterFrame = followMouse;
rightEyejnc.onEnterFrame = followMouse;
Функция followMouseO назначается обработчиком события onEnterFrame для обоих
зрачков. При вызове она просто сохраняет начальную позицию зрачка и назначает
обработчиком onEnterFrame функцию animateEyeO для последующих кадров.
Конечно, вы можете наделить свою зверушку гораздо большим спектром эмо-
ций, чем предусмотрено в анимированном GIF-файле (рис. 1.21), но это будет
уже не трюк, а проявление истинной сущности Flash.
Итоги
Хотя анимация получилась довольно стандартной, сама скорость ее создания на
базе существующего анимированного GIF-файла показывает, как легко созда-
Анимация PSD-файлов Photoshop в Flash 49
№5 в Flash
Импортирование PSD-файлов Photoshop в Flash для последующей ани-
мации.
В этом трюке будет показано, как воссоздать файл Photoshop на слоях Flash.
Процесс рассматривается во всех подробностях, потому что они весьма поучи-
тельны (и к тому же бесплатны!), хотя модуль Photoshop PSD2FLA (http://
www.medialab.com/psd2fla) от сторонней фирмы Media Lab существенно упроща-
ет этот процесс. Вероятно, читатели, работающие с Director, помнят Media Lab
как разработчика PhotoCaster, популярной и почитаемой надстройки для им-
портирования PSD-файлов в Director.
Если в системе установлен QuickTime версии 4.0 и выше, PSD-файл можно им-
портировать прямо в Flash. Скорее всего, Flash сообщит, что файл импортиро-
вать не удается, но предложит импортировать его через QuickTime. Щелкните
на кнопке Yes, и изображение будет успешно импортировано.
ПРИМЕЧАНИЕ
В процессе импортирования Flash описывает файлы .psd как «графику Photoshop
версий 2.5, 3», однако при импортировании через QuickTime Flash обрабатыва-
ет файлы гораздо более поздних версий Photoshop.
В своем примере я решил убрать весь текст, кроме названия (наверху слева).
Удаляемый текст заменяется более четким векторным текстом при последую-
щей обработке изображения в Flash. Название было сохранено в исходном виде,
поскольку к нему были применены эффекты Photoshop, которые трудно воспро-
извести средствами векторной графики.
На рис. 1.23 изображена упрощенная версия графики после удаления текста.
Рис. 1.23. Графика Photoshop после исключения слоев, которые могут быть
построены средствами Flash
• ' '•••- V •
.... <——
•:•
':.; :li
г- >!>•<• U4I
вит
Яе-ч
ДИИИИвЯииВВ
2. Выделите растр.
3. Нажмите клавишу F8 и создайте на базе растра символ анимационного кли-
па. Для предотвращения путаницы рекомендуется присвоить клипам те же
имена, что и у растров, но снабдить их суффиксом _тс.
Когда все будет готово, вы получите набор растров с прозрачными фонами и смо-
жете разместить их на сцене Flash по аналогии с тем, как они размещались в ори-
гинале PSD. На рис. 1.26 представлена библиотека Flash с набором импортиро-
ванных растров.
' btm
i aps Foider
И background Bitmap
Щ сопсербопТШе Bitmap
Щ Breenleaf Bitmap
Щ overAfcha Bitmap
1 1 spine Bitmap
'•• • > , :
*v is'-;••:':а .-ч
: »: \<ц , •• х
>
При выборе качества следует помнить, что растры образуют многослойную ком-
позицию, поэтому большая часть шума, обусловленного высоким коэффициен-
том сжатия, будет скрыта слоями и полупрозрачным наложением. Чтобы опре-
делить минимальный порог снижения качества, следует оценить общее восприятие
композиции. Возможно, для некоторых нижних слоев окажутся приемлемыми
коэффициенты сжатия 20% и менее.
ПРИМЕЧАНИЕ
Flash позволяет экспортировать растровое изображение с альфа-каналом од-
новременно с применением сжатия JPEG!
Итак, у нас имеется отправная точка для построения анимации. Теперь с каж-
дым элементом композиции можно выполнить следующие действия:
• анимацию с использованием кадрирования (задайте на панели свойств пара-
метру Tween значение Motion);
• присвоение имени экземпляра и динамическую анимацию средствами Action
Script.
Далее в композицию добавляются отсутствующий текст и векторные элементы,
удаленные из оригинала (или в Flash-версии создаются новые векторные элементы).
Как упоминалось ранее, анимация растровых изображений может привести к за-
метному торможению работы Flash. Впрочем, практический опыт показывает,
Генератор деревьев 55
Итоги
Если создаваемая анимация не дает особой нагрузки на процессор и не занимает
много места на экране, попробуйте использовать механизм преобразования
PSD-PNG-Flash, описанный в данном разделе (если исходные условия не вы-
полняются, вероятно, стоит подумать о переходе на Director). У описанного пути
также есть свои преимущества, если вы собираетесь имитировать сайт по визуа-
лизациям Photoshop или печатным материалам. В этом случае также стоит по-
думать об использовании Photo Webber (http://www.photowebber.com) от создате-
лей PSD2FLA.
Практический опыт применения данной методики также показывает, что размер
итогового файла SWF может быть на удивление небольшим по сравнению с раз-
мером исходного файла PSD. Обычно размер анимированной SWF-версии бо-
лее или менее соответствует размеру статического JPEG-файла с качеством от
среднего до высокого.
function growO {
// Вырастить ветвь...
this.lineStyle(trunkThickness, 0x0. 100);
this.moveTo(0, 0);
this ЛineTo(0. trunkLength);
// Если это не ствол, изменить угол и размер ветви
i f (this._name != "trunk") {
this._rotation = (Math.random()*angle) - angle/2;
this._xscale *='branchSize:
this._yscale *= branchSize;
}
. // Сгенерировать ростки...
var seed = Math.ceil(Math.random()*branch);
for (var i = 0; i < seed; i++) {
if (counterO < 3000) {
var segment = this.createEmptyMovieClip("segment" + i. i)
segment.onEnterFrame = grow;
segment.+y = trunkLength; }
}
delete (this.onEnterFrame);
// Параметры дерева
var angle = 100;
var branch = 5;
var trunkThickness = 8;
var trunkLength = -100;
var branchSize =0.7;
Базовая форма дерева определяется параметрами, значения которых задаются
в завершающих строках листинга:
• angle - максимальный угол ветви по отношению к родителю;
• branch - максимальное количество ростков (дочерних ветвей) для любой
ветви;
58 Глава 1. Визуальные эффекты
trunkThickness angle
Масштабирование
с коэффициентом branchSize
trunkLength
1 2 3
Рис. 1.29. Фазы построения ветви
Затем функция создает от 1 до branch новых «ростков». Весь фокус в том, что
ростки получают тот же обработчик onEnterFrame, что и текущий, а именно grow(),
поэтому в следующем кадре они отращивают собственные ростки и т. д. Здесь
используется фрагмент кода, который создает новый анимационный клип для
каждого ростка и назначает ему обработчик события onEnterFrame. Дерево могло
бы создавать новые ростки до бесконечности, но процесс необходимо как-то
ограничить, иначе Flash будет работать все медленнее и в итоге просто «завис-
нет». Чтобы предотвратить эту ситуацию, функция counterQ ограничивает об-
щее количество ветвей пороговым значением 3000:
var seed = Math.cei1(Math.randomC)*branch);
for (var i = 0; i < seed: i++) {
i f (counterO < 3000) {
var segment = this.createEmptyMovieClip("segment" + i . i ) ;
segment.onEnterFrame = grow:
segment.+y = trunkLength: }
}
В завершение grow() удаляет себя, поскольку она должна выполняться только
один раз для каждой ветви.
Имитация движения дерева 59
Итоги
Хотя в представленном решении задействована пара неочевидных моментов, под
«трюком» здесь следует понимать скорее общий подход. Копирование живой
природы или других объектов, оказавшихся под рукой, — испытанный путь по-
иска новых идей и решений для Flash-дизайна.
Flash является средой графического программирования; именно это обстоятель-
ство делает возможным такие эксперименты, как в нашем решении. Вы можете
написать программу и немедленно получить графическую обратную связь. Если
Имитация движения дерева 61
ив в ••
- : •
1
I
Цветовые эффекты
Трюки № 8-13
Как правило, Flash-дизайнеры при создании анимации уделяют основное вни-
мание движению и масштабированию, однако цвет также может быть объектом
анимации для создания различных эффектов и переходов.
Для дизайнера анимация цвета интересна прежде всего тем, что она позволяет
с минимальными усилиями (и практически без увеличения файла) изменить вне-
шний вид и атмосферу. Изменением цветовой схемы анимаций Flash реализует-
ся широкий спектр эффектов - например, смена дня и ночи. Приданием изобра-
жению сепийных оттенков создается эффект «ретро», а цветовая гамма «электрик»
может использоваться для имитации более современного стиля «техно».
Изменения цвета могут применяться ко всему, что инкапсулируется в анимацион-
ных клипах, включая растровые изображения, видеоклипы и векторную графику.
В сущности, все, что отображается на сцене Flash, может стать объектом цвето-
вой анимации, управляемой посредством кадрирования (то есть на временной
диаграмме во время разработки) или ActionScript (на стадии выполнения).
Это обстоятельство упрощает применение цветовых эффектов на стадии выпол-
нения и позволяет сделать контент более привлекательным при минимальном
увеличении объема передаваемых данных. Вы узнаете, как при помощи цвето-
вых эффектов сделать растровое изображение более оригинальным, привести
его к цветовой гамме сайта и даже реализовать некоторые возможности видео
для статических растровых изображений.
Также мы рассмотрим, как применение цветовых переходов к видео субъектив-
но удлиняет короткий повторяющийся клип и делает его более интересным.
Учитывая, что пересылка видеоданных обычно сильнее всего загружает каналы
связи, вы также можете оптимизировать процесс загрузки видео за счет добавле-
ния сложных переходов на стадии выполнения (вместо их применения в исход-
ном видеоматериале).
Файлы SWF принадлежат к числу немногочисленных графических веб-ресур-
сов, у которых цвет обходится «бесплатно» - прибавление множества цветов
к Flash-сайту не создает дополнительной нагрузки на канал связи. Впрочем, су-
ществует и оборотная сторона: при такой свободе выбора вам придется действо-
вать более внимательно. По этой причине мы рассмотрим несколько новых спо-
собов управления цветом и быстрого создания палитр.
Применение цветовых эффектов к видео 63
Наконец, любой обзор работы с цветом в Flash будет неполным без упоминания
ActionScript. Сценарии существенно расширяют возможности цветовой анима-
ции. Мы рассмотрим способы создания нестандартных цветовых эффектов на
объектно-ориентированном коде ActionScript 2.O.
№8 к видео
Имитация видеоперехода с использованием цветовых эффектов Flash.
В этом трюке класс Color используется для изменения видеоклипа и создания
уникального цветового перехода. Методика не является очевидной, а видеопере-
ходы обычно реализуются другими средствами, но суть трюков как раз и заклю-
чается в том, чтобы исследовать все неочевидное.
ПРИМЕЧАНИЕ
Чтобы уменьшить объем анимации, не утомляя зрителя, следует на программ-
ном уровне внести изменения, отсутствующие в исходном видеоматериале.
Кодирование цветов
Возможно, вам доводилось применять цветовые эффекты к видеоклипам при
помощи диалогового окна Advanced Effect (рис. 2.1). А если не доводилось, рас-
смотрим несложный пример цветовой анимации:
1. нарисуйте черный круг на сцене в первом кадре и преобразуйте его в символ
анимационного клипа (F8).
2. вставьте в кадре 10 ключевой кадр (выделите кадр 10 на главной временной
диаграмме и выполните команду Insert • Timeline • Keyframe).
3. щелкните на ключевом кадре 1 и примените к экземпляру анимацию движе-
ния (задайте на панели свойств параметру Tween значение Motion).
4. щелкните на ключевом кадре 10. Активизируйте инструмент Selection и щел-
кните на сцене, чтобы снять выделение с кадра. Наконец, щелкните на экзем-
пляре клипа на сцене, чтобы выделить его.
5. выберите в списке Color на панели свойств строку Advanced.
6. щелкните на кнопке Settings на панели свойств; на экране появляется диало-
говое окно Advanced Effect. Задайте параметру rb значение 200, как показано
на рис. 2.1. Закройте диалоговое окно кнопкой ОК.
Если медленно перемещать индикатор текущей позиции по первым 10 кадрам
временной диаграммы, вы увидите, как цвет клипа медленно переходит от чер-
ного к красному то есть, фактически, происходит цветовой переход (если при
кадрировании была допущена ошибка, клип останется черным до кадра 9, а за-
тем внезапно станет красным на кадре 10).
Все это, конечно, хорошо. Но как применить цветовой переход к видео на стадии
выполнения? Класс Color позволяет применять аналогичные преобразования к лю-
бым анимационным клипам, в том числе и к содержащим видеоклипы. Метод
Color.setTransform() получает один аргумент - объект преобразования со свой-
ствами га, да, ba, aa, rb, gb, bb и ab.
Объект преобразования (transObject) представляет собой экземпляр класса Object
со свойствами, используемыми для выполнения цветовых преобразований. Во-
семь свойств объекта просто соответствуют значениям восьми полей диалогово-
го окна Advanced Effect на рис. 2.1. Чтобы понять смысл свойств, поэксперимен-
тируйте с изменением параметров в окне Advanced Effects.
Применение цветовых эффектов к видео 65
Цветовые видеопереходы
В следующем трюке реализуется один характерный тип преобразований - мгно-
венные эффекты (например, когда нормальный цветной клип резко превращает-
ся в фотографический негатив, остается им в течение нескольких кадров, а затем
возвращается к исходному состоянию). Эффект выглядит весьма впечатляюще,
особенно если синхронизировать его со звуком (см. трюк 59). Методика может
быть расширена для создания другой категории эффектов: наплывов и других
постепенных преобразований (см. трюк 9).
Начнем с мгновенных эффектов. На рис. 2.2 показано исходное изображение,
а на рис. 2.3 и 2.4 - два возможных эффекта.
№9 и белом фоне
Создание видеопереходов растворения на черном и белом фоне.
Переходы могут применяться как к статическим изображениям, так и к видео-
клипам. Например, для достижения мгновенного эффекта к видеоклипу можно
применить цветовое преобразование (см. трюк 8). Настоящий раздел посвящен
эффектам, протяженным во времени, - мы рассмотрим их на примере последо-
вательного применения цветовых преобразований для реализации растворения.
Протяженные эффекты
Для реализации протяженных переходов нам понадобится структура данных,
позволяющая вносить поэтапные изменения в параметры цветового преобразо-
вания за несколько кадров. На практике часто встречаются эффекты растворе-
ния видео на черном и белом фоне. Итоговые объекты преобразований для та-
ких эффектов выглядят так:
transToBlack={ra:100. rb:-255. да:100. gb:-255.
Ьа:100. bb:-255. aa:100. ab:0}:
transToWhite={ra:100. rb:255. да:100. gb:255.
ba:100. bb:255. aa:100. ab:0}:
Обратите внимание: смещения у этих преобразований совпадают, отличается
только знак (+255 или -255). В результате мы либо прибавляем к каждому пик-
селу значение RGB с компонентами (255, 255, 255) (растворение на белом фоне),
Растворение видео на черном и белом фоне 69
frames--;
if (frames == 0) {
// Явно задать итоговое преобразование на случай, если
// целевые числа не кратны числу кадров, затем
// выполнить зачистку.
transCol.setTransform(targetTrans);
delete this.onEnterFrame;
delete transCol;
}
Попробуйте выполнить сценарий с другими видами преобразований, встречаю-
щихся в этом и предыдущих трюках.
Итоги
Два последних трюка интересны прежде всего тем, что они могут применяться
к любому анимационному клипу, а не только к клипам, содержащим видеомате-
риалы. Например, применение их к _root позволяет применять преобразования
ко всему SWF-файлу во время выполнения (хотя в некоторых ситуациях такой
вариант непрактичен из-за чрезмерной загрузки процессора). Помимо создания
впечатляющих эффектов, цветовые переходы также находят практическое при-
менение: инвертирование цвета всего содержимого сцены на 100 мс может стать
сигналом о неправильной реакции пользователя (при включении так называе-
мых специальных возможностей система Windows при выдаче сообщения об
ошибке ненадолго изменяет цвет экрана, потому что пользователи с дефектами
слуха могут не расслышать звуковой сигнал).
Добавление «видеоподобных» цветовых переходов к статической графике (ска-
жем, к растровым изображениям) обладает другим большим преимуществом: вы
можете «обмануть» пользователя и заставить его думать, что он смотрит ви-
део, - особенно если действовать хитро и разбавить последовательность реаль-
ными видеофрагментами. Эта методика способна творить настоящие чудеса, осо-
бенно для маскировки предварительной загрузки видео!
Вероятно, самые наблюдательные читатели заметили, что во всех представлен-
ных примерах данные альфа-канала оставались неизменными. Чтобы отрегули-
ровать альфа-канал, просто задайте объект преобразования, у которого свойства
га, да, Ьа или аа не равны 100. Изменение альфа-канала позволяет реализовать
такие профессиональные эффекты, как перекрестное растворение, то есть плав-
ный переход от одного видеоклипа к другому (а еще лучше - переход видеокли-
па в векторную графику Flash). Альфа-переходы интенсивно расходуют ресурсы
процессора, но, к счастью, Flash Player 7 обладает гораздо более производитель-
ным механизмом воспроизведения видео, поэтому и эта проблема перестала быть
такой серьезной.
Аналогичные принципы справедливы для звуковых преобразований. Объект зву-
кового преобразования, представленный классом Sound, позволяет создавать сце-
нарные эффекты изменения громкости и баланса (трюк 60).
72 Глава 2. Цветовые эффекты
№10 преобразования
Создание пользовательского класса для выполнения цветовых преобра-
зований.
Как было показано в двух последних трюках, существует целый ряд стандарт-
ных цветовых преобразований (см. трюк 8), которые часто применяются к целе-
вым клипам. Более того, вы уже знаете, что это требует определенных вспомога-
тельных действий, включая настройку таймеров и функций обратного вызова
(см. трюк 9). Специфика задачи наводит на мысль о том, что она хорошо подхо-
дит для оформления в виде пользовательского класса. Класс позаботится обо
всех служебных операциях и позволит выполнить цветовое преобразование про-
стым вызовом нескольких методов. В этом трюке пользовательский класс цветово-
го преобразования будет реализован на ActionScript 2.0 средствами объектно-
ориентированного программирования (ООП) вместо процедурного кода времен-
ной диаграммы, использовавшегося в предыдущих трюках.
Объектно-ориентированное преобразование
ActionScript 2.0 работает только в Flash MX 2004 или Flash MX Professional
2004. Кроме того, необходимо выбрать ActionScript 2.0 на вкладке Flash диалого-
вого окна File • Publish Settings. Более того, разработанный нами класс Transform
должен храниться во внешнем текстовом файле Transform.as (и регистр симво-
лов имени, и расширение .as являются обязательными). В Flash MX Professional
2004 для создания и редактирования таких файлов можно использовать коман-
ду File • New • ActionScript File. B Flash MX 2004 вам потребуется внешний тек-
стовый редактор (см. трюк 74). Файл .as должен находиться в одной папке с фай-
лом .fla, использующим класс Transform.
Хотя я не смогу привести полный курс ООП и ActionScript 2.0, для использова-
ния класса цветового преобразования не обязательно разбираться в тонкостях
ООП. Некоторые ключевые аспекты кода рассматриваются после листинга.
Далее приводится объектно-ориентированная версия, реализованная в виде поль-
зовательского класса Transform; этот класс должен храниться во внешнем файле
Transform.as.
// Этот код ActionScript 2.0 должен храниться во внешнем файле Transform.as
class Transform {
// NEG_TRANS - инвертирование цветовых значений.
// NEUTRAL_TRANS - сброс цветовых значений.
II BLACK_TRANS - замена цветовых значений черными пикселами.
// WHITE_TRANS - замена цветовых значений белыми пикселами.
// RATE - скорость применения эффекта в миллисекундах.
private s t a t i c var NEG_TRANS:Object = {га:-100. rb:255.
ga:-100. gb:255. ba:-100. bb:255. aa:100. ab:O};
private s t a t i c var NEUTRAL_TRANS:Object = {ra:100. rb:O.
ga:100. gb:O. ba:100. bb:O. aa:100. ab:O};
Пользовательский класс цветового преобразования 73
Создание и упорядочение
ТРЮК
Импортирование цветов
На панели Color Swatches находится пережиток прошлого, динозавр из давно
ушедшей эпохи - веб-безопасная палитра. В наше время веб-безопасная палит-
Создание и упорядочение пользовательских каталогов цветов 77
Lossy. 0 >
Perceptual U
Diffusion [vj Dithtr I ООН
No Transpar»,. V j Amount-
Чтобы загрузить цветовую таблицу в Flash, выберите команду Add Colors в меню
Options панели Color Swatches. Импортированные цвета присоединяются в конец
текущего каталога цветов.
Существует и другой, гораздо более простой способ импортирования цветов из
Photoshop: нарисуйте серию образцов в Photoshop, используя однородную кисть
или аэрограф (рис. 2.8), затем импортируйте растровое изображение в формате
без потери данных (PNG-32 или TIFF) в Flash.
> • # »
Рис. 2.8. Изображение, используемое для перенесения
цветовой палитры из Photoshop в Flash
Использование естественных цветовых схем 79
Итоги
Хотя цвета играют важную роль в определении общего настроения и впечатле-
ния от работы с веб-сайтом, средства работы с цветом в интерфейсе Flash остав-
ляют желать лучшего - например, цвета каталога не удастся разбить на группы
по вашему усмотрению. Создание пользовательских цветовых каталогов в рабо-
чей области за пределами видимой сцены позволяет обойти это ограничение.
Наконец, интерфейс Flash менее удобен для выбора и проектирования цветовых
схем, чем интерфейс Photoshop, поэтому очень важно уметь экспортировать цве-
товую информацию из Photoshop и импортировать ее в Flash.
Использование естественных
ТРЮК
Итоги
Проектирование цветовых схем в Flash (и во многих других приложениях) неред-
ко производится методом проб и ошибок, поскольку цвета, выбираемые по отдель-
ности, воспринимаются совсем не так, как в окружении других цветов. Сканирова-
ние изображения реально существующего объекта, уже содержащего желаемую
цветовую схему, и его преобразование в цветовой каталог повышает точность вы-
бора цветов, так как последний осуществляется в контексте. Утилита Gliftic ав-
томатически строит цветовые схемы на базе изображений (http://www.ransen.com/
Gliftic/Gallery/Natural-Color-Schemes.htm).
На основе работ Джошуа Дэвиса и других
трюке вы узнаете, как вручную создать эффект сепии в Photoshop и затем преоб-
разовать результат в Flash.
• . щшш ; ••'
I O l
> 1 ?| * | EPreview I
Н; 3D5 RGB
50%
M i l y*!ii В 75% Add Swatch
Close Panel
J
поэтому не стоит рассчитывать на то, что изменение цветов будет выполнено так
же точно, как в Photoshop.
Наконец, чтобы воссоздать этот эффект в ActionScript, задайте параметру Color
значение Advanced, щелкните на кнопке Settings, запомните цветовые значения
и используйте их для определения цветовых преобразований на стадии выпол-
нения (см. трюк 10).
Рис. 2.14. Создание границы кадра в виде круглого отверстия с размытыми краями
Рисование и маски
Трюки № 14-25
Говоря о «рисовании» в Flash, мы нередко говорим о двух разных вещах. Первая,
более традиционная форма рисования - рисование «от руки» - используется
художниками, создающими анимацию на Flash. Во второй форме графика создает-
ся при помощи сценариев; я называю ее «кинетическим рисованием». Кинетичес-
кое рисование не сводится к перемещению по экрану графических объектов -
вы также можете создавать графику в реальном времени и отображать промежу-
точные результаты для пущего эффекта. Рисование в реальном времени осуще-
ствляется средствами так называемого Drawing API - набора методов класса
MovieClip, в том числе lineStyle(), moveTo(), lineToQ, beginFillQ и т. д., предназначен-
ных для создания линий и заливок.
Аниматор классической школы найдет в этой главе полезные приемы для реше-
ния стандартных проблем - таких, как сокращение пикселизации вокруг краев
растрового изображения (см. трюк 23), обеспечивающее эффективное объедине-
ние растровой графики с векторным содержимым и ликвидацию неровностей
на линиях.
Разработчик сценариев узнает, как решать некоторые стандартные проблемы
Flash, в том числе проблему неточности свойства _alpha (см. трюк 19) и «сдвига
пикселов» в растровых изображениях (см. трюк 24). Также здесь описаны
приемы создания стандартных «строительных блоков» при динамическом по-
строении графического контента (скажем, рисование круга из прямой линии -
см. трюк 14).
Навыки рисования в Flash абсолютно необходимы как художникам, так и раз-
работчикам сценариев, поэтому представленные трюки должны быть доступны-
ми для всех категорий пользователей Flash. Опытные Flash-разработчики
не удивятся тому, что некоторые из трюков основаны на использовании масок.
Если вы еще не знакомы с масками, обратитесь к краткому введению в начале
главы 1.
Глава 3. Рисование и маски
№14 с заливкой
Рисование кругов с заливкой на стадии выполнения требует интенсив-
ной работы процессора. Рисование кругов из прямой линии повышает
быстродействие и обеспечивает большую гибкость по сравнению с ин-
струментами, применяемыми на стадии разработки.
Нарисовать прямоугольник с заливкой средствами Drawing API относительно
легко - вы определяете четыре угловые точки, и находящаяся между ними об-
ласть заполняется автоматически. С кругами дело обстоит сложнее. Вам придет-
ся либо аппроксимировать кривизну круга многочисленными отрезками, либо
создать серию дуг методом MovieClip.curveToQ. В обоих случаях тригонометри-
ческие вычисления замедляют работу программы и безнадежно усложняют код
для тех, кто слабо разбирается в синусах и косинусах. И все же не стоит огор-
чаться, в Flash существует очень простой способ рисования кругов с заливкой -
для этого достаточно нарисовать всего одну прямую линию.
Каждый раз, когда вы рисуете прямую, ее концы закругляются (рис. 3.1).
1111
Щ
НИ 163.0
близко, что в результате получается почти идеальный круг диаметром 200 еди-
ниц.
Рис. 3.2. Очень короткая линия, закругленные концы которой образуют круг
Программа
Следующая программа (файл dynaButton.fIa на сайте книги) строит меню, в ко-
тором круглые кнопки используются в качестве маркеров команд. Жирным шриф-
том выделен фрагмент, создающий «псевдокруги» в клипе:
function createButton(dynaButton. dynaLabel. depth, x. у) {
var c l i p = this.createEmptyMovieClip(dynaButton. depth);
clip.lineStyle(15. 0x0, 100);
clip.moveTo(0, 0 ) ;
clip.lineTo(0.2, 0);
c l i p . _ x = x:
c l i p . _ y = y;
// Необходимые действия
products_btn.onRelease = function О
// Необходимые действия
about_btn.onRelease = f u n c t i o n O
// Необходимые действия
1 inks_btл.onRelease = functionO {
// Необходимые действия
}:
При выполнении этого кода на экране появляется динамически сгенерирован-
ное меню, изображенное на рис. 3.3.
ф home
Ф products
ф about us
Ф links we like
Усовершенствование трюка
Чтобы код стал более универсальным, можно усовершенствовать идею и напи-
сать класс создания кнопок на ActionScript 2.0:
// Этот код ActionScript 2.0 должен храниться
// во внешнем файле CreateButton.as
class CreateButton {
// Переменная target определяет временную диаграмму, на которой
// CreateButton будет создавать кнопки.
private var target:MovieClip:
// Конструктор
public function CreateButton(targetTimeline:MovieClip) {
target— targetTimeline;
// Определение метода createBtnO
// Аргументы:
// buttonName - имя экземпляра создаваемой кнопки
// dynaLabel - надпись на создаваемой кнопке
// depth - глубина кнопки
// х, у - координаты создаваемой кнопки.
// Возвращаемое значение:
// Анимационный клип кнопки с. именем экземпляра buttonName.
public function createBtnCbuttonName:String. dynaLabel:String,
depth:Number, x:Number, y.• Number):MovieClip {
// Инициализация
var clip:MovieClip:
Быстрое построение кругов с заливкой , 91
var clipMask:MovieClip:
var txt_fmt:TextFormat;
var clipText:TextField;
home.onRelease = functionO {
traceC'You clicked the home button");
links.onRelease = functionO {
traceC'You clicked the links button"):
ПРИМЕЧАНИЕ
После компиляции наш класс кнопки занимает менее 1 Кбайт — он состоит
только из программного кода и поэтому хорошо сжимается. Благодаря этой
особенности он хорошо подходит для сайтов, которые должны занимать как
можно меньший объем (например, рассчитанных на мобильные устройства),
а также для конкурсов на самую компактную программу.
c1ip.lineTo(0.2. 0);
clip._x = х;
d i p . _ y = у;
}
function drag О {
this.startDrag(true);
paper.onMouseMove = drawLine;
this.onPress = drop:
}
function dropO {
this.stopDrag(true);
delete (paper.onMouseMove);
this.onPress = drop;
}
function drawLineO {
this.clearO;
t h i s . l i n e S t y l e ( 2 . 0x0. 100);
this.moveTo(pointl._x, p o i n t l . _ y ) ;
this.lineTo(point2._x, point2._y);
updateAfterEventO;
}
// Пример использования:
createPointC'pointl". 1. 100. 100):
createPoint("point2". 2. 120. 100):
pointl.onPress = drag;
point2.onPress = drag;
this.createEmptyMovieClip("paper". 0);
Протестируйте пример: щелкните на точке и перетащите ее, как показано на
рис. 3.4. Повторный щелчок останавливает перетаскивание.
Синтетическая графика
Вместо загрузки больших растровых изображений или создания готовых
макетов заставьте Flash генерировать изображения «на ходу».
Как известно, компьютеры умеют генерировать песни на основании небольшого
набора музыкальных правил. Точно так же их можно заставить генерировать
простые изображения на основе нескольких правил построения макета и разме-
щения графических объектов.
94 _^ Глава 3. Рисование и маски
Листинг
Изображение строится из нескольких секций, каждая из которых находится на
ключевом кадре анимационного клипа node. Примеры секций представлены на
рис. 3.5. Исходный текст программы хранится в файле antart.fla на сайте книги.
Фрагмент строит случайную сетку из фигур; при этом создаются узоры вроде
изображенного на рис. 3.6.
Чтобы узор получился более сложным, можно вложить в него дополнительные
копии node. Каждая копия node содержит следующий код:
i f (Math.ceil (Math.randomO < 0.80)) {
this.attachMovieC'node", "n". 0):
this["n"]._x = 50*i:
this["n"]._y = 50*j;
this["n"]._xscale = n._yscale = _parent._xscale / 1.5;
thi s["n"].gotoAndStop(Math.cei1((Math.random()*10))):
Синтетическая графика 95
liliilil
Рис. 3.7. Случайный узор, сгенерированный из базовых фигур
96 Глава 3. Рисование и маски
Итоги
В примерах продемонстрированы два стандартных приема создания синтетичес-
кой графики: рекурсия (рисование постепенно уменьшающихся копий одного
клипа внутри текущего узла) и случайное размещение. Создав набор фигур, ко-
торые хорошо сочетаются друг с другом независимо от размещения и вложения,
Энт Идеи создал узор, который всегда выглядит естественно, словно рисунок
был обдуман заранее. "
Конечно, Энт действительно все «обдумал заранее» - но лишь при проектиро-
вании форм, рассчитанных на хорошее объединение друг с другом!
Именно этот принцип заложен в основу всего «компьютерного творчества» -
программист проектирует серию фраз или визуальных образов, хорошо комби-
нируемых друг с другом (или определяет правила построения случайных пос-
ледовательностей), а затем предлагает программе показать, что же из этого вый-
дет!
Спасибо Энту Идену за творческую идею и разрешение на использование графики
Формирование мозаики
Принцип создания идеальных мозаик на удивление прост. Начните с однород-
ной сетки из треугольников, квадратов или шестиугольников (см. рис. 3.8), а за-
тем измените каждую плитку и превратите ее во что-нибудь более интересное.
Начнем с мозаики из квадратных плиток, потому что с ними проще всего работать.
Чтобы создать более интересный узор, можно вырезать или просто затемнить
часть плиток. Для создания квадратной решетки можно воспользоваться сред-
ствами привязки Flash (View • Grid • Show Grid and View • Snapping • Snap to Grid).
Нарисуйте на сцене темный круг, полностью закрывающий одну ячейку, не-
сколько раз продублируйте его и заполните все квадраты в области 2 x 2 (рис. 3.9).
На рис. 3.11 создаются простые круговые и ромбовидные формы вроде тех, что
использовались при построении синтетической график№(см. трюк 15).
-Ф-
Рис. 3 . 1 1 . Некоторые узоры, полученные применением контуров и заливок
к позитивным и негативным областям
Глава 3. Рисование и маски
Далее в полученном узоре выделяется одна плитка (рис. 3.13), которая позднее
используется для эффективного воссоздания узора (рис. 3.14).
Итоги
Конечно, ручное размещение плиток - не самый удобный способ; к тому же
плитки относительно бесполезны, если мы не сможем использовать их для за-
полнения фигур и областей по своему выбору. В трюке 17 будет показано, как
организовать мозаичное заполнение фигур.
Но прежде чем следовать дальше, попробуйте создать несколько собственных
узоров - например, заменив круги треугольниками в квадратных ячейках. Так-
же попробуйте начать с прямоугольных ячеек или других фигур, изображенных
на рис. 3.8.
return pattern;
}
var patternClip:MovieClip = t i l e r C ' t i l e P a t t e r n " . t h i s .
"patternClip". 1. 50. 50. 15. 5);
Программа создает клип patternClip и заполняет его узором, состоящим из 15 х 5
плиток; левая верхняя плитка находится в позиции (50, 50), как показано на
рис. 3.15.
-w-
"ф- -ф- -ф-
"ф*
"ф- -ф-
А
- -^»w -Aw, „ilPSu. ^»ЙЧ^ -JA- J L ^AI» -ЖЬ. -»^- ^V. ^Aw J(L. ^
> * * .
4 4 4 ,
> • « « • .
4 4 4 4 4 4 4 4
Рис. 3.16. Прямоугольный узор и круглая маска
На рис. 3.17 маска скрывает все части прямоугольника за пределами круга; в ре-
зультате мы получаем круг с узорной заливкой.
+ 4- 4- + -$•
• • • • • • >
(. 4- 4 4 * 4 4 4 %
• • * • •• • • • \
•&••&•¥ "^••4*-^'41"'4'"Ф>
• • • • • • • • •
+ + + + + + + + +
4 + + + 4 + + 4^ +
• • • • • • • • • • *
• + 4- -f ^ > * 4• + -*• +
••-••••••• •••••<
- 4- ^ •¥ Л + + + +.•.+•
> "•- > Ч- 4• Ч- 4- 4- 4- 4
* • • • ' • • • •' • >
•*• +. 4- + •••
Рис. 3.17. Результат применения маски: все внешние части
скрываются, ыостается лишь круг с узорной заливкой
102 Глава 3. Рисование и маски
Итоги
Flash не поддерживает произвольные векторные узорные заливки (растровые
заливки поддерживаются, но только на стадии разработки), однако это ограни-
чение можно обойти.
Имитация мозаик Эшера 103
Разбиение плоскости
Методика определения негативных областей (см. трюк 16) станет хорошей от-
правной точкой для решения поставленной задачи. В этой методике плитка с по-
зитивными и негативными областями использовалась для имитации геометри-
ческих узоров, однако сами плитки были квадратными, а мозаика состояла из
простых геометрических фигур. А если вдруг потребуется создать узор в стиле
Эшера со сложным взаимным переплетением фигур? Как придать плиткам бо-
лее интересную форму, не ограничивающуюся простыми квадратами и шести-
угольниками, но при этом обеспечить их идеальную стыковку?
Фокус заключается в том, чтобы начать с геометрически правильной формы
и преобразовать ее во что-то еще более интересное. Давайте снова начнем с квад-
рата, потому что с ним проще всего работать.
Нарисуйте квадрат и преобразуйте его в символ анимационного клипа клави-
шей F8. Разместите рядом с ним на сцене еще несколько экземпляров символа
анимационного клипа, чтобы в итоге получилась сетка 3 x 3 , изображенная на
рис. 3.18. Дважды щелкните на центральном клипе, чтобы войти в режим редак-
тирования «на месте».
Теперь измените, скажем, левую сторону квадрата, выгнув ее при помощи ин-
струмента Selection. Изменения отражаются на всех девяти экземплярах клипа,
как показано на рис. 3.19; теперь вы видите, как будет выглядеть сетка 3x3
104 Глава 3. Рисование и маски
Итак, правую сторону клипа тоже нужно выгнуть, чтобы она идеально стыкова-
лась с левой стороной соседней плитки. Но как обеспечить идеальное прилега-
ние? Просто скопируйте форму контура с левой стороны клипа и используйте ее
для замены правой стороны бывшего квадрата. Конечно, для обеспечения пра-
вильной кривизны можно воспользоваться инструментом Zoom. Изменение фор-
мы снова немедленно отражается на других экземплярах. На рис. 3.20 изображе-
на мозаика с идеально прилегающими плитками, которые выглядят гораздо
интереснее исходных квадратных плиток.
Без особых усилий мы создали новую форму плитки, обеспечивающую мозаич-
ное заполнение плоскости.
Имитация мозаик Эшера 105
л
III
tlllill
кliSili
{. \ ISI,
V:. ;:r:i||:i!^
Рис. 3.20. Повторение изгибов с двух сторон обеспечивает
идеальное разбиение плоскости
ПРИМЕЧАНИЕ
Секрет идеального прилегания плиток — всегда добавлять с одной стороны
плитки то, что было убрано с другой стороны.
v / 2
f f f
Рис. 3.22. Узор из вертушек
Итоги
Имитация стиля известных художников - полезное занятие; во-первых, просто
интересно узнать, что из этого выйдет, а во-вторых, ваш творческий арсенал
может обогатиться новыми идеями. В данном случае мы лишь крайне поверхно-
стно соприкоснулись со стилем М. К. Эшера. При более глубокой имитации его
работ вы сможете создать воистину выдающиеся Flash-анимации и сайты.
Исправление неточности
ТРЮК
ПРИМЕЧАНИЕ
Альфа-прозрачность замедляет воспроизведение анимации в Flash из-за необ-
ходимости обработки пикселов как изображения, так и фона. Если в результате
ошибки округления альфа-уровень будет представлять собой дробную величи-
ну менее 100 %, это замедлит работу Flash. После перехода мы задаем alpha
значение 100, чтобы предотвратить это падение быстродействия.
110 Глава 3. Рисование и маски
Итоги
Анимированные альфа-эффекты интенсивно используют вычислительные мощ-
ности процессора, поэтому потенциальная неточность свойства _alpha способна
сильно замедлить работу приложения. Клип с альфа-уровнем 99,6078 % внешне
не отличается от клипа с альфа-уровнем 100 % (то есть полностью непрозрачно-
го), но воспроизводится гораздо медленнее! Чтобы написать эффективный код
анимации альфа-эффекта, необходимо знать о потенциальных ошибках округле-
ния свойства _alpha и уметь справляться с ними.
Вероятно, борцы за чистоту ООП брезгливо поморщатся при виде решения в сти-
ле ActionScript 1.0, основанного на применении прототипов, однако этот синтак-
сис поддерживается в ActionScript 2.O. Помните, что субклассы ActionScript 2.0
компилируются в тот же байт-код, что и решение с применением прототипов.
Используйте тот вариант, который вам кажется более удобным (наследование
на базе прототипов, композиция или формальное наследование).
Сложные маски
Маски Flash должны быть сплошными. Если в качестве маски используется слож-
ная фигура (например, бублик), Flash упрощает ее. В этом нетрудно убедиться
на следующем простом примере.
В новом документе присвойте первому слою имя background, затем добавьте над
ним два уровня с именами maskLayer и actions (рис. 3.24).
iiiiiiiie
• •• 1Ё1Й! |Я1Щ|1§1
На слое maskLayer создайте фигуру в виде бублика (рис. 3.26). Нажмите клави-
шу F8, чтобы преобразовать ее в символ анимационного клипа. Присвойте сим-
волу имя mask, задайте клипу имя экземпляра maskClip.
•
I
i
L Л •
i
:
'•:•• • •, •••,:•:. '.; : i |- / г •
}
mc.onMouseUp = functionO
delete this.onMouseMove;
this.stopDragO;
}ragDrop(maskCp
d il):
backCpil.setMask(maskCp
il);
Небольшое отступление: плавное перетаскивание клипа является задачей на-
столько распространенной, что для ее решения стоит создать специальный класс.
Далее приведен пример класса для выполнения плавного перетаскивания:
// Этот код ActionScript 2.0 должен храниться
// во внешнем файле SmoothDrag.as
class SmoothDrag {
public function SmoothDrag(targetClip:MovieClip) {
dragDrop(targetClip);
}
private function dragDrop(mc:MovieClip):Void {
Использование сложных фигур в качестве масок 115
mc.onPress = functionO {
mc.onMouseMove = functionO {
updateAfterEventO;
}
mc.onMouseUp = functionO
delete mc.inMouseMove;
mc.stopDragO;
Для масок Flash устанавливается одно важное ограничение: они должны иметь
непрерывный периметр. Таким образом, если прорезать в «бублике» небольшую
щель, его контур будет непрерывным. Проблема в том, что после вырезания
щели О-образный бублик превратится в букву С. Щель должна быть настолько
маленькой, чтобы Flash игнорировал ее при выводе, но достаточно большой для
того, чтобы вся фигура рассматривалась как единая форма с непрерывным пери-
метром. Для этой цели будет использоваться прорезь в виде волосяной линии.
Выделите экземпляр maskClip и дважды щелкните на нем, чтобы перейти в ре-
жим редактирования «на месте». Активизируйте инструмент Line и нарисуйте
волосяную линию по радиусу «бублика», как показано на рис. 3.28.
116 Глава 3. Рисование и маски
•Ы-ihairtne-
У Urn
tool
В ы д е л и т е н а р и с о в а н н у ю л и н и ю и в ы п о л н и т е к о м а н д у Modify • S h a p e • Convert
Lines to Fills, чтобы преобразовать линию в фигуру. Обратите внимание: толщина
созданной линии меньше 1 пиксела (на моем компьютере она составляет 0,3 пик-
села). Теперь удалите фигуру. После удаления на «бублике» остается щель тол-
щиной 0,3 пиксела. Если увеличить масштаб и сравнить изображение с сеткой
пикселов, как показано на рис. 3.29, становится видно, что толщина линии мень-
ше 1 пиксела.
Рис. 3.30. Маска с тонким разрывом (слева) и она же при большом увеличении (справа)
Интерференционные картины
ТРЮК
Эффект на рис. 3.32 был создан при помощи двух наборов концентрических
колец с прорезями (см. трюк 20), гарантирующими, что в масках, несмотря на их
внешний вид, отсутствуют замкнутые области. При размещении фигур друг над
другом получается однородный круг, но если сместить одну фигуру и назначить
ее маской для другой, получится узор, изображенный на рис. 3.32. А если умень-
шить толщину кругов и сблизить их, картина приобретает по-настоящему пси-
ходелический вид (рис. 3.33).
Применяя эти узоры для маскирования графики или другого контента, можно
создать интересные эффекты переходов. Вдобавок тот, кто не знает об этом трю-
ке, не сможет повторить его - несомненное преимущество для законодателей
моды Flash.
При помощи сложных масок можно разделить изображение на несколько раз-
дельно маскируемых частей, а также применить сценарные волновые эффекты.
Визуальный эффект на рис. 3.34 создан посредством применения маски к двум
листам, один из которых был повернут.
Итоги
Многие разработчики недооценивают возможности масок. Хотя в документации
Flash сказано, что маски предназначены для скрытия контента, в действительно-
Сглаживание краев на растровых изображениях 119
сти эта формулировка не дает должного представления о том, что можно сде-
лать при помощи масок. Область применения масок чрезвычайно широка - от
экзотических переходных эффектов до сугубо утилитарных пользовательских
компонентов. Когда сценарные маски впервые появились в Flash, они стали на-
стоящим даром небес для квалифицированных разработчиков. Позднее народ
осознал ограниченность простых масок. Но после знакомства с представленным
трюком препятствий на вашем пути станет гораздо меньше!
Еще один пример нетривиального использования масок встречается при описа-
нии трюка с листанием страниц (см. трюк 25).
№22 изображениях
Векторная графика при любом разрешении отличается хорошим сгла-
живанием краев, но" в некоторых ситуациях приходится использовать
растровые изображения. От очевидных дефектов краев растровых изо-
бражений можно избавиться при помощи альфа-канала или векторных
краев.
Иногда растровая графика оказывается предпочтительнее векторной, особенно
при работе с текстурными объектами (в отличие от областей с однородной или
почти однородной заливкой, которые лучше представляются в векторной графи-
ке). Именно эта причина обусловила применение растровых изображений в не-
которых современных анимациях (хорошие примеры - http://www.centrifuga.net/
desiderata.html и http://www.centrifuga.net/gab.html).
Серьезным недостатком растровых изображений является пикселизация. В на-
стоящем трюке представлены два способа борьбы с неровностями краев на рас-
тровых изображениях. Как правило, пикселизация сильнее всего проявляется
при резких различиях между цветами изображения и его фона (на границах
с менее резкими переходами цветов пикселизация обычно не столь заметна). На
техническом жаргоне эти зубчатые линии обычно называются «пилой». Впро-
чем, такая ступенчатость характерна для любых цифровых данных (в том числе
и звуковых - см. трюк 58) при недостаточной частоте выборки, которая и явля-
ется причиной появления артефактов. Методика решения проблемы носит на-
звание сглаживания (antialiasing). Одно из решений основано на применении
альфа-прозрачности: размывка областей, прилегающих к краям растрового изоб-
ражения, улучшает слияние с фоном и одновременно предотвращает эффект
ореола (когда изображение окружается по периметру светлыми пикселами).
Рис. 3.39. Край размытого (слева) и неразмытого (справа) растра при увеличении
Произведите разбивку растра командой Modify • Break Apart. Это позволит рабо-
тать с растром, применяя векторные инструменты.
Переместите векторный контур с текущего слоя на один слой с растровым изоб-
ражением. Перемещение проще всего выполняется через буфер обмена:
1) заблокируйте все слои кроме слоя, на котором находится векторный контур;
2) нажмите клавиши Ctrl+A (Windows) или «Н>+А (Мае), чтобы выделить контур.
Скопируйте его в буфер клавишами Ctrl+X (Windows) или §€+Х (Мае);
3) разблокируйте слой, на котором находится растровое изображение. Заблоки-
руйте все остальные слои. Убедитесь в том, что текущее выделение отсутствует,
щелкните правой кнопкой мыши (Windows) или щелкните с нажатой клави-
шей Ж (Мае) и выберите в контекстном меню команду Edit • Paste in Place.
Выделите остальные пикселы за пределами контура и нажмите клавишу Delete.
Наконец, осторожно удалите контур (рис. 3.43) - вокруг растрового изображе-
ния появляется идеально четкая векторная граница!
Исправление ошибки сдвига 125
Итоги
Настоящий раздел убедительно показывает, что для интеграции растров в четко
очерченный векторный мир Flash можно сделать довольно много. Круг возмож-
ностей не ограничивается скрытием неровностей при помощи альфа-масок -
существует и такой вариант, как создание «псевдовекторной фигуры», состоя-
щей из растра с векторным контуром (впрочем, правильнее было бы назвать ее
векторным контуром с растровой заливкой).
гййЭЗИ ок
! : :
Ш^ШШШЩ^ Щ1ШР^^?^- Й&: •• • • Cancel'
ПРИМЕЧАНИЕ
Получается, что, исправляя ошибку для Flash Player 6, вы создаете ошибку в Flash
Player 7. Если результат должен экспортироваться в формат Flash Player 7, не
используйте этот трюк.
this.createEmptyMovieClip("myImageLoader". 2);
this.mylmageLoader.onEnterFrame = functionO {
i f (this._pa'rent.mylmage._width > 1) {
// Изображение было загружено
this._pareirt. my Image. _xscale = 99.98:
this._pa rent, my Image. _yscale = 99.98;
thi s.removeMovi eCli p():
Листание страниц
Недавно арсенал классических трюков Flash пополнился эффектом листа-
ния страниц (один из ранних примеров можно найти по адресу http://wel-
come.hp.com/country/us.en/msg/corp/flashdreamworks.html). Во время началь-
ного обсуждения подборки трюков для включения в книгу мой редактор Брюс
Эпстейн сказал: «Было бы здорово, если бы мы могли описать эффект листа-
ния страниц. Я видел, как Эрик Нацке кратко описывал процесс на семинаре
Flash Forward. Ты знаешь, как это делается?» Я понятия не имел, как реали-
зовать этот трюк, но во время разговора я машинально делал наброски
(я вообще всегда что-нибудь рисую, когда говорю по телефону, - это помога-
ет думать).
На рис. 3.47 представлена схема моего решения эффекта листания страниц. Ри-
сунок дает полное представление об идее, на которой базируется весь эффект;
набросав эту схему, я сразу сказал Брюсу: «Думаю, я довольно быстро разберусь
с этим эффектом, ставь его в план».
Эффект листания страниц 131
§11
W^ г.
maskReverse me
maskNew me
Итоги
Эффект листания страниц впервые был создан Эриком Нацке (http://
www.natzke .com), выдающимся дизайнером и автором многих впечатляющих
SWF. Именно после знакомства с его работами я осознал, что многие графичес-
кие эффекты базируются на симметрии и эффектах частиц (а иногда - и том
и другом!) Соответствующий образ мысли поможет вам не только воспроизвес-
ти работы Эрика, но и расширить их.
В этом трюке представлены основные концепции эффекта листания страниц,
демонстрирующие общий подход к воссозданию подобных эффектов:
• найдите и выделите базовые структурные элементы (из которых самым рас-
пространенным является симметрия, но также встречаются и другие - на-
пример, фракталы и эффекты частиц). Нарисуйте диаграммы с указанием
места этих концепций в эффекте. Используйте ту систему наглядных обозна-
чений, которая вам покажется наиболее удобной;
• чтобы развить идею, сделайте дополнительные наброски, описывающие пе-
реход от базовой идеи к ее реализации в Flash. Если вы не понимаете, как
создается эффект, скорее всего, в нем используется маска. По собственному
опыту могу сказать, что маски в сочетании со сценариями обычно создают
самые неочевидные эффекты;
• не пытайтесь немедленно преобразовать все концепции в математические
формулы, потому что визуальное предоставление упрощает выделение зако-
номерностей или поиск полезных концепций высокого уровня. Несмотря на
все преимущества, математические уравнения плохо подходят для преобра-
зования в визуальную форму. Они скорее абстрактны, нежели визуальны (ве-
роятно, именно из-за этого большинство дизайнеров испытывает к ним под-
сознательное отвращение!).
В этом трюке основное внимание уделено анализу сути эффекта, а не его реали-
зации. Надеюсь, вы согласитесь с тем, что этот аспект более важен. Освойте его,
и у вас появится ключ, который позволит немедленно раскрыть сущность любо-
го новомодного графического эффекта.
Пример реализации эффекта листания страниц pageturn.fla находится на сайте
книги.
ГЛАВА 4
Анимация
Трюки № 26-34
Настоящая глава посвящена подлинной сущности Flash: анимации. Интерфейс
Flash основан на приемах традиционной покадровой анимации. Временная диа-
грамма Flash является электронным аналогом серии кадров; каждый кадр пред-
ставляет собой квант времени, а отображение последовательных кадров создает
иллюзию движения. Во Flash, как и в традиционных средствах анимации, под-
держивается концепция слоев, используемых для последовательного формиро-
вания анимации от заднего плана к переднему; разные элементы располагаются
на разных глубинах.
Ключевые и промежуточные кадры Flash тоже покажутся знакомыми всем, кто
имел дело с традиционной анимацией: обычно ведущий художник рисует клю-
чевые кадры, а его подручные занимаются черновой работой по построению
промежуточных кадров. В Flash ключевые кадры создает дизайнер, a Flash авто-
матически генерирует промежуточные изображения. Все изменения, вносимые
аниматором (например, перемещение графики на новое место), должны проис-
ходить в ключевых кадрах. Кадр 1 всегда является ключевым, а дополнительные
ключевые кадры создаются командой Insert • Timeline • Keyframe (или клави-
шей F6). Допустим, вы создали графический объект в кадре 1 и разместили его
в левой части сцены. Затем в кадре 19 создается ключевой кадр, и графический
объект перемещается в новую позицию в правой части сцены. Чтобы создать
анимацию, выделите начальный и конечный ключевые кадры на временной диа-
грамме и задайте параметру Tween на панели свойств значение Motion (или вы-
полните команду Insert • Timeline • Create Motion Tween). Flash автоматически ге-
нерирует промежуточные изображения, в результате чего объект перемещается
по сцене за 19 шагов. Чтобы убедиться в этом, достаточно прокрутить воспроиз-
ведение первых 19 кадров.
Графика, размещенная на слое, отображается на сцене до тех пор, пока на этом
слое не встретится пустой ключевой кадр. Например, если вы хотите убрать
графический объект со сцены после кадра 19, вставьте пустой ключевой кадр
в кадре 20 (команда Insert • Timeline • Blank Keyframe или клавиша F5).
Хотя Flash выполняет за разработчика большой объем работы, в этой главе бу-
дут представлены многие трюки, которые пригодятся как опытному аниматору,
так и новичку. Создание анимации требует времени и опыта, поэтому трюки
прежде всего направлены на ускорение работы и упрощение процессов. В отли-
Плавное сценарное движение 135
-•X У
•х
}
var drawClip:MovieClip = this.createEmptyMovieClipC'drawClip",
thi s.getNextHi ghestDepth()):
drawClip.onMouseDown = penDown;
138 Глава 4. Анимация
Итоги
Мысль об использовании обработчиков onEnterFrame для анимации выглядит
заманчиво, и все же это не единственное событие, применяемое для создания
анимации в Flash. В этом разделе была рассмотрена ситуация, в которой обра-
ботка события onMouseMove обеспечивала более эффективную и плавную ани-
мацию. Эффективность объясняется меньшими затратами вычислительных мощ-
ностей (экран обновляется только при необходимости), а плавность - тем фактом,
что частота возникновения событий onMouseMove не связана с частотой смены
кадров (в отличие от события onEnterFrame).
Хотя анимация на базе обработки события onMouseMove возможна только в том
случае, если действия пользователя связаны с перемещением мыши (например,
при операциях перетаскивании или рисования), при желании можно найти и дру-
гие события, синхронизируемые с обновлением экрана. Например, обновление мо-
жет происходить при получении данных или завершении воспроизведения звука.
Тем не менее, в некоторых случаях анимация должна синхронизироваться по
времени. К счастью, onEnterFrame - не единственное событие, связанное с вре-
менем. Если потребуется создать несколько анимаций с разными частотами сме-
ны кадров, обычно лучше использовать функцию setlntervalQ для раздельного
хронометража событий (см. трюк 27), вместо того чтобы использовать обработ-
чик onEnterFrame для всех анимаций.
function enterFrameMover():Void {
this._x += speed;
i f (this._x > 550) {
delete this.onEnterFrame:
}
function drawBall(clip:MovieClip. x:Number. у:Number):MovieClip
var mc:MovieClip = this.createEmptyMovieClip(clip.toString().
thi s.getNextHi ghestDepth()):
Быстрая и компактная анимация символов 141
Итоги
Хотя кое-кто жалуется на недостаточную быстроту Flash Player, существует много
способов ускорить работу кода. Правильный выбор обработчиков событий (см.
трюк 26), благодаря которому код выполняется только в случае необходимости,
делает анимацию более плавной и улучшает ее субъективное быстродействие.
Другие трюки из области оптимизации приводятся в главе 9.
№28 символов
Ручное построение анимации занимает целую вечность. Несколько фо-
кусов «для служебного пользования» от аниматора, работавшего на сту-
дии Диснея, избавят вас от части тяжелой работы.
При работе над анимацией Flash всегда приходится решать вопрос, как добиться
цели минимальными средствами, поскольку пропускная способность канала
142 Глава 4. Анимация
Стилизованная походка
В процессе работы над реалистичным циклом ходьбы приходится решать две
проблемы:
• ходьба не сводится к простой перестановке ног - голова смещается вверх
и вниз, руки двигаются в воздухе, а корпус слегка покачивается. Если не вклю-
чить все эти элементы в анимацию, возникает впечатление, что на идущего
надели жесткий, негнущийся костюм;
• скорость ходьбы должна соответствовать скорости движения. Звучит тривиаль-
но, но вам, наверняка, попадались видеоигры или дешевые мультфильмы,
в которых персонажи словно скользят вдоль пола. Эффект возникает из-за
того, что скорость движения не совпадает с частотой перестановки ног.
Для создания реалистичного цикла ходьбы необходимо множество кадров и хо-
рошее чутье аниматора.
Одно из возможных решений проблемы - создание цикла ходьбы, в котором
нарушение перечисленных правил несущественно. Создайте упрощенную ани-
мацию (с меньшим количеством кадров), которая будет выглядеть эксцентрич-
ной и непохожей на нормальную походку; персонаж даже может ненадолго за-
висать в воздухе, что сведет к минимуму эффект скольжения. При грамотной
реализации стилизованная походка даже сделает вашего персонажа более ори-
гинальным.
Крайним случаем такого рода служит Тасманийский дьявол из мультфильма
студии «Warner Bros». Он двигается настолько быстро, что его невозможно раз-
глядеть, - по экрану просто проносится вихрь из одной точки в другую. Это
хороший пример того, как простота анимации изначально закладывается в кон-
цепцию персонажа.
Сайт, над которым работали мы с Адамом, обладал оригинальным интерфей-
сом - вместо того чтобы перемещаться по сайту при помощи мыши, посетитель
водил за ней персонажа по имени Скриббл. Если Скриббл не занимался чем-то
иным (например, обижался, разглядывал найденный предмет или просто думал
о чем-то своем), он следовал за указателем мыши.
Быстрая и компактная анимация символов 143
Итоги
Хотя идеи, заложенные в основу этого трюка, после прочтения кажутся триви-
альными, в веб-анимации они встречаются не так уж часто. Аналогичная мето-
дика применима к любой циклической анимации (например, полету птицы).
Идеально плавная анимация нужна не всегда. Более того, довольно часто сни-
жение количества кадров лучше передает движение и делает его более ориги-
нальным. Конечно, не стоит забывать и о таких положительных аспектах, как
сокращение времени загрузки и объема работы!
Если вам захочется узнать, как выглядит Скриббл в деле, ознакомьтесь с одной
из наших ранних работ scribbleWalk.fIa на сайте книги. Также обратите внимание
на код кадра 1 уровня actions в загруженном файле. В этом коде также применен
ряд других оптимизаций, но их поиск поручается читателю для самостоятель-
ной работы.
Processing
*&
KoolMoves
Итоги
У среды разработки Flash существует немало альтернатив; одни используют
формат SWF (и требуют Flash Player для воспроизведения), другие работают
148 Глава 4. Анимация
каждые 209 кадров (20,9 с при частоте смены кадров 10 fps), а не каждые 20
кадров (2 с),, как при использовании клипов длиной 20 и 10. Неплохо, если
учесть, что более длинная анимация состоит из 19 кадров. Итак, если каждая
кадрированная анимация, выполняемая в цикле, имеет длину, выраженную про-
стым числом (и отличную от длины других анимаций), повторения будут разде-
лены максимальными промежутками.
Наверное, лучшим примером использования простых чисел в FLA служит мой
самый первый Flash-файл. Мне хотелось создать анимированную картинку от-
дыхающей бабочки. Движения бабочек, как и большинства одушевленных объек-
тов, хаотичны и непредсказуемы:
• крылья периодически складываются и раскрываются, даже если бабочка не
собирается взлетать;
• усики двигаются;
• все тело насекомого слегка подрагивает.
На рис. 4.7 представлено несколько начальных кадров ролика - моего первого
опыта в компьютерной анимации.
Итоги
Хотя для создания неповторяющейся анимации проще воспользоваться Action
Script, некоторые анимации просто лучше работают в кадрированном варианте.
Конечно, основные проблемы с кадрированием возникают из-за фиксированно-
го, циклического характера анимации. Немного математики, нестандартный под-
ход к вопросу - и проблема легко решается.
раз через каждые 14 535 931 кадров (примерно две недели при 12 fps), так что
может считаться почти случайной.
В моем варианте реализации используется пять кадрированных анимаций, каж-
дая из которых выделена в отдельный клип. В каждом клипе текст падает сверху
вниз (рис. 4.10).
щ «
• .
1
п|
т ж
т
з| \ы
\4\
: я&я.
\п\ h
] ж№\ d
|э| am
s
1*1*1
w и
*
Рис. 4.9. Три статических текстовых поля, используемые
в качестве основы для построения анимации
Movie Clip
Movie Clip
Movie Clip
Movie Clip
Итоги
Повторение циклов анимации довольно часто встречается даже в коммерчески
успешных анимационных проектах. Например, главный герой едет на машине,
и в окнах подозрительно часто мелькает одна и та же комбинация уходящих
вдаль деревьев, пригородных домов и припаркованных машин. А когда видишь,
что в саду перед домами с номером 56 играют одни и те же дети, все становится
ясно. Такое происходит из-за того, что даже в высокобюджетных проектах ани-
мация обходится дорого, поэтому постановщик старается по возможности сэко-
номить. И все же подобные ухищрения не должны бросаться в глаза, а трюк
с простыми числами помогает скрыть циклическое повторение отдельных анима-
ций. Реализм компьютерных спецэффектов растет, и даже сцены из реальной жизни
содержат повторяющиеся элементы. Например, огромная толпа в Вашингтоне
из фильма «Форест Гамп» в действительности состоит из маленькой группы лю-
дей, многократно повторенной. В фильме «Шоу Трумэна» обитатели фальшиво-
го городка регулярно повторяют одни и те же действия (машины кружат по
кварталу и т. д.), причем главный герой в исполнении Джима Керри замечает это.
Возможно, на уроках математики вы думали, что с простыми числами имеют дело
только математики. Оказывается, даже Тому и Джерри не обойтись без них.
Анимация персонажа,
ТРЮК
• : • :• s • •
Возможно, фигуру Минни стоит немного сдвинуть назад на сцене Poser, чтобы
она полностью помещалась на сцене Flash при анимации в формате SWF (дело
в том, что сцена Poser имеет квадратную форму, тогда как сцена Flash обычно
представляет собой прямоугольник, и при просмотре в Flash верхняя и нижняя
части фигуры будут усечены). Для этого найдите на экране кнопки Editing Tools
(если они не отображаются, выполните команду Window • Editing Tools). Щелк-
ните на кнопке Translate In/Out (рис. 4.16) и перетащите указатель мыши вверх
или вниз, чтобы передвинуть Минни назад или вперед.
R a s h S e t t i n g s C a n c e l
tSH Export
Number of colors:
Quantization: (* M Frames
Щелкните на кнопке OK, чтобы подтвердить параметры в окне Flash Export. По-
вторный щелчок на кнопке ОК создает SWF-ролик.
Чтобы импортировать сгенерированный ролик в Flash, создайте новый или от-
кройте существующий файл FLA и выполните команду File • Import • Import to
Stage.
Анимация отображается в виде серии ключевых кадров на одном слое. Графи-
ческие формы объединяются в группы. Как и при всех операциях экспортирова-
ния, следующим шагом должна стать оптимизация анимации. Оптимизация дан-
ных Poser очень близка к оптимизации данных Swift 3D.
Возможно, вам помогут следующие рекомендации:
• отмените группировку содержания каждого кадра, затем выполните оптими-
зацию (Modify • Shape • Optimize) и/или сглаживание (Modify • Shape • Smooth);
• Poser, как и Swift 3D, не преобразует часто используемые фигуры в символы
для повторного использования. Вы должны сами найти такие фигуры и ре-
шить проблему. Например, ноги и юбку Минни явно можно заменить не-
большим количеством символов, которые могут многократно использоваться
в разных кадрах.
На рис. 4.19 представлен процесс оптимизации с применением развертки конту-
ров, а также стандартных приемов и графических инструментов Flash.
Более опытные Flash-дизайнеры предпочитают импортировать изображения из
Poser в виде опорных растровых изображений и трассировать их в векторную
форму, как показано на рис. 4.20. Я тоже предпочитаю этот способ; несмотря на
некоторое увеличение объема ручной работы, он сохраняет дух «ручной прори-
совки» и экономит время. Кроме того, такая графика лучше оптимизируется.
160 Глава 4. Анимация
Итоги
Poser часто используется совместно с Photoshop для построения любой графи-
ки, в которой задействованы модели персонажей. Совместно с Flash эта про-
грамма используется довольно редко.
Хотя создание трехмерных персонажей и их анимация в Poser с последующей
ручной оптимизацией каждого кадра в Flash занимают довольно много времени,
по сравнению с ручной реализацией эта процедура способна сэкономить целые
месяцы тяжелой работы (особенно при наличии опыта работы в Swift 3D).
Эффекты частиц 1G1
}
var path:MovieClip = this.createEmptyMovieClipC'path". 0):
var dot:MovieClip = this.path.createEmptyMovieClipC'dot". 0);
dot.lineStyleCO. 0x0. 100);
dot.moveTo(0. 10);
dot.lineTo(0. 15):
dot.speed = Math.randomO * 10 + 5;
dot.onEnterFrame = mover;
Приведенный фрагмент создает клип path, в котором создается другой клип
с именем dot. Затем клип dot перемещается от верхнего края экрана вниз. Возни-
кает резонный вопрос: для чего мы создали path? В этом и заключается суть
трюка - поворачивая path, можно изменить направление перемещения dot. По-
пробуйте добавить следующий фрагмент в конец предыдущего листинга и по-
смотрите, как это делается.
// Перемещение клипа в точку (100.100), чтобы он
// оставался видимым даже при повороте,
path._x = path._y = 100;
path._rotation = 50;
Поворачивая path, мы изменяем направление движения dot. Более того, масшта-
бированием path в процессе перемещения dot можно создавать сложные эффек-
ты ускорения без лишней работы.
162 Глава 4. Анимация
Звездный поток
В следующем листинге приведена измененная версия этого кода. Обратите вни-
мание: операции масштабирования и поворота выделены жирным шрифтом.
Программа предполагает, что сцена была окрашена в черный цвет (выполните
команду Modify • Document, щелкните на образце и выберите черный цвет).
function moverО {
// Перемещение частиц во времени
this._y += this,speed:
this.yscale =+= 10;
this.speed++:
i f (this._y > 500) {
this._y = 0:
this.speed = Math.random()*10;
this._yscale = 100:
function starField(x, y. n) {
// Построение звездного потока заданных размеров из п звезд
for (var i = 0: i < n: i++) {
var star = this.createEmptyMovieClipC'star" + i. i):
var dot = star.createEmptyMovieClip("dot". 0):
star._rotation = Math.randomQ * 360;
star._x = x;
star._y = y;
dot.lineStyleCO. OxFFFFFF. 100);
dot.moveTo(0. 10):
dot.lineTo(0. 15):
dot.onEnterFrame = mover:
dot.speed = Math.random()*10;
}
starField(275. 200. 100):
В этом коде мы создаем множество клипов star, каждый из которых принимает
на себя роль клипа path, рассмотренного в предыдущем примере. Каждый клип
star поворачивается под случайным углом (рис. 4.21).
Клипы star также подвергаются масштабированию; растяжение траектории (клип
star) во время движения dot ускоряет перемещение и создает иллюзию того, что
при приближении к зрителю объект движется быстрее.
Трюк с масштабированием path во время движения dot может использоваться
для создания эффекта гравитации (см. трюк 38). В следующем листинге те же
приемы имитируют Движение воды:
function mover():Void {
this._у += this.speed:
this._yscale =+= 10:
this.speed++:
i f (this._y > 500) {
this._y = 0:
this.speed = Math.randomO * 10:
Эффекты частиц 163
}
waterfall(200. 300. 800);
}
function snow(a. n)
1В4 Глава 4. Анимация
}
snow(30. 800);
Итоги
Хотя эффект частиц может строиться и в координатах (х, у), вы рискуете увяз-
нуть в сложных тригонометрических вычислениях и изменениях траекторий.
Использование внедренных клипов для определения угла траектории и скорос-
ти частиц (то есть их описания в полярных координатах) упрощает программи-
рование эффекта и требует минимальных вычислений; это способствует увели-
чению количества частиц и упрощает реализацию эффекта.
Из рисунка понятно, что происходит при морфинге. Flash вполне разумно пыта-
ется преобразовать внешний контур «е» во внешний контур «с», но не знает, что
делать с внутренним контуром, поскольку у буквы «с» такого контура нет. Та-
ким образом, без введения дополнительных линий сделать ничего не удастся.
Ранее уже был описан прием создания прорезей в фигурах (см. трюк 20). Ис-
пользуя его, вы, фактически, обманываете Flash и заставляете его думать, что
сложная фигура (с несколькими замкнутыми контурами) имеет более простую
форму. Аналогичный трюк может использоваться и для сближения разнород-
ных фигур, обеспечивающего более гладкий морфинг.
Применяя ту же методику, мы просто надрезаем петлю буквы «е», чтобы обе
буквы имели одинаковое количество замкнутых контуров. Местонахождение
разреза выбирается таким образом, чтобы Flash было проще преобразовать одну
фигуру в другую. Возможно, с выбором придется немного поэкспериментиро-
вать, но вскоре у вас разовьется необходимая интуиция. В нашем случае разрез
лучше всего расположить в любом месте вдоль горизонтальной линии, образую-
щей нижнюю сторону петли в букве «е». Выберите волосяную линию в свой-
ствах инструмента Line на панели свойств и проведите линию в выбранной точ-
ке. Преобразуйте линию командой Modify • Shape • Convert Lines to Fills и удалите
ее. Контур замкнутой области сливается с внешним контуром, и фигура стано-
вится одноконтурной.
Как видно из рис. 4.23, на этот раз морфинг дает гораздо лучший результат.
Лишние петли исчезают, a Flash принимает вполне разумные решения при уп-
равлении переходом. Теперь Flash правильно преобразует контур «е» в контур
«с», поскольку каждая буква имеет только один замкнутый контур.
Ь'-\
Итоги
Векторная графика снижает объем пересылаемых данных, но из-за потенциальных
затрат на обработку Flash накладывает ряд ограничений на ее использование -
например, предполагая, что начальная и конечная формы морфинга имеют оди-
наковое число замкнутых контуров. Как было показано раньше, для преодоле-
ния этих ограничений абсолютно необходимо хорошо разбираться в них. А как
только вы поймете, что Flash вычисляет промежуточные состояния не только
для начальной и конечной фигур, но и для замкнутых контуров, проблему мож-
но считать наполовину решенной.
ГЛАВА 5
ТРЮК
Имитация трехмерной графики
№35 Flash не обладает полноценной поддержкой трехмерной графики, но чтобы
добиться желаемого эффекта, можно разместить фрагменты двухмер-
ного изображения так, словно они находятся в трехмерном простран-
стве.
Flash не обладает поддержкой трехмерной графики, однако объемный эффект
можно имитировать различными способами. Одно из решений - разбить двух-
мерное изображение на срезы и расположить их так, чтобы создать иллюзию
объема.
Примеры использования данного трюка встречаются на многих сайтах - напри-
мер, трехмерная голова на сайте sofake (зайдите на сайт http://www.sofake.com,
щелкните на десятом белом квадратике в нижней части основной страницы и от-
кройте ссылку haircut.swf), а также «Предводитель свободного мира» Энди Фулдса
(откройте страницу http://www.foulds2000.freeserve.co.uk/index_v2.html и щелкни-
те на восьмом квадрате над заголовком Amusements). Тем не менее, впервые
я столкнулся с ним еще во времена Flash 4; тогда его использовали Руйен Зарин
(http://www.zarinmedia.com) и Энт Идеи (http://www.arseiam.com). Энт Идеи раз-
работал превосходный механизм для работы с трехмерными срезами, расширяю-
щий концепцию поворота и масштабирования (щелкните на ссылке 3D на странице
http://www.arseiarri.com/index2.htm). Он позволяет перемещать срезы в трехмер-
ном, а не в двухмерном пространстве, как в этом трюке.
Ранее говорилось о том, как для создания анимации импортировать GIF-файл
в Flash и воссоздать его с расширенными возможностями анимации (см. трюк 4).
В этом трюке используется талисман издательства O'Reilly - долгопят с облож-
ки книги «Learning the vi Editor». Мы перенесем его в трехмерный мир. На
рис. 5.1 долгопят не выглядит объемным; чтобы полностью оценить эффект, за-
грузите файл critterO2.fla с сайта книги.
O ' R E I L L Y ®
ШШШШШШЩШШШШ&ШШШ
©
O ' R E I L L Y
O ' R E I L L Y ®
Долгопят в нарезке
Для создания срезов мы воспользуемся универсальным инструментом - маска-
ми. Подумайте, как будет выглядеть долгопят, если его разделить на поперечные
срезы, а потом снова собрать их вместе: вместо внутренних органов будет видна
только шкурка. Примерный вид срезов показан на рис. 5.2.
Улавливаете? Перед вами простая маска в форме круга, центр которой находит-
ся на носу долгопята (ближайшая к зрителю точка в трехмерном пространстве).
Тем не менее, если наложить срезы друг на друга на плоском экране, никакой
иллюзии объема не появится; все, что мы увидим, - это исходное изображение
Имитация трехмерной графики 171
••ияЯтт я >.
о ' к а•. -
• аи .
. tj::
* % I-.->.:ISli,
Ш -•
Итоги
Теперь, когда вы уловили общий принцип, наш эффект имитации трехмерности
можно было бы усовершенствовать. Фактически, базовая методика отображает
срезы изображения на конус. Если отвести указатель мыши очень далеко от
долгопята, конус становится четко различимым, как показано на рис. 5.4.
—|-|
г-|
—1
,,„ ,„.,
- -
- - LJ
}
arrow.onMouseDown = function О {
// Если кнопка мыши нажата, изменить xpos для создания эффекта прокрутки
// при вызове redrawStripsO
this.onEnterFrame = function О {
i f (this.islnside) {
this._parent.xpos -= ((this._parent.viewWidth / 2) - t h i s . j O / 10;
// Максимальная скорость перемещения
this._pa rent. redrawStripsO;
arrow.onMouseUp = functionO {
this.onEnterFrame = undefined:
}:
Приведенный код реализует только панораму с возможностью прокрутки вле-
во/вправо, а прокрутка по вертикали не поддерживается; однако он достаточно
прост и при необходимости легко модифицируется.
Оптимизированный трехмерный плоттер 181
Итоги
Flash не может конкурировать со специализированными программами просмот-
ра панорам по качеству и скорости, но возможность интеграции панорам в роли-
ки и управление ими на уровне ActionScript является большим преимуществом.
Простейшие панорамы - не более чем основа; например, средствами ActionScript
в них молено включить активные зоны пли ссылки. Трюк с построением цилин-
дрической панорамы улучшает эффект присутствия, не требуя от пользователя
загрузки дополнительных модулей.
Зе Фернандо
Оптимизированный трехмерный
ТРЮК
№37 плоттер
Создание компактного и быстрого механизма для рисования простых трех-
мерных объектов на сцене Flash.
Полноценная трехмерная графика возможна лишь при подаче двух разных изоб-
ражений в глаза зрителя. На основании различий в изображениях мозг зрителя
вычисляет пространственную глубину каждого объекта (так называемое стерео-
скопическое зрение). Например, в очках для просмотра стереофильмов исполь-
зуются красные и синие фильтры (или фильтры с вертикальной и горизонталь-
ной поляризацией), при помощи которых на каждый глаз подаются разные
изображения - на киноэкран проецируются два разных изображения со смеще-
нием, а мозг конструирует из них единую картинку. Однако в так называемой
трехмерной компьютерной графике вместо вывода разных изображений трех-
мерный объект проецируется на плоскость. Если закрыть один глаз, рисунок не
изменится, просто мозг зрителя делает разумные предположения относительно
глубины элементов изображения на основании масштаба и положения теней.
Создать простейший механизм трехмерного вывода не так сложно, как может
показаться. В этом трюке приведена математическая база для написания просто-
го трехмерного плоттера, преобразующего координаты точки в трехмерном про-
странстве (х, у, z) в двухмерные координаты (х, у) на плоскости сцены Flash.
Как и большинство графических программ, Flash использует систему коорди-
нат, показанную на рис. 5.7: ось Y направлена сверху вниз (а не снизу вверх, как
в декартовой системе координат). Ось X идет в обычном направлении, то есть
слева направо.
Flash поддерживает только двухмерную графику (оси X и У). Чтобы имитировать
ось Z, мы аппроксимируем глубину применением масштабирования. На рис. 5.8
182 Глава 5. Трехмерная графика и физика
частоту смены кадров 24 fps. Свяжите следующий код с кадром 1 главной вре-
менной диаграммы:
function moveSpheresO {
// Функция перемещения сферы
for (var i:Number = 0: i < n: i++) {
pX[i] += pXS[i];
i f (Math.abs(pX[i]) > wSize) {
pXS[i] = -pXS[i]:
}
pY[i] +« pYS[i];
i f (Math.abs(pY[i]) > wSize) {
pYS[i] = -pYS[i];
}
pZ[i] += pZS[i] * scale;
i f (Math.abs(pZ[i]) > wSize) {
pSZ[i] = -pZSCi];
}
threeDPlotter(i);
}
function threeDPlotter(i) {
scale = flength/(flength + p Z [ i ] ) ;
world["p"+i]._x = (pX[i] * scale);
world["p"+i]._y = (pY[i] * scale);
world["p"+i]._xscale = world["p"+i]._yscale = 100 * scale;
}
// ОСНОВНОЙ КОД
var fLength:Number = 150;
var wSize:Number = 100;
var centerX:Number = 275:
var centerY:Number = 200;
var n:Number = 30;
var pX:Array = new ArrayO;
var pX:Array = new ArrayO;
var pY:Array = new ArrayO;
var pZ:Array = new ArrayO;
var pXS:Array = new ArrayO;
var pYS:Array = new ArrayO;
var pZS:Array = new ArrayO;
// Построение модели трехмерного мира
thi s.createEmptyMovi eCli p("worl d". 0);
world._x = centerX;
world._y = centerY;
// Инициализация сфер
for (var i:Number = 0; i < n; i++) {
world.createEmptyMovieClipC'p" + i. i ) ;
world["p"+i].lineStyle(10. 0x0. 100):
world["p"+i].moveTo(0, 0):
184 Глава 5. Трехмерная графика и физика
world["p"+i].lineTo(l. 0):
pX[i] = pY[i] = pZ[i] = 0;
pXS[i] - Math.randomO * 5;
pYS[i] = Math.randomO * 5;
pZS[i] = Math.randomO * 5:
threeDPlotter(i):
}
// Настройка обработчика события onEnterFrame
this.onEnterFrame = moveSpheres;
При выполнении этого кода в трехмерном мире перемещаются 30 сфер (рис. 5.9).
Вскоре вы поймете, почему сферы рисуются в виде простых черных кругов, без
эффектных бликов.
• • • < • • •
• 4
• • • « • •
• •
p o s i t i o n ( p X , pY, p Z )
Итоги
Несмотря на свою тривиальность, представленный механизм способен стать на-
чальной точкой для построения более совершенных механизмов трехмерной гра-
фики:
• соединяя точки отрезками, можно строить трехмерные векторные модели
(см. трюк 85);
• введение буфера глубины (z-буфера) повысит реалистичность представления
трехмерного мира. В частности, это позволит использовать сферы с бликами
вместо простых черных кругов.
Построение трехмерных изображений в реальном времени интенсивно расходу-
ет ресурсы процессора. Как было показано в текущем разделе, упрощение этой
задачи позволяет быстро создать эффект с минимальными затратами ресурсов.
Такие силы, как сила притяжения, создают постоянное ускорение. Иначе гово-
ря, скорость объекта изменяется во времени с постоянным приращением. Ско-
рость объекта в конце интервала равна сумме его начальной скорости и произве-
дения значения ускорения на продолжительность интервала:
newV = oldV + (ускорение * время)
Позиция объекта в конце интервала равна сумме начальной позиции и скорости,
умноженной на продолжительность интервала:
newPos = oldPos + (newV * время)
Если позиция и скорость вычисляются настолько часто, что скорость при каж-
дой итерации может считаться постоянной, а продолжительность интервала при-
нимается за 1, то уравнение позиции упрощается до следующего вида:
newPos = oldPos + newV
Проще говоря, это означает: «Чтобы вычислить новую позицию, следует взять
старую позицию и прибавить к ней текущую скорость». Например, если машина
едет со скоростью 60 км/ч, то за один час она сместится на 60 км от исходной
позиции. Таким образом, в каждом кадре анимации мы смещаем позицию на
небольшую величину в направлении вектора скорости.
В конце интервала вычисляется новое значение скорости, учитывающее ускоре-
ние. Уравнение скорости по знакомому принципу упрощается до вида
newV = oldV + ускорение
Переведем: «Чтобы вычислить текущую скорость, следует взять исходную ско-
рость и прибавить к ней значение ускорения». Например, если машина едет со
скоростью 60 км/ч, и за одну секунду ее скорость увеличивается на 10 км/час, то
через одну секунду ее скорость составит 70 км/ч. В каждом кадре анимации к
скорости прибавляется величина приращения в направлении вектора ускорения
(для силы притяжения этот вектор обычно направлен вниз).
Ускорение, обусловленное силой притяжения Земли, составляет примерно
9,8 м/с 2 . Впрочем, если вы не пытаетесь моделировать конкретные физические
условия, для ускорения можно использовать любую постоянную величину.
Сила трения покоя (сила трения, действующая на неподвижное тело) должна
быть больше силы трения качения (которая действует, скажем, на катящийся
мяч). Сила трения воздуха обычно возрастает пропорционально скорости объекта,
поэтому мы воспользуемся простым коэффициентом трения, считая итоговое
воздействие пропорциональным текущей скорости.
Следующая программа генерирует несколько частиц (см. трюк 33) и анимйру-
ет их, заставляя двигаться под воздействием силы притяжения и трения возду-
ха:
function f a l l ( ) {
// Прибавление ускорения, обусловленного гравитацией
this.speedY +- GRAVITY:
// Учет воздействия силы трения
this.speedY *= FRICTION:
188 Глава 5, Трехмерная графика и физика
function dragO {
// Когда пользователь щелкает на клипе, активизировать режим
// перетаскивания и прекратить его анимацию
// на базе события onEnterFrame.
this.startDragO ;
delete this.onEnterFrane:
// Чтобы сэкономить на вызове функции, можно воспользоваться
// вызовом следующего вида:
// this.onMouseMove = updateAfterEvent:
// поскольку обработчик onMouseMoveO вызывает только одну функцию.
// Тем не менее, мы используем следующее определение функции
// на случай, если потребуется реализовать дополнительные возможности
// (скажем, проверку границ, предотвращающую перетаскивание клипа
// за пределы сцены).
this.onMouseMove = functionO {
updateAfterEventO:
}
function dropO {
// Инициализация анимации и выход из режима перетаскивания клипа.
// Исходная скорость по оси Y равна нулю,
this.speed.у = 0:
this.stopDragt):
this.onEnterFrame = fall;
// ОСНОВНОЙ КОД
// Создание 20 клипов со сферами
for (var i = 0: i < 20; i++) {
var ball:MovieClip = this.createEmptyMovieClipC'ball" + i. i ) :
ball.lineStyle(6. 0x0. 100):
ball .moveTo(0. -3):
ball .UneToCl. -3):
ball._x = Math.randomO * 550;
ball._y = Math.randomO * 200:
ball.speedY = 0:
ball.onEnterFrame = fall;
ball.onPress = drag;
ball.onRelease = ball.onReleaseOutside = drop;
}
// Инициализация физических констант
var GRAVITY:Number = 0.5;
var FRICTION:Number = 0.995;
Гравитация и трение 189
Итоги
Поскольку анимация выполняется на уровне кадров, уравнения движения в ней
выглядят проще, чем те уравнения, которые мы изучали на уроках физики. Дви-
жение на уровне кадров всегда описывается линейными уравнениями, благода-
ря чему сценарии становятся короткими и эффективными. Попробуйте реализо-
вать движение не только по оси У, но и по оси X (подсказка: гравитация по оси X
не действует, поэтому шару необходимо придать начальную горизонтальную
скорость).
В анимацию можно внести всевозможные дополнения: попробуйте изменить
коэффициент гравитации (и даже сделать его отрицательным, чтобы объекты не
притягивались, а отталкивались). Если задать нулевой уровень гравитации, кар-
тина приобретет такой вид, словно камера находится над бильярдным столом.
Разместите на сцене бегунки для управления гравитацией, силой трения и элас-
тичностью - и экспериментируйте! При желании добавьте звуки или реализуй-
те деформацию шара при ударе.
190 Глава 5. Трехмерная графика и физика
ТРЮК
Имитация броска
№39 Чтобы сделать интерфейс более реальным, попробуйте реализовать эф-
фект броска: объект перетаскивается мышью, а при отпускании кнопки
продолжает двигаться в прежнем направлении.
Как было показано ранее, воздействие ускорения (см. трюк 38) и силы трения,
включая сопротивление воздуха, гораздо проще имитировать на уровне отдель-
ных кадров, а не посредством реализации физических уравнений.
В этом трюке представлен простой способ имитации бросания объектов.
В момент броска определяется воображаемый вектор силы. Направление векто-
ра определяет начальное направление перемещения объекта, а его длина про-
порциональна силе броска (и, соответственно, определяет дальность полета бро-
шенного объекта).
В Flash сила броска неизвестна, так как в этом виртуальном мире не существует
понятий силы и массы, поэтому мы имитируем движение другим способом, кото-
рый выглядит довольно реалистично. Как это обычно бывает при имитации фи-
зических процессов в Flash, модель должна быть близка к идеалу лишь до той
степени, до которой ее эффект выглядит реалистично. На практике сгенерирован-
ное движение не является абсолютно точным, но, по крайней мере, близко к нему.
На рис. 5.12 изображен шар в момент броска. Пользователь молсет щелкнуть
на шаре и протащить его по сцене (шар двигается в направлении, в котором
двигался указатель мыши в момент отпускания кнопки).
Цикл анимации начинается с события onPress (строка 15) при нажатии кнопки
мыши на клипе ball; обработчик события активизирует режим перетаскивания.
Точка отпускания обнаруживается либо обработчиком события onRelease (цикл
«нажатие кнопки мыши - перетаскивание - отпускание»), либо обработчиком
события onReleaseOutside, если указатель мыши вышел за пределы сцены (в этом
случае вы просто «роняете» шар, не бросая его). Обработчики событий onRelease
и onReleaseOutside начинаются в строке 31, они создают интервальный таймер,
который вызывает функцию moverQ для управления анимацией шара после
броска.
Функция mover() использует переменные dirX и dirY для управления перемеще-
нием шара. С течением времени вертикальная составляющая вектора наращивает-
ся константой GRAVITY, а составляющие dirX и dirY уменьшаются с коэффициентом
FRICTION. Инертная масса шара косвенно моделируется константой MOMENTUM.
Чем больше значение MOMENTUM, тем больше амплитуда вектора силы.
Интервал сбрасывается (строка 17) в функции onPress (начало - строка 15) при
повторном щелчке на шаре. В этот момент цикл броска начинается заново.
1 // Код ActionScnpt 2.0
2 function drawPip(clip:MovieClip. clipName:String, clipDepth:Number.
3 x:Number, у:Number):MovieClip {
4 var pip:MovieClip = clip.createEmptyMovieClip(clipName, clipDepth);
5 pip.lineStyle(20. 0x0. 100);
6 pip.moveTo(0, 0);
7 pip.lineToCl. 0);
8 pip-_x = x:
9 pip._y = y:
10 return pip;
11 }
12 function throwClip(clip:MovieClip):Void {
13 clip.oldX = clip._x;
14 clip.oldY = clip._y;
15 clip.onPress = functionO {
16 clip.startDrag(true. -265. 190. 265. -200);
17 clearlnterval(clipMove):
18 clip.onMouseMove = functionO {
19 clip.dirX = MOMENTUM * (clip._x - clip.oldX);
20 clip.dirY = MOMENTUM * (clip._y - clip.oldY):
21 clip.oldX = clip._x;
22 clip.oldY = clip._y:
23 // ** Диагностика **
24 // clip.line = clip.createEmptyMovieClipC'line". 0):
25 // clip.line.lineStyle(4. 0x0. 100);
26 // clip.line.lineTo(5 * clip.dirX. 5 * clip.dirY);
27 /7 ** Диагностика **
28 updateAfterEventO;
29 };
30 };
31 clip.onRelease = clip.onReleaseOutside = functionO {
32 clip.stopDragO;
33 delete clip.onMouseMove;
192 Глава 5. Трехмерная графика и физика
Итоги
Программистам, работающим в стиле Flash MX, стоит обратить внимание на то, что
в обработчиках событий никогда не используется текущий объект this. Вместо этого
имя целевого клипа передается в аргументах функций. Такое решение работает го-
раздо эффективнее - чтобы убедиться в этом, попробуйте заменить clip на this в са-
мом часто выполняемом коде события (обработчик onMouseMove, строки 18-30).
Flash Player 7 оптимизирован для быстрой обработки данных, передаваемых в ар-
гументах (см. трюк 100); данный стиль кодирования является предпочтитель-
ным для кода ActionScript 2.O. Оптимизация основана на том факте, что Flash
Player сохраняет данные в нескольких аппаратных регистрах (вместо обраще-
ния к переменным в памяти).
Если заменить ссылки на клипы, передаваемые в аргументах, псевдопеременной
this, Flash Player не применяет регистровую оптимизацию, поэтому программа
работает медленнее.
Обнаружение множественных столкновений 193
Обнаружение множественных
ТРЮК
№40 столкновений
Обнаружение столкновений используется в играх и имитациях. Попробу-
ем усовершенствовать стандартный механизм обнаружения коллизий
Flash для нетривиальной анимации.
Flash позволяет обнаруживать столкновения между двумя клипами методом
MovieClip.hitTest(). Метод возвращает true, если столкновение было обнаружено,
или false при отсутствии столкновений.
Само понятие «столкновение» тоже понимается по-разному. Столкновением
можно считать контакт точки с краем клипа, а также ограничивающими прямо-
угольниками двух клипов (то есть прямоугольниками, окружающими клипы при
их выделении в среде разработки). Обе ситуации будут рассмотрены далее.
Предположим, на сцене находятся два клипа: clipA и clipB. Следующий код акти-
визирует режим перетаскивания клипа clipA и выводит значение true для каждо-
го кадра, в котором ограничивающие прямоугольники clipA и clipB перекрывают-
ся. В противном случае выводится значение false.
clipA.onEnterFrame = function О {
hit = clipA.hitTest(clipB):
trace(hit):
}:
cl ipA.startDrag(true);
Данный способ обнаружения столкновений имеет один серьезный недостаток:
столкновения обнаруживаются при соприкосновении ограничивающих прямоу-
гольников даже в том случае, если пикселы внутри клипов не перекрываются.
На рис. 5.13 две круговые области клипов не имеют общих точек, но метод hitTest()
из предыдущего листинга возвращает true, потому что ограничивающие прямоу-
гольники перекрываются.
Иерархия столкновений
На практике обычно требуется обнаружить столкновения между одним объек-
том и группой других объектов, будь то молекулы газа в физической имитации,
орда космических агрессоров или стены лабиринта. Допустим, мы хотим выя-
вить столкновения с одним графическим объектом, представляющим игрока
(игрового персонажа, находящегося под управлением пользователя).
В медленном способе проверки столкновений каждый клип рассматривается как
отдельная сущность. Таким образом, если в видеоигре на экране находится од-
новременно 20 инопланетных кораблей, придется проверять столкновения меж-
ду кораблем игрока и каждым инопланетянином по отдельности.
Вместо этого правильнее объединить всех инопланетян в один клип (например,
alienSwarm). Полученная иерархия изображена на рис. 5.14.
JeveS-sSenSwarm.afersJ
Создайте второй клип с именем asteroid (рис. 5.16), присвойте ему идентифика-
тор компоновки asteroid. Положение точки регистрации в этом клипе несуще-
ственно.
196 Глава 5. Трехмерная графика и физика
Разместите клип ship в нижней части сцены, где обычно находится корабль иг-
рока в классической игре «Space Invaders».
}
// Инициализация
left = Key.LEFT:
Обнаружение множественных столкновений 197
right = Key.RIGHT:
playerSpeed = 10;
asteroidSpeed = 3;
shiplnterval = setlnterval(shipMove. 10):
createAsteroidsO:
Функция createAsteroidsO создает клип с именем asteroidBelt, содержащий 20 вло-
женных клипов с именами asteroidO- asteroid 19. Астероиды постепенно переме-
щаются по экрану.
Клип ship перемещается клавишами <— и ->. Цель игрока - уклониться от столк-
новения с астероидами.
Анимация корабля управляется событием setlnterval() и получает гораздо боль-
шую долю ресурсов Flash Player (см. трюк 71). Астероиды управляются обра-
ботчиками onEnterFrame, поэтому их анимация выполняется на более низкой
частоте (частоте смены кадров).
Если корабль игрока сталкивается с одним или несколькими астероидами, на
панели Output выводится слово «collision»'для каждого кадра, в котором такое
столкновение произошло. Ключевой фактор, обеспечивающий высокое быстро-
действие, - единая проверка столкновений для всего пояса астероидов:
i f (asteroidBelt.hitTest(ship._x. ship._y. true)) {
trace("collision"):
Выполнение функции означает, что как минимум одно столкновение уже про-
изошло и код можно оптимизировать с учетом этого обстоятельства.
Итоги
Поиск столкновений не должен создавать проблем для имитаций, требующих вы-
сокого быстродействия. Объединение графических объектов в иерархию позволит
существенно сократить время, необходимое для обнаружения столкновений.
В типичной игре-«стрелялке» должно присутствовать несколько функций обна-
ружения столкновений; две выполняются часто, а одна - редко. В нашем сцена-
рии первые две функции проверяют столкновения между кораблем игрока и фло-
том захватчиков, а также между лазером игрока и флотом захватчиков. Если
вторая проверка дает положительный результат, выполняется более редкая (но
более детализированная) проверка столкновений между лазером и каждым вра-
жеским кораблем внутри флота.
Разворот к точке
Представьте, что корабль должен развернуться к цели перед выстрелом (пред-
полагается, что орулше всегда стреляет в текущем направлении). Следующий
код рисует отрезок прямой и разворачивает его в направлении текущей позиции
указателя мыши:
// Создание анимационного клипа tracker
var tracker:MovieClip = this.createEmptyMovieClipC'tracker". 0):
// Рисование линии в клипе tracker
tracker.lineStyle(0. 0x0. 100):
tracker.moveTo(0. 0):
tracker.lineTodOO. 0):
tracker, x = Stage.width / 2:
200 Глава 5. Трехмерная графика и физика
tracker._y = Stage.height / 2:
// Определение множителя для преобразования радианов в градусы
// var RAD_DE6:Number = 180/Math.PI:
tracker.onMouseMove = functionО {
// Поворот клипа в направлении указателя мыши
var angle:Number = Math.atan2(_ymouse - this._y. _xmouse - t h i s . _ x ) :
t h i s . _ r o t a t i o n = angle * RAD_DEG;
updateAfterEventO:
}:
Метод Math.atan2(), использованный в этом фрагменте, возвращает угол, на ко-
торый нужно повернуть линию, чтобы она была обращена к точке, заданной
координатами X и Y (обратите внимание: в первом параметре передается рассто-
яние У, а не X). Геометрическая интерпретация представлена на рис. 5.17.
target
s t a r t position
Рис. 5.17
Инерция
Допустим, мы хотим имитировать эффект инерции, чтобы клип двигался к точ-
ке назначения по дуге. Для этого следует добавить перемещение в том направле-
нии, куда клип направлен в каждый момент времени. Опробуйте следующее
решение:
function drawBlip(clip) {
// Рисование линии в клипе
clip.lineStyleCO. 0x0. 100);
clip.moveTo(0. 0):
clip.lineTodO. 0):
clip._x = Math.randomO * Stage.width:
clip._y = Math.randomO * Stage.height:
}
function real MoveО {
// Вычисление расстояния между текущей позицией клипа
// и целевой позицией (указателем мыши).
this.xDist = _xmouse-this._x;
this.yDist = _ymouse-this._y;
// Вычисление угла между текущей и целевой позициями клипа.
// а также разности между желаемым направлением
// и текущим углом (errorAngle).
var targetAngle:Number = Math.atan2(this.yDist. this.xDist):
var errorAngle:Number = targetAngle * RAD_DEG - this._rotation:
// Вычисление угла .поворота по значению errorAngle.
if (Math.abs(errorAngle) > 10) {
if ( ((errorAngle > 0) && (errorAngle < 180))
j | (errorAngle < -180) ) {
this._rotation += 10:
} else {
this.rotation -= 10:
Итоги
Существует немало приемов имитации реального движения. Разворот к целевой
точке и имитация инерции в направлении движения закладывают основу для
создания анимаций с реалистичным движением.
ГЛАВА 6
Текст
Трюки № 42-51
Средства работы с текстом в Flash не ограничиваются выводом статических
сообщений, единственный смысл которых - оставаться на своем месте и быть
прочитанными пользователем. Flash позволяет интерпретировать текст как на-
бор векторных фигур или серию анимационных клипов; оба варианта обладают
тем преимуществом, что они позволяют анимировать текст. Достаточно взгля-
нуть на титры некоторых фильмов, чтобы понять, насколько выразительным
может быть анимированный текст и до какой степени движение может спо-
собствовать передаче смысловой нагрузки. Более того, появляющиеся и исчеза-
ющие текстовые сообщения иногда используются для создания подтекста (по
аналогии с тем, как жестикуляция создает подтекст для произносимых слов).
Далее перечислены некоторые сайты Flash, демонстрирующие возможности ра-
боты с текстом:
• Typorganism (http://www.typorganism.com) - сайт демонстрирует так называе-
мое кинетическое оформление, то есть эффекты анимации текста, вносящие
дополнительный смысл посредством движения.
• Overage4Design (http://www.overage4design.com) - современный дизайн, в ко-
тором текст интерпретируется как графический объект, а не как нечто предназ-
наченное для простого чтения.
• Mono-craft (http://www.yugop.com) Юго Ыакамуры (Yugo Nakamura) - один
из первых сайтов с новаторскими и интерактивными возможностями работы
с текстом. Mono-craft версии 2.0 считался одним из законодателей моды «зо-
лотого века» Flash 4 и 5, когда первая волна Flash-дизайнеров на базе совре-
менной методики ActionScript создавала концепции, которые в наше время
считаются стандартными.
• Saul Bass on the Web (http://www.saulbass.net) - сайт поддерживается хорошо
известным Flash-дизайнером Бренданом Доусом (Brendan Dawes). Он отдает
дань уважения Солу Бассу (1920-1966) - одному из первых людей, исполь-
зовавших текст как динамическую графику в фильме. Басе также применял
текст для графического оформления плакатов к фильмам, как это делали его
предшественники-модернисты из Советской России в 1920-х годах.
204 Глава 6. Текст
Шрифты
Flash поддерживает две категории шрифтов: системные и встраиваемые. При
использовании одного из трех стандартных шрифтов («_jsans», «_serif» или
«.typewriter») Flash Player на стадии выполнения подбирает наиболее похожий
шрифт в системе пользователя. Шрифт «_sans» (эквивалент sans-serif в HTML/
CSS) обычно соответствует Arial в системе Windows или Helvetica на Мае. Вме-
сто шрифтов «serif» и «^typewriter» (эквиваленты serif и mono в HTML/CSS)
Flash обычно использует Times или Courier или другие подходящие шрифты.
Контурное описание шрифта может быть сохранено в SWF-файле для выполне-
ния различных текстовых эффектов (см. трюк 48) - скажем, поворота текста.
Встраивать стандартные шрифты в SWF не обязательно, но системные шрифты
не содержат векторной информации, поэтому Flash не может интерпретировать
текст, выведенный с применением системного шрифта, как графический объект.
Из-за этого текст, оформленный системным шрифтом, обычно исчезает со сце-
ны при повороте или масштабировании клипа. При встраивании стандартных
шрифтов («_sans», «_serif» или «_typewriter») Flash использует ближайший
шрифт, обнаруженный в системе на стадии компиляции. На стадии выполнения
такой текст успешно поворачивается, масштабируется и анимируется, посколь-
ку Flash использует встроенное описание шрифта, а не системный шрифт, нахо-
дящийся на компьютере пользователя.
Трюки, представленные в этой главе, помогут сделать текст более разборчивым,
реализовать текстовые поля с автоматическим заполнением, импортировать текст
со сложным форматированием, использовать CSS, а также применять такие спе-
цифические возможности, как всплывающие подсказки. В других главах ветре-
Сохранение разборчивости текста 205
12 my_txt.border = true;
13 my_txt.text r myStr:
14 my_txt.setTextFormat(txtFmt):
Строки 1 и 2 создают экземпляр TextFormat с именем txtFmt, используемый для
отображения текста myStr. В строке 4 выбирается шрифт «_sans» - один из трех
стандартных шрифтов, поддерживаемых Flash.
Затем в строке 7 метод TextFormat.getTextExtent() создает элемент Object с именем
metrics. Метод возвращает объект с двумя свойствами, textFieldWidth и textFieldHeight,
определяющими ширину и высоту текстового поля, необходимого для отображе-
ния сообщения myStr с разрывом текста после 200 пикселов.
Вторая часть приведенного кода динамически строит текстовое поле my_txt с глу-
биной 1 и позицией (100, 100); ширина и высота поля определяются значениями
упоминавшихся ранее двух свойств metrics.
Последние четыре строки просто задают свойства текстового поля после его
создания. В частности, они заносят в него наш текст myStr и применяют к полю
объект TextFormat с именем txtFmt, определяющий шрифт и его кегль.
Особенно важна строка 6:
txtFmt.size = 12:
Если присвоить txtFmt.size любое другое значение (и применить его вызовом
setTextFormatO), текст будет отображаться другого кегля, а высота текстового
поля автоматически подгоняется под высоту текста, как показано на рис. 6.1,
для значений txtFmt.size, равных 8, 12 и 16 соответственно.
Вероятно, вы уже уловили, к чему я клоню: если задавать свойство size в зависи-
мости от разрешения экрана пользователя, проблему удобочитаемости текста
можно считать решенной. Попробуйте заменить строку 6 следующим фрагмен-
том:
i f (System.capabi1iti es.screenResol uti onX 800) {
txtFmt.size = 12:
} else {
txtFmt.size = 10:
Автоматическое завершение текста 207
Итоги
Необходимость поддержки разных размеров экранов (для мобильных телефо-
нов, карманных компьютеров и других нестандартных устройств) становится
все более насущной, поэтому требования к удобочитаемости текста выходят на
первый план. Тривиальное решение проблемы - создать разные версии для всех
основных категорий устройств, но таких категорий немало (причем даже уст-
ройства одной категории могут различаться). Лучше реализовать возможность
динамического управления текстовыми метриками.
Также существует возможность динамического изменения размеров сцены Flash
и/или находящихся на ней текстовых экземпляров в соответствии с разрешени-
ем экрана (и размером окна браузера). Зная соотношение между размером сцены
Flash и общими размерами экрана, вы получаете дополнительные возможности
для динамического масштабирования содержания Flash. Реализация динамичес-
кого изменения текстовых метрик и размеров сцены (см. трюк 92) позволит вам
в значительной степени контролировать адаптацию SWF к разным условиям
времени выполнения.
Другое полезное применение кода, приведенного в настоящем трюке, - созда-
ние всплывающих подсказок. Код для оперативного создания легко перемещае-
мого и масштабируемого текста легко адаптируется для создания текста справ-
ки (см. трюк 47), который всегда масштабируется и позиционируется возле
указателя мыши, но внутри сцены.
Иногда при изменении размеров текста бывает желательно сменить шрифт. На-
пример, чтобы текст хорошо читался при малых размерах, следует использовать
пиксельные шрифты (см. трюк 67).
called с*ие can chance children city ccae oeoi could cstuitry d&y d»Y» SiS oiCferenc doea dcr.'t dour, during
Мой усеченный список слов занимает всего лишь 1,5 Кбайт, причем его можно
усечь до 990 байт (большая выгода!) копированием выходных данных предыду-
щего сценария в листинг ActionScript. Как вы вскоре убедитесь, полная версия
выглядит не так компактно:
var myText:String = "about above across ... years you young your";
var dictionary:Array = new ArrayO;
dictionary = myText.splitC " ) ;
dictionary. sortO;
delete (myText);
При публикации SWF Flash сжимает текст определения словаря.
На сайте http://www.the-stickman.com я обнаружил весьма изобретательный трюк
для реализации автоматического завершения.
В нем используются два текстовых поля, одно над другим. Верхнее поле пред-
назначено для ввода данных, а нижнее, динамическое поле содержит рекоменда-
ции для автоматического завершения. Допустим, у вас уже имеется слой с име-
нем actions, с первым кадром которого связан предыдущий фрагмент кода.
Добавьте два новых слоя с именами entered text и completed text (см. рис. 6.3).
« 3 D
illllQ
;
entered text * • 5
Ij? complete text:: . . •• i
Рис. 6.З. Создание слоев для реализации автоматического завершения текста
На слое entered text создайте многострочное текстовое поле без бордюра и при-
свойте ему имя myText_txt (см. рис. 6.4).
ты s.ens
А !V| ! M ;|vl И|;
iiifcl;^
:
ж rayText_txt * | Normal
309 0 х:
67. 3 ш |Ми1Шпе v| ;
| <> D Var:
И: 170.8 у;
.|
1183
Рис. 6.4. Настройка параметров текстового поля для слоя entered text
;:
:•• i Dynamic Text v ' .A _sans vl 14 V
A b £ ;|
completejxt
jj 309.0 Ш67.0 |!;1А|,::|Ми1Шпе v ; A0 <Ь П Van
:
Hti 1*3.3 Щ 118.3
Программа
Введите в сценарии, связанном со слоем actions, следующий фрагмент, содержа-
щий как программный код, так и предварительно инициализированный словарь:
function autoCompleteO {
// Функция подтверждает текущий предложенный вариант
// автоматического завершения при нажатой клавише CONTROL,
if(Key.isDown(Key.CONTROL)){
myText_txt.text = complete_txt.text + " ";
Selecti on.setSelecti on(myText_txt.text. 1 ength,
myText_txt.text.length):
function fieldChangeO {
// Функция для поиска и отоображения варианта
// автоматического завершения строки,
match = "":
// Получение последнего незавершенного слова в текстовом поле
startOfWord = this.text.lastlndexOf(" ") + 1:
lastWord = this. text. substring(startOfWord, this.text .'length);
// Поиск в словаре кандидатов для последнего незавершенного слова,
if(lastWord.length > 1){
for (var i = 0; i < dictionary.length; i++) {
if (lastWord == (dictionary[i].substr(0. lastWord.length))){
// Если совпадение обнаружено, сохранить в переменной match.
match = dicti onary[i];
search = i;
break;
} else {
search = 0;
Автоматическое завершение текста 211
// Инициализация
var myText:String = "about above across after again against air all almost
along also always and animals another answer any are around asked away
back because been before began being below best better between big both
boy boys but bye called came can change children city come cool could
country day days did different does don't down during each earth email end
enough even ever every example eyes far father feet few find f i r s t five
following food for form found four from get give going good goodbye got
great had hand hard has have head hear heard hello help her here high him
himself his home house how however html important into i t ' s its just keep
kind knew know land large last learn left let l i f e light like line l i t t l e .•
live long look looked made make man many may means men might miles more
most mother much must name near need never new next night no not now
number off often old once one only other others our out over own page
paper part parts people picture place play point put read right room said
same saw say school sea second see sentence set several she should show
side since small some something sometimes soon sound s t i l l story study
such sun sure take t e l l than that the their them then there these they
thing things think this those thought three through time times today
together told too took top toward try turned two under until use used
using usually very want was water way ways web website well went were what
when where which while white who whole why will with without word words
work work world would write year years you young your";
Не s| Не за|н Не said
Итоги
В этом разделе приведен базовый код, необходимый для реализации автомати-
ческого завершения. Скорее всего, вы захотите его изменить - например, чтобы
автоматическое завершение подтверждалось другой клавишей (скажем, пробелом).
Но в этом случае придется приложить дополнительные усилия. Хотя нажатие
пробела можно обнаружить простым поиском « » в конце текущего содержимо-
го поля, нужно убедиться в том, что последней нажатой клавишей была не кла-
виша Backspace. Другой потенциальный недостаток заключается в том, что при
нажатии пробела для перехода к другому слову механизм автоматического за-
вершения может добавить нежелательный текст. Например, если ввести слово
«table» и нажать пробел, это слово может неожиданно замениться словом «tablecloth».
Впрочем, это маловероятно, потому что часто встречающиеся слова из списка
обычно имеют небольшую длину.
Другое обстоятельство, способное вызвать раздражение у некоторых пользова-
телей, - добавление пробела в конец каждого автоматически завершаемого сло-
ва. Впрочем, это все мелочи - даже если изменить подробности реализации,
основной принцип остается прежним.
Базовый словарь из часто встречающихся слов также может стать отправной
точкой при построении более полезного списка. Когда речь заходит о «включе-
нии словаря», может показаться, что это приведет к заметному увеличению объема
SWF-файла, однако 300 самых распространенных слов занимают менее 1 Кбайт.
Расширение списка до 3000 слов (что приближается к количеству слов, исполь-
зуемых в нормальной речи, если не считать имена собственные и служебные
частицы) потребует не более 10-15 Кбайт! Получается не так уж много, и это
обстоятельство позволит нам создать словарный запас для синтезатора речи
(см. трюк 52), чтобы он мог читать простой текст. Синтезатор выводит неопоз-
нанные слова, которые вы можете добавлять в словарь (см. трюк 44) по своему
усмотрению.
214 Глава 6. Текст
Программа
Следующий код решает задачу поиска новых слов и их включения в список
(предполагается, что код из трюка 43 также присутствует, а обработчик события
onRelease вызывает функцию entered()).
1 function entered О {
2 var newWords:Array = new ArrayO;
3 newWords = myText_txt.text.split(" " ) ;
4 for (var i = 0; i<newWords.length; i++) {
5 if (myText.indexOf(newWords[i].toString()) == -1) {
6 // Новое слово отсутствует в словаре.
7 // Добавить его и отсортировать словарь заново.
8 myText += " "+newWords[i];
9 dictionary.push(newWords[i]):
10 dictionary.sort О:
11 }
12 }
В строках 2 и 3 функции создается новый массив newWords, содержащий все
слова из текстового поля myText_txt. Если форма содержит несколько текстовых
полей, просто объедините их в одну строку конструкцией следующего вида (вме-
сто строки 3 предыдущего листинга):
newWords = (myTextFieldl_txt.text + " " +
myTextField2_txt.text).split(" ");
В теле цикла for (строки 4-11) программа последовательно ищет в словаре каж-
дое слово в текстовом поле (конечно, можно ограничиться словами, состоящими
из трех и более букв). Если новое слово не найдено, оно включается в словарь,
после чего словарь заново сортируется.
Хотя в этом коде содержимое строки myText используется для быстрого поиска
(см. трюк 79), новые слова сохраняются в массиве dictionary (см. трюк 43). В этом
можно наглядно убедиться: запустите ролик в отладочном режиме (Control •
Debug Movie) и просмотрите содержимое массива root.dictionary при вводе слова
«aardvark». Если щелкнуть на кнопке Submit, вы увидите, что элемент dictionary[0]
теперь содержит слово «aardvark». Нажимайте клавишу Backspace до тех пор,
пока слово «aardvark» не будет полностью стерто, и начните вводить его заново.
После ввода символов «аа» Flash автоматически завершает слово.
}
if (needUpdate) {
saveDictionaryO;
>
function saveDictionaryO {
var shared:SharedObject = SharedObject.getLocal("dictionary")
shared.data.dictionary = myText;
shared. flushO;
}
function loadDictionaryO {
var shared:SharedObject = SharedObject.getLocal("dictionary")
if (shared.data.dictionary != undefined) {
myText = shared.data.dictionary;
}
function enterEventO {
enteredO;
// Прочая обработка кнопки Submit...
}
function autoCompleteO {
if (Key.isDown(Key.CONTROL)) {
myText_txt.text = complete_txt.text+" ";
Sel ect i on.setSelecti on(myText_txt.text.1ength,
myText_txt.text.1ength):
}
function fieldChangeO {
match = "";
startOfWord = this.text.lastlndexOfC ")+l;
lastWord = this.text.substring(startOfWord. this.text.length):
i f (lastWord.length>l) {
for (var i = 0: idictionary.length: i++) {
i f (lastWord == (dictionary[i].substr(0. lastWord.length)))
// Совпадение обнаружено
match = dictionary[i]:
Динамическое построение списка вводимых слов 217
search = i ;
break;
}
} else {
search = 0:
}
complete_txt.text - this.text.subs-tr(0. startOfWord)+match;
}
// Инициализация
// Полный список слов не приводится
var myText:String = "about above... you young your";
var dictionary:Array = new ArrayO;
var search:Number = 0:
var lastWord:String = "";
var startOfWord:String = "":
var control:Object = new ObjectO:
// Загрузка хранимого словаря
loadDictionaryO;
// Построение словаря
dictionary - myText.spiit(" ");
dictionary. sortO;
// Настройка событий и слушателей
myText_txt.onChanged = fieldChange:
control.onKeyDown = autoComplete;
Key.addLi stener(control):
enter_btn.onRelease = enterEvent;
В третьей строке обновленной функции enteredO определяется логическая пере-
менная needUpdate; при обнаружении новых слов, которые должны быть добав-
лены в словарь, ей присваивается значение true. Если в словарь были добавлены
новые слова, в последней строке enteredO вызывается функция saveDictionary().
Она сохраняет текст текущего полного словаря в локальном хранилище LSO
(Local Shared Object). LSO всего лишь является удобным средством для хране-
ния данных между сеансами, по аналогии с браузерными cookie. Данные будут
загружены в тот момент, когда это потребуется.
При попытке сохранения LSO, размер которого превышает максимально допус-
тимое значение в системе пользователя, Flash Player запрашивает у пользовате-
ля разрешение на сохранение дополнительных данных, отображая вкладку Local
Storage диалогового окна Settings. По умолчанию объем локального хранилища
данных составляет 100 Кбайт на домен.
Если вы собираетесь организовать локальное хранение данных, сообщите об этом
пользователю. Если диалоговое окно появится неожиданно для пользователя,
это может сильно встревожить его - особенно если заполняемая форма пред-
назначена для оформления заказа на какой-нибудь товар!
Сохраненный словарь загружается функцией loadDictionaryO. Функция сначала
ищет в LSO ранее сохраненный словарь и, если он существует, использует но-
вый текст для замены стандартного словаря myText.
Чтобы убедиться в том, что новые слова сохраняются между сеансами, запусти-
те ролик в режиме тестирования, введите в текстовом поле слово «aardvark»,
218 '_ Глава 6. Текст
закройте SWF-файл и запустите его заново. На этот раз слово «aardvark» авто-
матически завершается после второй буквы.
Итоги
В последнем листинге поиск в словаре производится в двух случаях:
• когда пользователь вводит слова в текстовом поле, происходит подбор вари-
анта для автоматического завершения (алфавитный поиск в массиве dictionary);
• когда мы хотим узнать, присутствуют ли в словаре вновь введенные слова,
поиск выполняется по строке myText.
Таким образом, мы имеем две версии списка слов: одна обеспечивает структур-
ный алфавитный поиск, а другая позволяет узнать, присутствует ли введенное
слово в текущем словаре. Обе версии оптимизированы по скорости.
Возможно, вы также обратили внимание на одно допущение: наша программа
предполагает, что все слова встречаются с одинаковой частотой, а вернее - что
частота их появления соответствует алфавитному порядку. Это не всегда так.
Например, слово «said» встречается чаще, чем «sad», но при алфавитном упоря-
дочении словаря «sad» будет предлагаться раньше, чем «said». Одно из возмож-
ных решений - упорядочить список по частоте использования (либо на основа-
нии данных, полученных в результате статистического анализа, либо простым
подсчетом использования отдельных слов в текущем контексте). Но такое реше-
ние замедлит поиск, если список не будет упорядочиваться (по крайней мере
частично) по алфавиту. При небольших списках слов поиск всегда выполняется
относительно быстро. Но если списки имеют большой размер, выбор решения
зависит от того, насколько алфавитная сортировка снижает скорость.
Область применения методики сохранения часто используемых слов не ограни-
чивается автоматическим завершением текста. Она также может использоваться
для накопления статистики - скажем, отслеживания самых популярных отве-
тов в опросах или предложения возможных условий поиска в тех случаях, когда
поиск по заданному критерию не дает результатов. Конечно, эти нетривиальные
варианты применяются в основном при сохранении данных на рабочем сервере.
Трюк обеспечивает локальное хранение данных, а это означает, что набор часто
используемых слов зависит от пользователя. При помощи Flash Remoting или
других технологий можно загружать данные на сервер и накапливать статисти-
ку по нескольким пользователям.
№45 в Flash
Воспроизведение в Flash сложных текстовых/графических макетов —
таких, как математические формулы. Microsoft Word используется как
буфер для промежуточного хранения данных.
Flash получает все большее распространение и все чаще используется в целях,
отличных от «чистого» дизайна веб-сайтов. На обучающих сайтах часто возни-
Перенос сложного форматирования в Flash 219
1
Micros 4
Features to install:
ш Office Shared Features
*ш
Office Tools
• ' * - - •
H T M L S o u r c e E d i t i n g
i •щ^|
L a n g u a g e S e t t i n g s T o o l
M i c r o s o f t D r a w C o n v e r t e r
M i c r o s o f t G r a p h
: ^р| -г M i c r o s o f t O f f i c e S n d e r S u p p o r t
M i c r o s o f t O f f i c e D o c u m e n t I m a g i n g
X - M i c r o s o f t O f f i c e S h o r t c u t B a r
Description
Inserts mathematical symbols and equations into
documents.
Space Required on С: 1696 KB
Hep „Cancel,:
Рис. 6.7
E q u a t i o n
В Word сложный текст может выглядеть как таблица, но если скопировать его
и вставить в Flash, все получается нормально, как показано на рис. 6.12.
На рис. 6.13 показано, как выглядит группа, созданная Flash в результате опера-
ции вставки. Только подумайте, сколько времени потребовалось бы для ручного
создания такой формулы в Flash!
Рис. 6.13. Сложная формула, представленная в виде группы текстовых элементов Flash
ПРИМЕЧАНИЕ
Копирование/вставка — удобный способ создания форм Flash на базе суще-
ствующих форм HTML/JavaScript.
На рис. 6.14 выделяется основной шаблон сайта O'Reilly с боковым меню. Выде-
ленный HTML-код копируется в буфер.
Перенос сложного форматирования в Flash 223
Вставьте данные в формате HTML в Word, как показано на рис. 6.15, скопируй-
те их из Word в буфер обмена, затем вставьте в Flash
^ final Showing P
Итоги
Хотя для публикации технической информации в Веб можно использовать про-
стые электронные документы PDF или отформатированные данные HTML, тех-
нология Flash обладает рядом преимуществ (например, она позволяет приме-
нять анимацию при выводе диаграмм). Многие физические концепции трудно
объяснить на статических моделях, и тогда SWF-ролики Flash с анимацией, по-
ясняющей описанный материал, окажут огромную помощь.
Если вы еще не уверены в необходимости использования математических фор-
мул в Flash, ознакомьтесь с некоторыми анимированными системами, реализо-
ванными на Flash (например, с системой работы с формулами Роберта Пеннера
по адресу http://www.robertpenner.com). Автор объясняет основные принципы
работы с системой при помощи Flash, и это выглядит в высшей степени уместно!
Возможности форматирования текста в Flash весьма ограничены (хотя поддержка
CSS в Flash MX 2004 отчасти решает эту проблему). Microsoft Word обладает
гораздо лучшими средствами работы с текстом, поэтому текст удобнее отформа-
тировать в Word и перенести в Flash через буфер обмена.
Если элементы Flash потребуется вставить в существующую структуру HTML,
попробуйте импортировать весь макет (вместе с текстом и растровой графикой)
Использование HTML и CSS в Flash 225
п
по цепочке H T M L • Word • Flash. Таким способом даже многие интерфейсные эле-
менты JavaScript (например, поля) импортируются в виде растровой графики!
ПРИМЕЧАНИЕ
Flash MX 2004 стал первой версией продукта с проверкой орфографии. Если вы
используете более раннюю версию, проверьте правописание текста в Word и ско-
пируйте его в Flash.
T h i s is a link
a:active {
font-family: Verdana. Arial. Helvetica, sans-serif;
font-size: lOpx;
font-weight: bold:
. text-decoration: underline;
col or:#444444:
a:hover {
font-family: Verdana. Arial. Helvetica, sans-serif;
font-size: lOpx;
font-weight: bold:
text-decoration: underline;
COlor:#C08080;
}
Стоит обратить внимание на ряд обстоятельств:
• Flash не поддерживает теги заголовков HTML (<h1>, <h2> и т. д.), однако
это ограничение можно обойти посредством определения собственных клас-
сов CSS - таких, как класс .title в нашем примере.
• Flash не различает единицы определения размеров шрифта рх (пикселы)
и pt (пункты). Следовательно, неважно, какая из этих единиц будет исполь-
зоваться в таблице стилей.
• Поддержка CSS в Flash позволяет определять ссылки HTML. Текст, пред-
ставляющий ссылку, находится в одном из состояний link, visited, active или
hover, атрибуты которых определяются в таблице.
Использование HTML и CSS в Flash 229
ПРИМЕЧАНИЕ
Если HTML-код имеет относительно небольшой объем, определите его внутри
SWF. Однако графику в HTML-коде обычно лучше загружать на стадии выполне-
ния при помощи тега <img>, о котором речь пойдет далее.
Внедренная графика
Один из самых замечательных аспектов поддержки HTML в Flash MX 2004 -
возможность применения атрибута src тега <img> для внедрения графики J P E G
в текстовое поле. Например, в следующем фрагменте изображение задается в од-
ном из тегов <р> (изменения выделены жирным шрифтом):
myHTML = "<р class = 'titie'>Creating an e f f i c i e n t walk cycle</p>"
myHTML+= "<br><p><img src = 'walk.jpg' align = ' r i g h t 1 > " +
"<span class = 'emphasis'>Scribble</span> moves very " +
"quickly in the f i n a l work, far too quickly for the viewer to see " +
"the lack of frames. He also spends a l o t of time in the a i r . thus " +
"minimizing the slide walk effect.</p>"
myHTML+= "<p>You can see an example of him moving <a href = 'someURL'>here</
a>.<br><br><br><br>"
myHTML+= "<p>Of course, when two designers get together, easy options " +
"always go out of the window...(etc)</p>."
Результат, полученный при выполнении этого кода, показан на рис. 6.19.
Изображение загружается во время обработки HTML-кода на стадии выполне-
ния. Сначала на странице появляется текст. После того как изображение будет
230 Глава 6. Текст
; when two designers gz he?., easy options always, go out Dt the wind aw,,, (etc)
Рис. 6.19. Загрузка внедренного изображения на стадии выполнения
Итоги
Flash MX 2004 предоставляет широкие возможности управления текстом за счет
поддержки функциональных подмножеств стандартных спецификаций HTML
и CSS. Чтобы объем Flash Player оставался небольшим, фирма Macromedia отка-
залась от полной реализации спецификаций; кроме того, поддержка CSS в Flash
отличается от поддержки CSS в браузере. Подмножество поддерживаемых тегов
и определений CSS прошло тщательный отбор. Некоторые теги (например, теги
заголовков) не поддерживаются, но вместо них можно легко определить соб-
ственные классы или стили CSS.
Всплывающие подсказки 231
Всплывающие подсказки
Вспомогательный текст обычно используется специализированными про-
граммами для пользователей с дефектами зрения. Впрочем, его также
можно использовать для выдачи справочной информации тем, кто видит
нормально.
При проектировании Flash MX была учтена и такая серьезная проблема веб-
дизайна, как проблема доступности контента Flash наравне со всем прочим веб-
контентом. В частности, появилась панель Accessibility для ввода текстовых строк,
используемых специальными программами для слабовидящих. В Flash MX 2004
компоненты v2 были дополнены новыми возможностями, включая улучшенную
поддержку управления фокусом.
Конечно, даже пользователи с нормальным зрением иногда нуждаются в помо-
щи, поэтому вспомогательный текст может пригодиться и им, хотя и в несколь-
ко иной форме. В этом трюке вспомогательный текст используется для реализа-
ции всплывающих подсказок.
* Accessibility
j 0 Make Object Accessble '
# В Г ] Make child objects a xessible •'.'. \
• С
- Name:! Button A
Щ
. Shortcut: : A ''11
Tab index:: -:
ш"!шштА
Если экспортировать клип для Flash Player версии 6г65 и выше, вы увидите, что
у выделенного объекта появилось свойство accProps (рис. 6.21).
; JevdO.buttonA
3 accProps
I true
гмитев
shortcut
Button В
Control+B
Взяв за основу код создания сочетаний клавиш (см. трюк 96), мы включим в не-
го три новые функции:
• определение событий, управляющих выводом справочного текста. Для этой
цели будут использоваться события onRollOver и onRollOut;
• размещение подсказок на сцене;
Всплывающие подсказки 233
Программа
Следующий код получает вспомогательный текст и использует его для построе-
ния всплывающей подсказки. Предполагается, что на сцене размещены три кнопки
с именами buttonA, buttonB и buttonC. Если щелкнуть на кнопке или нажать опре-
деленную комбинацию Клавиш, выполняются соответствующие обработчики
событий. За кнопками закреплены следующие комбинации клавиш:
• ButtonA - A;
• ButtonB - Control+B;
• ButtonC - Control+D.
Обратите внимание: в поле Shortcut слово «Control» должно вводиться полностью,
хотя в книге эта клавиша обычно обозначается сокращением «Ctrl». Кроме того,
для каждой кнопки должны быть определены свойства, содержащие вспомогатель-
ную информацию. Откройте панель Accessibility (Window • Other Panels • Acces-
sibility) и введите для каждой кнопки имя и комбинацию клавиш, как показано
на рис. 6.24. В нашем примере заполняются поля Name и Shortcut, но вы можете
самостоятельно изменить программу, чтобы в подсказке отображалось содержи-
мое поля Description.
• - • . • • • • • •
тлссе* sibrfrty
0 Make 01sjectAccesable
;::Owske:d-|fd objects;.3ccesSbie и;' ';•,•}
г\
Name: | Button A
Description: i
С ; Shortcut: j A
Tab: infer:
removeHelpTextO ;
function createHelpText(target) {
// Создание клипа с текстом подсказки.
var helpClip:MovieClip = attachMovieC'helpText". "helpText".
t h i s.getNextHi ghestDepth());
clearlnterval(helplnterval):
// Задание атрибутов текста подсказки.
var helpText:TextField = helpClip.helpText;
helpText.background = true;
helpText.backgrounded or = OxFFFFCC;
// Форматирование текста подсказки.
var helpFormat:TextFormat = new TextFormatO;
helpFormat.leftMargin = 2;
helpFormat.rightMargin = 2;
helpFormat.indent = 0:
helpFormat.size = 15;
helpFormat.font = "_sans";
//
// Если у целевого клипа задано вспомогательное свойство name.
// оно отображается в подсказке.
if (target._accProps.name != undefined) {
helpText.text = target._accProps.name;
}
if (target._accProps.shortcut !•= undefined) {
// Если у целевого клипа задано вспомогательное свойство
// shortcut, оно включается в подсказку.
helpText.text += "\n"+target._accProps.shortcut;
}
// Задание размеров подсказки.
var fieldSize;Object = helpFormat.getTextExtent(helpText.text)
helpText._height = fieldSize.textFieldHeight;
helpText._width = fieldSize.textFieldWidth;
helpClip._x = _xmouse-helpClip._width/2:
helpClip._y = _ymouse-helpClip._height-10;
} • •
function removeHelpTextO {
helpText.removeMovi eCli p ( ) :
}
function aHandlerO {
// Обработчик события кнопки А
traceC'You clicked A");
}
function bHandlerO {
// Обработчик события кнопки В
traceC'You clicked В");
}
function cHandlerO {
// Обработчик события кнопки С
traceC'You clicked С"):
236 Глава 6. Текст
function down() {
// Функция обнаруживает комбинацию клавиш
// и выполняет соответствующий сценарий,
var all Keys;
// Проверить, нажаты ли все клавиши в комбинации,
for (var j - 0: j<keys.length; j++) {
all Keys = true;
for (var i = 0; i<keys[j].combo.length; i++) {
allKeys = al1 Keys && Key.isDown(keys[j].combo[i]);
}
if (allKeys) {
// Если все клавиши комбинации нажаты, передать фокус
// кнопке и выполнить ее обработчик события. Дальнейшие
// события блокируются до момента отпускания нажатых клавиш.
Selecti on.setFocus(keys[j]):
this.onKeyDown = undefined:
this.onKeyUp = up:
keys[j].btn.onRelease();
break;
}
function upO {
// Функция выполняется при отпускании комбинации клавиш.
this.onKeyUp = undefined:
this.onKeyDown = down:
Button 8
Control+B
Итоги
С реализацией этого трюка и определением клавиатурных сокращений для кно-
пок (см. трюк 96) ваш сайт не только станет более доступным для пользователей,
использующих специализированные программы для слабовидящих, но и предо-
ставит ту же справочную информацию пользователям с нормальным зрением.
Перемещение служебной информации во всплывающие подсказки экономит место
на экране, при этом информация остается доступной в любой момент. Общий
дизайн сайта становится более компактным и эстетичным.
Создание текста
Хотя пустые текстовые поля можно создавать динамически методом MovieClip.create
TextField(), прежде чем анимировать текстовое поле, его необходимо создать в пу-
стом анимационном клипе (поскольку класс TextField не поддерживает события
onEnterFrame для покадрового обновления). Кроме того, необходимо просле-
дить за тем, чтобы шрифт, используемый текстовым полем, был правильно вне-
дрен в итоговый SWF-ролик. Самый простой и безопасный способ - создать
текстовое поле внутри клипа и вручную внедрить шрифт на стадии разработки.
Далее остается лишь воспользоваться ActionScript для размещения символа,
созданного вручную, на сцене во время выполнения.
Создайте на сцене динамическое текстовое поле при помощи инструмента Text.
Введите в нем текст «mm», чтобы быть уверенными в том, что поле вместит
один произвольный символ выбранного шрифта. Выберите на панели свойств
тип текста Dynamic Text (рис. 6.26), выберите простой шрифт без засечек (напри-
мер, Arial или Helvetica) размером 24 пункта. Наконец, задайте текстовому полю
имя экземпляра field.
Dynamc
i Text j^J Jill Arial
"field' ШШФ \ %:•' f Ш;1
imrn
\ Single Line ° .U EH
v; <0
ПРИМЕЧАНИЕ
Выбор простого шрифта без засечек предотвращает использование сложных
шрифтов с большим количеством векторных элементов. Тем самым гарантиру-
ется быстрая анимация итогового эффекта и незначительный объем лишних
данных, обусловленных внедрением шрифта. Не используйте системные шрифты
(такие, как _sans), потому что текстовые эффекты работают только при внедре-
нии шрифта.
Внедрение шрифта
Чтобы внедрить шрифт в SWF, не снимайте выделения с текстового поля и щелк-
ните на кнопке Character в правой части панели свойств (если кнопка Character
не отображается, значит, вы забыли выбрать тип текста Dynamic Text). В открыв-
шемся диалоговом окне Character Options (рис. 6.27) установите переключатель
Select Ranges и выделите первые 4 строки списка, щелкая на них с нажатой
клавишей Shift.
Текстовые эффекты 239
! !
}
var format:TextFormat = new TextFormatO;
format.font = "Arial":
format.size = 24;
placeText(this, 100. 100. "This is a text effect", format);
Функция placeText() создает надпись, текст которой задается аргументом banner,
в позиции (х, у) временной диаграммы timeline. Межсимвольные интервалы
определяются объектом tFormat класса TextFormat. Если вместо Arial использует-
ся другой шрифт или размер шрифта отличен от 24, внесите соответствующие
изменения в две строки, выделенные жирным шрифтом. Чтобы использовать
шрифт другого размера, измените размеры текстового поля - выделите его ин-
струментом Text и перетащите ограничивающий прямоугольник до нужных
размеров.
При использовании значений, заданных в последней строке листинга, текст
выводится с правильными межсимвольными интервалами, как показано на
рис. 6.29.
T h i s is a t e x t e f f e c t
Рис. 6.29. Выходные данные генератора с пропорциональными интервалами
ТЫ s j s a text effect
• Рис. 6.30. Текст, выведенный без пропорциональных интервалов
Итоги
В настоящее время существует целый ряд генераторов текстовых эффектов, раз-
работанных независимыми фирмами, но базовый код текстового эффекта все-
гда остается одним и тем же. Стоит разобраться в основополагающих принци-
пах, и вы сможете легко создавать собственные эффекты. Возможности написания
текстовых переходов ограничены только вашим воображением.
Хотя некоторые знаменитые текстовые эффекты (см. трюк 31) можно реализо-
вать разными способами, универсальная основа, приведенная в этом трюке, по-
может вам генерировать собственные текстовые эффекты (см. трюк 50). Если
вам нужен исходный творческий импульс, посмотрите на начальные титры в та-
ких фильмах, как «Звездные войны», «Семь» или любой фильм Хичкока.
Программа
Приведенный далее код написан на базе заготовки для построения текстовых
эффектов (см. трюк 48). Изменения выделены жирным шрифтом. Предполага-
ется, что динамическое текстовое поле letter находится в клипе с именем экзем-
пляра field, а в библиотеке существует звуковой клип typeClick.
242 Глава 6. Текст
}
var keyHit = new Sound(this);
keyHit. attachSoundf typeCl i ck");
var format:TextFormat = new TextFormatO;
format.font = "Aria!":
format.size = 24;
placeTexttthis. 100, 100. "This is a text effect.", format);
В конце функции placeTextQ задается задержка timer от 200 до 300 мс на каждый
знак. Указанный интервал должен пройти перед выводом текста (и воспроизве-
дением соответствующего звука) функцией typewriter(). Тем самым имитируется
задержка между нажатиями клавиш в процессе ввода текста.
Любой текстовый эффект строится по тому же принципу:
• определяется задержка на вывод одного знака и изменяются одного или не-
сколько свойств каждой буквы;
• в конце задержки измененному свойству присваивается окончательное зна-
чение, завершающее эффект;
• происходит переход к следующей букве.
Для создания эффекта пишущей машинки свойству visible задается значение
false, в результате чего все буквы изначально невидимы. При истечении задерж-
ки код typewriter) делает текст снова видимым. На рис. 6.31 показан эффект
пишущей машинки в действии. Программа с небольшой задержкой открывает
каждую букву в последовательности.
Текстовые эффекты, контролируемые по времени 243
This is a
This is a text ef
Итоги
Эффект пишущей машинки наглядно показывает, что многие эффекты строятся
по одному образцу. Кроме того, в программе продемонстрированы важные ас-
пекты любых текстовых эффектов - задержка, выбор шрифта и звуковое сопро-
вождение. Без звука и задержки между выводом букв эффект будет выглядеть
отнюдь не так убедительно. Кстати говоря, моноширинный шрифт сделает ил-
люзию еще более полной.
Реализация многих текстовых эффектов требует тщательного подбора времен-
ных интервалов, звуков и шрифтов. Например, скрип мела по доске в сочетании
с подходящим шрифтом может использоваться для создания «рукописного»
эффекта (каждая буква может представлять собой анимированный клип, рисую-
щий букву несколькими штрихами).
№50 по времени
Создание различных эффектов за счет изменения размеров и позиции
букв с течением времени.
Ранее было показано, как на основе заготовки для создания текстовых эффектов
(см. трюк 48) создается эффект пишущей машинки (см. трюк 49). В этом трюке
рассматриваются еще три текстовых эффекта, построенных на базе того же уни-
версального кода.
Программа
Следующий листинг показывает, как реализовать плавный эффект «выраста-
ния» букв посредством постепенного изменения их свойств в обработчике
onEnterFrame. Функция placeText() тоже была модифицирована по сравнению
с предыдущим трюком (см. трюк 49): в новом варианте ей передается имя
выполняемой функции и величина задержки, что упрощает ее повторное ис-
пользование для- других эффектов. Предполагается, что динамическое текстовое
поле letter находится в клипе с именем экземпляра field. Итоговая версия нахо-
дится в файле standup.fla на сайте книги. Важные фрагменты выделены жирным
шрифтом,
function standUpCtarget :Movi eCl ip. del ay: Number)-.Void {
target.interval = functionO {
clearInterval(target.interval ID);
this.onEnterFrame = functionO {
target._yscale += 10;
if (target._yscale > 95) {
delete this.onEnterFrame;
}
target.interval ID = setlnterval(target, "interval", delay);
target._yscale = 0;
}
function placeText(target:MovieClip, x:Number, y:Number.
banner:String. tFormat:TextFormat.
effectFunction:Function, del ay:Number):Void {
II Для каждого знака...
for (var i = 0: i<banner.length; i++) {
// Создать клип и поместить текущий символ в текстовое поле,
var chanMovi eCl ip = target.attachMovieC'letter", "char"+i.
target.getNextHighestDepthО);
char.field.text = banner.substr(i. 1);
char._x = x;
char._y = y;
// Прибавить ширину текущего знака к позиции х следующего знака.
х += tFormat.getTextExtent(char.field.text).width;
//
// Вызов функции эффекта, передаваемой в виде параметра.
effectFunction(char, i*delay);
This is
T h i s is a text e f f _
T h i s is a text effect
Рис. 6.32. Эффект поднимающихся букв в действии
Эффект падения
Изменяя другие свойства (и/или сразу несколько свойств одновременно), мож-
но создавать переходы, визуально отличающиеся друг от друга, но работающие
на сходном коде. Чтобы создать эффект падения, мы постепенно изменяем свой-
ство _у - создается впечатление, что буквы падают на свое место в последова-
тельности. Также в начале падения каждой буквы свойство visible задается рав-
ным true, чтобы буква была видна на экране.
Чтобы падение выглядело более естественно, выделенная жирным шрифтом стро-
ка создает иллюзию инерции. Функция placeTextQ в листинге не приводится -
она не изменилась по сравнению с предыдущим примером. Как и прежде, пред-
полагается, что динамическое текстовое поле letter находится в клипе с именем
экземпляра field. Итоговая версия находится в файле drop.fla на сайте книги.
// Код ActionScript 2.0
function dropCtarget :MovieCl i p . del ay: Number)-.Void {
target.interval = functionO {
target._vi sible = true:
clearInterval(target.interval ID);
target.onEnterFrame = functionO {
target._y -= (target._y-target.startY)/3:
i f (Math.abs(target._y-target.startY)<l) {
target._y = target.startY:
delete target.onEnterFrame:
}
target.interval ID = setlnterval(target, "interval", delay):
target.startY = target._y:
target._y = 0;
target._visible = false:
}
var format:TextFormat = new TextFormatO;
format.font = "Arial":
format.size = 24;
placeText(this. 100. 100. "This is a text effect", format, drop. 100);
На рис. 6.33 показан эффект падения в действии. Буквы поочередно появляются
с небольшой задержкой, а затем «падают» на положенное место.
24G Глава 6. Текст
X
e
T h i s is a t
T h i s is a t e x t
T h i s is a t e x t e f f e c t
Проявление с масштабированием
Вероятно, наибольшую известность из всех текстовых эффектов получил эф-
фект постепенного проявления с масштабированием. Он прославились благода-
ря сайту theVoid (http://www.thevoid.co.uk).
Этот эффект основан на постепенном изменении свойств _xscale, _yscale и _alpha,
но программная реализация остается практически такой же, как прежде. При из-
менении всех свойств имитируется эффект инерции (соответствующий фрагмент
листинга выделен жирным шрифтом). Функция placeTextO в листинге не приводит-
ся - она не изменилась по сравнению с предыдущим примером. Как и прежде,
предполагается, что динамическое текстовое поле letter находится в клипе с име-
нем экземпляра field. Итоговая версия находится в файле fadein.fla на сайте книги.
function fadeZoom(target:MovieClip. del ay:Number):Void {
target .interval = functionO {
target._visible = true;
clearlnterval(target.interval ID);
target.onEnterFrame = functionO {
target._xscale -= (target._xscale-100)/3;
target._yscale -= (target._yscale-100)/3;
target._alpha -= (target._alpha-100)/3:
i f (Math.abs(target._xscale-100)<l) {
target._xscale = 100;
target._yscale = 100;
target.alpha = 100:
delete target.onEnterFrame:
}
target.interval ID = setlnterval(target, "interval", delay);
target._xscale = 2000:
target._yscale = 2000;
target.„alpha = 0;
Текстовые эффекты, контролируемые по времени 247
Thisj
This is a text
T h i s is a t e x t e f f e c t
m m
Итоги
После того как мы написали универсальную заготовку для построения тексто-
вых эффектов, в дальнейшем разнообразные текстовые эффекты строятся по
принципу изменения свойств во времени. Либо придумайте свой эффект и реа-
лизуйте его, либо выберите свойство (или комбинацию свойств), попробуйте
изменить его и посмотрите, что из этого выйдет.
В интерактивном генераторе текстовых эффектов пользователю нужно предоста-
вить возможность ввода текста и изменения параметров - таких, как амплитуда
248 Глава 6. Текст
№81 морфинга
Некоторые текстовые эффекты реализуются только с применением мор-
финга. Для создания эффектов такого рода применяется редко исполь-
зуемый, но очень полезный инструмент Envelope.
Ранее уже рассматривались способы создания сценарных текстовых эффектов
(см. трюк 50). Тем не менее, текстовые эффекты ActionScript ограничиваются
созданием анимации за счет изменения свойств клипа со временем. Данная раз-
новидность анимации позволяет изменять позицию, прозрачность, цвет, ориен-
тацию и масштаб текста, но ActionScript не способен создавать сложные анима-
ции с изменением геометрической формы текста. Чтобы решить эту задачу,
необходимо преобразовать текст в низкоуровневые векторные фигуры и рабо-
тать с ними, как с графическими примитивами.
Перспектива выполнения низкоуровневых операций с множеством фигур вы-
глядит устрашающе, но в этой ситуации нам пригодится очень полезный инст-
румент Envelope. Большинство дизайнеров забывает о нем, однако этот инстру-
мент позволяет быстро применять эффекты к набору букв способом, который не
удастся легко реализовать на сценарном уровне.
Разбиение текста
Прежде чем приступать к редактированию текста в виде векторных фигур, его
необходимо преобразовать в векторную форму - в Flash этот процесс называет-
ся разбиением (breaking apart). Создайте текст при помощи инструмента Text, a
затем, не снимая выделения с текста, дважды выполните команду Modify • Break
Apart. Первая команда Break Apart разбивает текстовое поле на несколько тексто-
вых полей (по одному на каждую букву), а вторая разбивает буквы на вектор-
ные контуры.
ПРИМЕЧАНИЕ
После того как текстовое поле будет преобразовано в серию векторных конту-
ров, отредактировать текст напрямую уже не удастся. Проверьте правописание
перед тем, как осуществлять разбиение!
Инструмент Envelope
Выделите все буквы в тексте инструментом Selection, активизируйте инстру-
мент Free Transform. В области параметров этого инструмента (в нижней части
панели Tools) выберите значок Envelope. Примерный вид текста показан на
Текстовые эффекты с применением морфинга 249
Рис. 6.37. Затемнение фона помогает различить два типа маркеров на огибающей
точек, форма текста автоматически подгоняется под форму огибающей, как по-
казано на рис. 6.39.
:!
10 1; 23 •-••:•
'.:
;
]J S • IS 13 2S
Г ЪШШ Ш$
Итоги
Некоторые анимации не удается легко создать.средствами ActionScript - в та-
ких случаях лучше всего прибегнуть к редактированию текста в векторной фор-
ме. Если править форму каждой буквы по отдельности, задача окажется весьма
трудоемкой. Мощный (хотя и не прощающий ошибок пользователя) инстру-
мент Envelope позволяет работать с несколькими буквами, как с единым целым.
В этом трюке показано, как организовать постепенное изменение формы текста.
Если вам потребуется создать более сложный морфинг, попробуйте отредакти-
ровать текст во внешнем векторном редакторе (таком, как Freehand или Illustrator
или даже в одной из последних версий Photoshop) и импортировать графику
в Flash командой File • Import.
Г Л А В А
Работа со звуком
Трюки № 52-60
На собственном опыте знаю, что многие веб-дизайнеры разделяют распростра-
ненное заблуждение по поводу звука. Это заблуждение можно сформулировать
примерно так:«Я не профессиональный художник, но это не мешает мне рисо-
вать картинки и строить симпатичные веб-сайты. Я не музыкант, и это мешает
мне создавать звуки и музыку для моих сайтов».
Такой подход годится для дизайнера HTML-сайта, которому практически не
приходится работать со звуком, но когда вы имеете дело с анимацией в Веб,
отсутствие звукового сопровождения оборачивается крупным недостатком. Звук
является одним из важнейших аспектов анимации и интерактивности. Попро-
буйте поработать на Flash-сайте с отключенным звуком или поиграть в Quake
на 20% громкости. Получается совсем не то!
Помимо создания собственных звуковых файлов есть и другой путь - приобре-
сти компакт-диск с готовыми звуковыми материалами. Однако содержимое та-
ких дисков обычно делится на две категории: «используется повсеместно и всем
надоело» или «настолько дико, что никто не захочет слушать».
К сожалению, поддержке звука в области веб-дизайна еще не уделяется должно-
го внимания. Все мы знаем, как оптимизировать растровое изображение для Веб
без создания лишних неровностей контуров или нежелательной зернистости/
цветового шума, но оптимизация звука редко выходит за пределы назначения
частоты оцифровки МРЗ при экспортировании с целью уменьшения размеров
файла. Однако в технологии оптимизации звука тоже присутствуют свои «не-
ровности» и «шумовые эффекты» (шум оцифровки). Вы должны знать о них,
чтобы добиться оптимального соотношения «размер файла/качество».
ПРИМЕЧАНИЕ
Звуковые данные загружают канал связи интенсивнее, чем остальные со-
ставляющие ролика (за исключением разве что видеоданных), поэтому очень
важно, чтобы звук был как можно лучше оптимизирован в любом веб-содер-
жании;
Проблема лазера
В основу многих трюков заложено нестандартное применение стандартных при-
емов и технологий. История науки полна примеров неожиданного применения
технологий - например, лазеров. Мало кто мог предположить, что лазеры будут
использоваться во всех областях, от военного дела до хирургии, от прослушива-
ния музыки и просмотра фильмов до ведения международных телефонных пе-
реговоров.
Давайте посмотрим, как использовать тривиальное на первый взгляд событие
onSoundComplete для построения синтезатора речи в Flash.
Событие Sound.onSoundComplete
Как только в Flash MX появился метод Sound.onSoundComplete(), я сразу же
подумал: «Здорово! Теперь звуки можно легко и точно синхронизировать, и я
смогу создать виртуальный микшерный пульт». И это действительно так - точ-
ность события onSoundComplete на порядок превышает частоту смены кадров,
поэтому оно гораздо точнее решения с ключевыми кадрами и onEnterFrame, при-
менявшегося в Flash 5.
События onSoundComplete, как и любые другие события, могут задерживаться
из-за большого количества параллельных вычислений, особенно анимации,
3) установите флажок Export for ActionScript. При этом флажок Export in First Frame
автоматически устанавливается и становится доступным. Оставьте его уста-
новленным.
В процессе компиляции SWF Flash проводит поиск по всем временным диаграм-
мам и проверяет порядок присоединения всех символов. На основании получен-
ных результатов упорядочивается содержимое SWF-файла. Далее при пересыл-
ке SWF через Веб символы загружаются в Flash Player в порядке использования.
Создание синтезатора речи 255
*?ЩШШШ
Mame
Sound Export: a £
Sound
Ш
Sound
Export: aa
Sound
Export: aer
•J; ay Export: ar
Sound Export; b
Sound Export: bb
Sound Export: с
Sound Export: ch
4$ ck Sound Export: dc
}
function say(phrase) {
var i = j=0:
aPhones = new ArrayO:
aPhones[0] = "":
for (i=0; i<phrase.length; i++) {
i f (phrase.charAt(i) != "|") {
aPhones[j] += phrase.charAt(i)
i f (phrase.charAt(i) == " ") {
aPhones[j] = "space";
}
} else {
a Phones[++j] = "";
speech.attachSound(aPhones[0]);
speech. startO;
speech.onSoundComplete = makePhrase:
soundCount = 0;
soundMax = j - 1 :
}
function soundlnitO {
speech = new Sound(this):
}
soundlnitO;
say("h|e|ll|oo| | | | | |h|ow| |ar| |y|ouu| | | | |tt|u|d|ay|");
stopO;
К сожалению, имена некоторых аллофонов слишком похожи, что затрудняет их
выделение из строки. Например, сочетание «ооо» можно записать в виде «о о о»,
«о оо», «оо о», и все варианты будут звучать по-разному. В программе аллофоны
258 Глава 7. Работа со звуком
Итоги
Синтезатор речи на базе Flash выглядит особенно впечатляюще, потому что весь
механизм синтеза реализован в SWF-ролике - никакие внешние модули им не
Говорящий аватар 259
Завершив работу над синтезатором речи (см. трюк 52), я показал его Адаму
Филипсу. Через несколько дней Адам нарисовал подходящего персонажа-робо-
та по имени Чарли (рис. 7.3).
Сначала мы создаем массив строк, по одной для каждой формы рта. Каждая
строка содержит все аллофоны, связанные с данной формой. Аллофоны допол-
няются пробелами с обеих сторон, чтобы «аег» молено было отличить от «г».
var shapes = new АггауО;
// Определение массива форм рта с соответствующими аллофонами.
shapesCO] = " space ";
shapes[l] = " b bb m p ";
shapes[2] = " a aer ay ее er err i ii ";
shapes[3] = " aa ";
shapes[4] = " г ";
shapes[5] = " о ";
shapes[6] = ' or ow oy ":
shapes[7] = ' 00 ou ouu w wh ";
shapes[8] = ' ck d dd dth g gg h hh n ng nn s t tt z zh ";
shapes[9] = ' с e ear k у уу ";
shapes[10] = " f u uh ";
shapes[ll] = 11 Ch sh j ";
shapes[12] = 1 1 11 ";
shapes[13] = th ";
Функция mouthAnim() ищет строку аллофона (например, «th») в массиве shapes.
Затем по номеру найденного элемента происходит переход к кадру клипа mouth,
содержащего наиболее подходящую форму рта. Первая форма находится в кад-
ре 10, вторая - в кадре 20 и т. д. Чтобы лучше понять, как работает алгоритм,
снимите комментарии с команды трассировки (выделенной жирным шрифтом)
при запуске FLA.
262 Глава 7. Работа со звуком
function mouthAnim(phone) {
for (var i = 0; i<shapes.length; i++) {
i f (shapes[i].indexOf(" "+phone+" ") != -1) {
// trace(phone + " found in "+ shapes[i]);
mouth.gotoAndStop((i+l)*10);
break;
}
function say(phrase) {
var i = j = 0;
aPhones = new ArrayO;
for (i = 0 ; i < phrase.length; i++) {
i f (phrase.charAt(i) != "|") {
aPhones[j] += phrase.charAt(i);
i f (phrase.charAt(i) == " ") {
aPhones[j] = "space":
}
} else {
speech.attachSound(aPhones[0]);
mouthAnum(aPhones[0]);
speech.startO;
speech.onSoundComplete = makePhrase:
soundCount = 0;
soundMax = j-1;
}
function mouthAnim(phone) {
for (var i = 0 ; i<shapes.length; i++) {
if (shapes[i].indexOf(" "+pnone+" ") !- -1) {
// trace(phone + " found in "+ shapes[i]);
mouth.gotoAndStop((i+l)*10);
break;
Синхронизация событийных звуков 263
изменить (см. трюк 57) в каком-либо звуковом редакторе (например, Sony Acid,
Adobe Audition или Audacity). Чтобы слияние звуков происходило без пауз и на-
ложений, необходимо как избавиться от ошибки синхронизации, так и сделать
звуки кратными частоте смены кадров.
Если разместить на временной диаграмме два звуковых файла так, чтобы один
файл останавливался непосредственно перед началом другого, можно предполо-
жить, что переход между звуками в Flash будет плавным. Однако в действитель-
ности этого не происходит из-за упомянутой ошибки.
1; S К
io
п
У~1 »
Рис. 7.7. Размещение потокового звука на временной диаграмме
для обеспечения синхронизации
Effect: Custom OK
Cancel
Итоги
Из-за невозможности синхронизации событийных звуков многие дизайнеры счи-
тают, что в Flash со звуком вообще невозможно сделать что-то серьезное (осо-
бенно до выхода Flash MX и появления события Sound.onSoundComplete).
Создание SWF-ролика со потоковым звуком-«катализатором» и его загрузка
функцией loadMovieNum() позволяют легко создать загружаемую звуковую дорож-
ку, которая сочетает преимущества многократного использования событийных зву-
ков с преимуществами потоковых звуков. Если вам потребуются более совершен-
ные средства синхронизации, воспользуйтесь якорными точками (см. трюк 59).
Преобразование монофонического
ТРЮК
Compression::1мРЗ \^}£\Шт
'-Preprocessing; >\:Х:даУа1 $Щтщ::тт •
А.
Sound: ipadl •-
Efect: C.uso
tm
Sync: .Event v Repeat vi 1
44k№Stereo tfiBit L3s236.0kB
Щелкните на кнопке Edit. На экране появляется окно Edit Envelope (рис. 7.11).
Effect: i Custom
•!>!
Два графика формы сигнала в этом окне представляют два звуковых канала,
а линия представляет уровень громкости. Если два канала имеют одинаковую
форму огибающей (по умолчанию), в динамиках будет воспроизводиться исход-
ный монофонический звук. Изменение огибающих создает различия между гром-
костью двух каналов. Подача двух уникальных сигналов на динамики создает
стереофонический эффект.
Звуковая огибающая содержит до восьми контрольных точек (маркеров, кото-
рые можно перетаскивать мышью). Чтобы создать новую контрольную точку,
щелкните на любом участке огибающей, не содержащем контрольной точки.
Чтобы удалить контрольную точку, перетащите ее мышью за пределы панели.
На многих сайтах для управления звуком используется ActionScript. Чтобы
использовать представленную методику для звуков, присоединяемых на стадии вы-
полнения методом MovieClip.attachSoundO, создайте клип с ключевыми кадрами, к ко-
торым присоединены звуки. Для каждого ключевого кадра с ассоциированным
268 Глава 7. Работа со звуком
Код ActionScript для управления звуком должен выглядеть примерно так (пред-
полагается, что клипу со звуками на панели свойств было задано имя экземпля-
ра soundHolder):
mySound = new Sound(soundHolder): // Определение объекта Sound
soundHolder.gotoAndPlayC'soundl"); // Запуск звука
mySound.stopO; // Остановка звука
Применяя огибающие к звуковому файлу, можно превратить один монофони-
ческий звук в разные стереофонические звуки. Вместо того чтобы использовать
несколько звуков с пониженным качеством, можно использовать один качествен-
ный базовый эффект и преобразовать его при помощи огибающих.
clearlnterval(arg.endSound):
}:
mySound = new Sound(this);
mySound. attachSoundC"UlSound");
mySound.startEnd(0.5, 0.7);
Метод Sound.startEndQ позволяет выделять небольшие фрагменты из существу-
ющих звуков, уже включенных в библиотеку, избавляя вас от необходимости
создавать их отдельно.
Возможность выделения подобных фрагментов может использоваться при соз-
дании интерактивных пультов микширования. Кроме того, это хороший способ
имитации режима быстрой перемотки, реализованной в некоторых проигрыва-
телях компакт-дисков, - проигрыватель воспроизводит односекундный образец
для каждых 10 секунд звукового материала, позволяя быстро найти нужную
точку.
Еще один трюк, маскирующий факт использования одних и тех же базовых ма-
териалов, - добавление эффектов реального времени. В следующем фрагменте
эффект реверберации создается воспроизведением двух версий одного звука с не-
большим смещением по времени:
mySound = new Sound(this);
mySoundEcho = new Sound(this);
mySound.attachSoundC"UlSound");
mySoundEcho.attachSoundC'UISound");
mySound.start(0. 1);
mySound.start(0.1. 1);
Если последняя строка имеет вид
mySound.start(0.001. 1);
возникает эффект фазового сдвига.
Повышение громкости до уровня выше 100% создает эффект дисторсии:
mySound = new Sound(this);
mySoundEcho.attachSoundC"UlSound");
mySound.start(0. 1);
mySound.setVolume(200);
Flash позволяет задавать отрицательные уровни громкости. При этом создается
версия исходного сигнала с фазовым сдвигом на 180°, которая может использо-
ваться для создания фазовых эффектов, особенно в сочетании с эффектом ревер-
берации. Тем не менее, восприятие таких эффектов требует хорошего звукового
оборудования и грамотной расстановки динамиков (что на практике встречается
гораздо реже, чем вы думаете).
Как видите, несложные приемы позволяют с максимальной эффективностью ис-
пользовать один-два звуковых файла, входящих в SWF, за счет обработки звука
в реальном времени. Это особенно важно при написании звукового Flash-содержа-
ния для приложений с крайне жесткими ограничениями по объему пересылаемых
данных - особенно для рекламных баннеров, которые часто ограничиваются
объемом 12 Кбайт.
270 Глава 7. Работа со звуком
Устаревшие программы
Устаревшими программами (abandonware) называются программные продукты,
коммерческий жизненный цикл которых уже завершился. На такие продукты
Создание звукового сопровождения для пользовательского интерфейса 271
Растяжение времени
Современные настольные системы способны на серьезную обработку цифрового
звука, но не стоит удивляться, если время обработки большого звукового файла
будет измеряться в минутах, а не в секундах.
Методика растяжения (и сжатия) звуков по времени позволяет изменять про-
должительность звука при сохранении тональности тона или темпа. Этот прием
используется при звукозаписи для модификации сэмплов, чтобы они лучше
соответствовали общей композиции. В нашем трюке используется тот факт, что
музыкальное произведение, воспроизводимое за несколько минут, можно пре-
образовать в звук продолжительностью в доли секунды с сохранением то-
нальности.
Даже простые, бесплатные звуковые редакторы способны творить настоящие
чудеса. Тем не менее, для общего редактирования звука я обычно использую
Adobe Audition (формально - CoolEdit). В настоящее время этот продукт суще-
ствует только на платформе Windows. Фирма Adobe предлагает 30-дневную пол-
ноценную пробную версию. За это время вы успеете создать все звуковые эф-
фекты пользовательского интерфейса, которые вам когда-либо понадобятся. После
этого созданные звуки можно будет использовать много лет.
272 Глава 7. Работа со звуком
tnf-T! r-
m
-----'-цдщ ЩЩ:
«•Us Щ
1 1
Г Щ
•
гШМШМШ; ШШМ Ш1
0:00.000
| к!
Cancel
Итоги
Вероятно, из всего контента Flash звуки используются наименее эффективно.
Коммерческие звуковые библиотеки качественно звучат, но дорого стоят. Нет
полной уверенности в том, что они идеально впишутся в дизайн вашего сайта,
зато велика вероятность их использования на множестве других сайтов. Конеч-
но, вам не хотелось бы идти на подобный риск с графикой, так стоит ли делать
то же самое со звуком?
Выберите фрагмент музыкального произведения, соответствующий общему на-
строению вашего сайта, а затем посредством растяжения/сжатия его фрагмен-
тов создайте уникальные звуки, которые дополнят графику сайта подходящим
звуковым сопровождением.
Если вам не хочется заниматься этим, попробуйте воспользоваться звуковыми
ресурсами устаревших программ. Хотя эти звуки не являются абсолютно обще-
доступными и свободными от авторских прав, такой путь все же гораздо лучше
«выдирания» звуков пользовательского интерфейса из операционной системы!
Максимальный уровень
дискретизации
Adobe Audition
1. Откройте звуковой файл в Adobe Audition.
2. В окне Organizer (Alt+9) перейдите на вкладку Effects.
3. Найдите эффект Off-line Effects • Amplitude • Normalize и дважды щелкни-
те на нем (рис. 7.18). На экране появляется диалоговое окно Normalize
(рис. 7.19).
ffl-Real-T
r,e Effects
В-Off-UP eEffects
| В-Asrpittude
1 ! i. •Amplify
Binaural Auto-Partner
£nve!ope
^ЩЩз! 'ЯР1Р1'
W Normalize to Jo " d B
1 O K 1
- ;• • i
W Normalize L/R Equally
C a n c e l !
Audacity
Выберите эффект Normalize. Проследите за тем, чтобы оба флажка были уста-
новлены, и щелкните на кнопке ОК.
Более опытные читатели также могут добавить усиление басов или сжатие - обе
возможности скрывают шум дискретизации. В Audacity соответствующие коман-
ды выбираются из раскрывающегося меню Effects.
На рис. 7.20 и 7.21 показаны формы сигнала до и после нормализации. Звуковые
данные масштабируются для заполнения всего спектра сигнала. Тем самым обес-
печиваются использование большего количества уровней дискретизации и умень-
шение влияния шума дискретизации.
Оптимизация звука 279
j Cancel j
[ Impart.. I
ТеД
8 3,0
16 5,5
20 6,0
24 6,0
32 8,0
48 10,0
56 10,0
64 12,0
80 16,0
96 16,0
282 Глава 7. Работа со звуком
Щ •• Reai-Time Effects
Й-Off-line Effects
I Й- Amplitude
I Щ- Generate
! ЁЗ niters
•Sdenfifk Filters
4. Создайте кривую в верхней части окна FFT Filter, как показано на рис. 7.24, со
«ступенькой» на частоте, указанной в табл. 7.1 (для 20 Кбит/с пороговая ча-
стота равна 6,0 кГц). При этом вы определяете фильтр нижних частот, отсе-
кающий частоты выше пороговой точки 6,0 кГц (в Audition частоты измеря-
ются в герцах, поэтому точка отсечения устанавливается на частоте 6000 Гц).
5. Щелкните на кнопке ОК, чтобы применить фильтр.
Служебная информация для синхронизации 283
Итоги
Нормализация звука и подавление всех звуковых составляющих выше порого-
вой частоты существенно повышают качество звука, импортируемого во Flash
для последующего экспортирования в SWF. Это позволяет сократить размер
файлов SWF или повысить качество звука без дополнительной нагрузки на ка-
нал связи.
Оптимизация звука является чем-то новым для многих разработчиков Flash,
привыкших просто сжимать звук в Flash и надеяться на лучшее, но она прино-
сит ощутимую пользу на сайтах с интенсивным использованием звука. По край-
ней мере, стоит попробовать - вряд ли кому-нибудь придет в голову обойтись
без оптимизации растровой графики на страницах HTML, а ведь звуковые дан-
ные занимают гораздо больший объем!
Служебная информация
ТРЮК
После того как сигнал будет обработан, под графиком в окне появляются марке-
ры, помеченные буквой «В» и следующие более или менее периодично (рис. 7.26).
Если интервалы между ударами выглядят хаотично, как на рис. 7.27, скорее все-
го, вы выбрали слишком высокий или слишком низкий порог. В этом случае
попробуйте удалить дорожку с маркерами (щелкните на кнопке с крестиком
в начале дорожки) и повторите процесс с другим порогом.
.г":
Повторите эту процедуру для всех маркеров. Полученный массив beatCode бу-
дет выглядеть примерно так: ,
beatCode = [120. 556. 996. 1366. 1835. 2302, 2669. 3124.
3559. 3938. 4414. 4827. 5232, 5661. 6091. 6512];
Массив содержит позиции всех ударов в миллисекундах. В такой форме его со-
держимое может использоваться с функцией setlntervalQ; именно это и делает при-
веденная ранее программа - она выполняет функцию beatHandlerQ в точках, опре-
деленных массивом beatCode. Чтобы реально использовать события setlntervalQ,
включите в функцию pulse() код для выполнения каких-нибудь полезных опера-
ций - например, управления танцующей фигурой или изменения параметров
узора. Функция даже может использоваться для синхронного запуска другого
звука.
В таких музыкальных проигрывателях, как WinAmp и iTunes, предусмотрена
возможность создания визуальных эффектов для сопровождения текущей до-
рожки. Как правило, эффекты представляют собой узоры, вращающиеся и пуль-
сирующие в такт музыке. Работа эффектов основана на идентификации удар-
ных звуков - точно так же, как мы сделали в Audacity. Выполнить описанным
способом хронометраж ударных для длинной песни будет довольно сложно, од-
нако он позволяет сохранять информацию о позициях ударов в коротких сэмплах,
традиционно используемых в веб-дизайне Flash в качестве фонового сопровож-
дения. Кроме того, на основании позиций ударов можно отображать столбчатую
диаграмму, пульсирующую в ритме музыки. На многих сайтах такие диаграммы
обозначают включение/выключение музыкального сопровождения, но диаграм-
ма остается неподвижной - а с этим кодом она придет в движение!
Массив beatCode можно заполнять данными любых контрольных точек, синхро-
низируемых с любыми событиями звуковой дорожки, будь то крещендо, удар по
тарелкам и т. д. Другими словами, массив beatCode в сочетании с приведенным
кодом имитирует то, что в Director называется якорными точками. В вашем
распоряжении появляется механизм для инициирования событий в определен-
ные моменты при воспроизведении звука.
Элементы пользовательского
интерфейса
Трюки № 61-64
Изначально Flash создавался как инструмент для создания анимации в услови-
ях каналов связи с низкой пропускной способностью, но с тех пор фирма
Macromedia добавила много возможностей для построения графического пользо-
вательского интерфейса (GUI).
В последние годы Macromedia усиленно продвигает Flash как платформу для
разработки RIA (Rich Internet Application). С этой целью в сценарный язык
Flash, ActionScript, были внесены изменения, упрощающие написание кода вза-
имодействия с пользователем, неформально называемого «клеем GUI» - того,
что объединяет элементы интерфейса и управляет их совместной работой.
Пользовательский интерфейс и средства передвижения могут быть реализованы
посредством использования временной диаграммы Flash как нелинейной серии
секций анимации/контента. В итоговом Flash-сайте пользователь перемещается
между секциями, каждая из которых представляет некоторое состояние програм-
мы (например, разные страницы в многостраничной форме); для перемещений
используется простой интерфейс, основанный на щелчках мышью. Пользова-
тельский интерфейс также легко создается дизайнером с минимальным объе-
мом сценарного кода. В Flash MX Professional 2004 появились новые средства
Slides и Forms (объединенные общим термином Screens), упрощающие визуальную
разработку за счет изоляции разработчика от парадигмы временной диаграммы.
Вместо этого парадигма разработки приближается к стилю PowerPoint или Visual
Basic.
Flash MX и Flash MX 2004 содержат многочисленные компоненты (см. трюк 73)
для построения пользовательских интерфейсов - поля со списками, переключа-
тели и т. д. Эти компоненты упрощают разработку и последующую модифи-
кацию (на базе скинов) пользовательского интерфейса. Конечно, вы также мо-
жете создавать собственные элементы вроде кнопок (см. трюк 14) и бегунков
(см. трюк 61).
ActionScript также включает встроенные методы, упрощающие интерактивное
управление мультимедийными потоками (звуком и видео) при использовании
классов Sound, Microphone и Camera.
290 Глава 8. Элементы пользовательского интерфейса
В любом случае главная задача Flash - увлечь пользователя. Даже при исполь-
зовании технологии Flash в коммерческих или образовательных целях содержа-
ние должно быть увлекательным, иначе вы рискуете потерять старых зрителей
и не сможете привлечь новых.
В одних случаях интерфейс должен быть лаконичным и четким, в других случа-
ях требуется создать нечто необычное, что понравится пользователю и будет
соответствовать его ожиданиям. В конечном счете дизайнер сайта или разработ-
чик сам выбирает стиль с учетом предполагаемой аудитории и своих художе-
ственных наклонностей, а иногда и изменяет его на основании обратной связи
с пользователями.
Тем не менее, книга посвящена не проектированию интерфейсов, а нестандарт-
ным применениям Flash. По этой причине трюки настоящей главы посвящены
нетривиальному применению элементов пользовательского интерфейса в Flash.
Некоторые из них позволяют преодолеть очевидные недостатки средств органи-
зации пользовательского интерфейса Flash. Но как показывает первый трюк,
интерфейсные элементы предназначены не только для конечного пользовате-
ля - иногда они могут упростить процесс разработки программы.
Если уж речь зашла о пользовательских интерфейсах стадии разработки, Flash
MX 2004 и Flash MX Professional 2004 поддерживают концепцию расширяемос-
ти, то есть возможности не только настройки среды разработки Flash, но и до-,
бавления/модификации ее отдельных компонентов.
Среда разработки Flash настраивается средствами JSAPI (JavaScript API) с ис-
пользованием диалекта JavaScript, специфического для среды Flash JSFL (со-
кращение означает «Flash JavaScript» - да, меня тоже раздражают обратные
акронимы).
Как известно большинству веб-дизайнеров, JavaScript предоставляет прямой
доступ к пользовательскому интерфейсу браузера и всем открытым документам
HTML при помощи модели DOM (Document Object Model). Однако, в отличие,
от браузерной модели DOM, модель JSFL DOM предоставляет доступ к пользо-
вательскому интерфейсу среды разработки и всем открытым документам FLA.
Используя JSFL и связанную с ним модель, вы можете:
• обратиться к любой части открытого в настоящий момент документа Flash
(FLA) и отредактировать его на программном уровне. Данная возможность
позволяет создавать расширенные команды, вызываемые из меню Commands,
для автоматизации рабочего процесса или создания новых инструментов;
• модифицировать пользовательский интерфейс среды разработки Flash - напри-
мер, создать новые инструменты на панели элементов. Один из таких инстру-
ментов (PolyStar) отображается, если щелкнуть на инструменте Rectangle
и удерживать кнопку мыши;
• экспортировать SWF из командной строки Windows, как описано по адресу
http://moock.org/blog/archives/000058.html.
Кроме того, вы можете создавать пользовательские панели и запросчики (reques-
ters) для организации взаимодействия между сценариями JSFL и пользовате-
лем, что позволит не только запускать сценарии для модификации интерфейса
среды разработки Flash, но и настраивать разные аспекты работы самих сцена-
Интерактивное тестирование 291
риев JSFL! Для этой цели используется специальный язык на базе XML, XML to
UI, который дает возможность создавать пользовательские модификации интер-
фейса, работающие в среде разработки Flash и обеспечивающие взаимодействие
между пользователем и вашим кодом JSFL. Также предусмотрена возможность
взаимодействия между стандартным ActionScript и JSFL, поэтому воспроизве-
дение SWF может использоваться как часть пользовательского интерфейса.
Функция MM Execute () позволяет выполняемому SWF (обычно внедренному в ин-
терфейс XML to UI) запускать сценарии JSFL; так создаются большие нестан-
дартные интерфейсы с множеством автоматизированных задач и инструментов
на одной пользовательской панели.
Более того, фирма Macromedia использовала средства расширяемости в Flash
MX 2004 для реализации ряда новых возможностей, в том числе Timeline Effects,
Behaviors и записи макросов через панель History- Интересно, когда сторонние фирмы
начнут использовать JSAPI, XML to UI и MMExecuteQ для настройки среды раз-
работки Flash и распространять свои модификации среди других разработчиков
(учтите, что применение JSAPI, XML to UI и MMExecute() ограничивается ста-
дией разработки; эти возможности не предназначены для использования на ста-
дии выполнения в Flash Player)?
Создайте в символе клипа slider новый слой с именем puck. Создайте на слое
puck небольшой квадрат размером 10 х 10, преобразуйте его в символ puck
и разместите точку регистрации в центре квадрата. Затем поместите его в пози-
цию (- 5, -5) и задайте клипу имя экземпляра puckjnc (рис. 8.2).
| Movie Clip
X: -5.С
PI Jf'}
Наконец, создайте над слоем по умолчанию новый слой с именем actions и при-
соедините следующий код к кадру 1 слоя actions:
puckjnc.onPress = function() {
this.startDragUrue. -100. 0. 100. 0);
this.onMouseMove = _onMouseMove:
}:
jonMouseMove = functionО {
parent[_name + "_txt"].text = this._x;
updateAfterEventO:
}:
_parent[_name + "_txt"].onChanged = functionO {
puckjnc._x = Number(this.text);
}:
puckjnc.onRelease = puckjnc.onReleaseOutside = functionO {
this.stopDragO;
}:
_parent[_name + "_txt"].onChanged():
Приведенный фрагмент обеспечивает перетаскивание puckjnc вдоль линии.
Кроме того, клип puckjnc связывается с текстовым полем, находящимся на од-
Интерактивное тестирование 293
ной временной диаграмме с клипом slider. Имя текстового поля совпадает с име-
нем клипа slider и снабжается суффиксом _txt (sliderjxt).
Использование бегунка
При построении рекурсивных деревьев (см. трюк 6) я подбирал начальные зна-
чения основных параметров при помощи бегунков. В коде присутствовали два
параметра, значения которых мне было трудно подобрать на интуитивном уров-
не: angle (угол роста веток) и branch (густота ветвления).
Сначала я просто закомментировал фрагмент программы, в котором определя-
лись эти переменные:
// angle = 10;
// branch = 2:
Затем я быстро создал символ slider, разместил несколько экземпляров slider
и связанных внеэкранных текстовых полей (рис. 8.3).
initialize
—•
•
. .. тщ•
...... ••
•
-'; i
т
•сэ
•со
•пз
•CD
Итоги
Чем больше думаешь об этой методике, тем лучше раскрываются ее достоин-
ства. В любой ситуации, когда у вас нет полной уверенности относительно вход-
ных значений, просто свяжите их с элементами пользовательского интерфейса
и поэкспериментируйте. Данная методика помогает подобрать начальные значе-
ния переменных даже в том случае, если вся логика уже запрограммирована.
Вам не придется возвращаться к программе и вносить изменения, потому что
настраиваемые переменные были отделены от кодовой базы. Если подобрать
начальные значения не удается, возможно, этот факт поможет вам осознать не-
достатки исходной логики и необходимость ее изменения.
Разработчики сайта Banja использовали стандартный набор элементов для визу-
альной настройки локаций - чрезвычайно полезная возможность для команды,
в которую входят как программисты, так и дизайнеры. Программист пишет код
Action Script и создает внеэкранные элементы. Дизайнер готовит графику и на-
страивает переходы при помощи элементов пользовательского интерфейса. Та-
ким образом, эта методика пригодится даже «чистому» программисту, поскольку
она позволяет другим изменять входные данные, не прикасаясь к написанному
296 Глава 8. Элементы пользовательского интерфейса
Класс 800
В Flash не предусмотрены документированные средства для работы с правой
и средней кнопками мыши. К счастью, недокументированная функция ASnative()
позволяет вызывать дополнительные внутренние методы ActionScript (см. трюк 83)
с использованием числовых индексов, приблизительно соответствующих встроен-
ным классам.
Похоже, при вызове ASnative() с аргументом 800 появляется возможность вызова
методов ввода/вывода классов Key и Mouse, в том числе и недокументирован-
ных. Попробуйте выполнить следующий фрагмент:
this.onEnterFrame = functionO {
i f (ASnative(800; 2)(D) {
trace("Detected something..."): ,
Если выполнить этот код и щелкнуть левой кнопкой мыши, сценарий выведет
строку «Detected something...». Оказывается, вызов ASnative(800,2)(1) возвраща-
ет информацию о состоянии левой кнопки мыши: 1 (логическая истина), если
кнопка нажата, или 0 (логическая ложь), если кнопка не нажата. Хотя факт
нажатия левой кнопки мыши можно обнаружить при помощи документирован-
ного события Mouse.onMouseDown, приведенный выше код позволяет проверить
его состояние на текущий момент (например, чтобы узнать, остается ли левад
кнопка нажатой, без установки флага и ожидания события Mouse.onMouseUp).
Если последний аргумент вызова ASnativeQ равен не 1, а 2, результат получается
еще более интересным - функция возвращает информацию о состоянии правой
кнопки мыши:
this.onEnterFrame = functionO {
i f (ASnative(800. 2)(2)) {
trace("Right-click!"):
Правая и средняя кнопки мыши 297
Итак, теперь мы можем проверять состояния левой, правой и средней кнопок мы-
ши! Если мышь имеет более трех кнопок, состояния дополнительных кнопок про-
веряются вызовами ASnative(800,2)(5) и ASnative(800,2)(6). Вызов ASnative(800,2)(3)
вроде бы ничего не делает (по крайней мере, при вводе данных с мыши).
ПРИМЕЧАНИЕ
Функция ASnative() не документирована, а следовательно, не поддерживается
официально. Вызовы ASnative(), описанные в тексте, работают в Flash Player 5,
6 и 7, но они не прошли полного тестирования, а их работоспособность в буду-
щих версиях не гарантирована.
Итоги
Мыши для Macintosh часто имеют только одну кнопку, поэтому описанная ме-
тодика применима в основном для Windows. Тем не менее, если вы захотите
проверить состояние правой кнопки мыши, учтите, что при тестировании в бра-
узере щелчок правой кнопкой вызывает меню Flash Player. У третьей кнопки
функция по умолчанию отсутствует, но так как в большинстве программ третья
кнопка не используется, многие пользователи закрепляют за ней какую-нибудь
специализированную функцию - например, сворачивание всех окон на рабочем
298 Глава 8. Элементы пользовательского интерфейса
п г
J j П t"P * over
П о— nr down
U|o—
so— r U
Рис. 8.7. Имитация состояний кнопок посредством создания
именованных кадров в клипе
Г!
ПРИМЕЧАНИЕ
Чтобы кнопочный клип нормально работал, необходимо использовать именно
метки _up, _over и _down, соответствующие трем состояниям кнопки.
Свяжите с каждым ключевым кадром операцию stop() (по одной операции для
каждого состояния кнопки) при помощи панели Actions.
Разместите три графических представления кнопки в трех ключевых кадрах
так, как вы бы сделали это для обычной кнопки; используйте столько дополни-
тельных слоев, сколько потребуется. Разместите все новые слои под уровнем
actions (рис. 8.8).
300 Глава 8. Элементы пользовательского интерфейса
Добавьте новый слой с именем hit (рис. 8.9). В первом кадре этого слоя размес-
тите экземпляр символа клина hit; если потребуется, измените его размеры по
размерам графики в других кадрах. Затем скройте слой hit.
Рис. 8.9. Размещение клипа hit на слое hit главного кнопочного клипа
зо .:• 35
"disable'
Итоги
На создание кнопочного клипа требуется чуть больше времени, чем на создание
стандартной кнопки, но зато кнопочные клипы гораздо более универсальны бла-
годаря возможности выполнения сценариев onEnterFrame и реализации допол-
нительных состояний.
ChedcBox
Up ComboBox
-Щ ListBox
-!ll PushButton
•• Д RadioButton
Ц SaollBar
•••§^ ScrollPsne
i Media Components
I Ul Components
Frasne; 1
6 KB (6433 B)
Итоги
Прогресс - замечательная вещь, и компоненты Flash MX 2004 обладают множе-
ством дополнительных возможностей. Они обеспечивают управление глубиной
и передачей фокуса, вывод вспомогательной информации для пользователей с де-
фектами зрения... но иногда все, что вам нужно, - это самая обычная полоса
прокрутки!
В таких ситуациях (а особенно если увеличение размера файла на 30 Кбайт ради
одного компонента неприемлемо) следует использовать надежную хорошо зна-
комую полосу прокрутки Flash MX из компонентов vl.
ГЛ Д В Д 9
Быстродействие и оптимизация
Трюки № 65-73
Механизм анимации Flash не блещет быстротой, потому что основным критери-
ем оптимизации Flash Player была не скорость, а минимальный размер передава-
емого файла. Кроме того, этот механизм проектировался с расчетом на исполь-
зование в Веб, то есть оптимизация ориентировалась на малые файлы, а не на
большие, сложные анимации. Для обеспечения минимального уровня требова-
ний и максимальной совместимости Flash Player не поддерживает аппаратное
ускорение. Из-за этого Flash-дизайнеры часто сталкиваются с проблемами быс-
тродействия.
В Flash можно выделить следующие области потенциальной оптимизации:
• сокращение времени загрузки за счет эффективного использования объема
контента или изменения способа загрузки (см. трюк 73);
• повышение скорости анимации посредством оптимизации перерисовки;
• повышение скорости обработки данных посредством написания быстро вы-
полняемого кода.
Все перечисленные способы более подробно описаны далее.
Оптимизация графики
Широкое распространение Flash в немалой степени объясняется малыми размерами
Flash Player и способностью создания контента для каналов с низкой пропуск-
ной способностью. Тем не менее, за оптимизацию размера файла приходится
расплачиваться снижением быстродействия при возрастании сложности.
Векторная графика более компактна, чем другие графические форматы, поскольку
в ней определяются не низкоуровневые графические данные, а математические
объекты (точки, кривые и заливки), необходимые для прорисовки изображения
на стадии выполнения. Тем не менее, преобразование векторных данных в ито-
говое изображение занимает много времени, к тому же эту операцию приходит-
ся выполнять при каждом изменении внешнего вида или позиции графики. Если
изображение содержит области со сложными контурами или заливками, изме-
няющиеся в каждом кадре, анимация будет работать довольно медленно.
В этой главе рассматриваются некоторые методы борьбы со снижением быстро-
действия, специфическим для векторной графики. В частности, будут описаны
общие рекомендации по проектированию графики (см. трюк 68) и замене век-
торных изображений растровыми (см. трюк 72).
файла FLA, в более ранних версиях Flash эта команда не поддерживается. Более
того, файл, сохраненный в формате Flash MX 2004, не удастся открыть в преды-
дущих версиях (хотя Flash MX 2004 и Flash MX Professional 2004 используют
общий формат файла).
Решение проблемы
Заставить Flash сжимать FLA-файлы можно двумя способами. Это:
• сохранение файла командой File • Save and Compact (только в Flash MX 2004
и Flash MX Professional 2004). В процессе сохранения Flash удаляет всю лиш-
нюю информацию. При этом весь файл переписывается заново, поэтому опера-
ция занимает больше времени в зависимости от объема сохраняемого контента.
Открыть файл в предыдущих версиях Flash не удастся, так что будьте внима-
тельны и сохраняйте архивы унаследованных FLA-файлов! Архив лучше хра-
нить под другим именем на тот случай, если операция сжатия почему-либо
завершится неудачей;
• сохранение и переименование файла командой File • Save As (все версии
Flash). Происходит то же самое, что и при выполнении команды File • Save
and Compact, но с переименованием файла. Переименование окажется по-
лезным на случай сбоев при сохранении, однако файл можно сохранить и под
исходным именем - когда Flash выдаст предупреждение о том, что файл
уже существует (щелкните на кнопке Yes).
310 Глава 9. Быстродействие и оптимизация
Так почему же Macromedia не изменит свой продукт так, чтобы команда File • Save
выполняла сохранение одновременно со сжатием? Дело в том, что добавочное
сохранение выполняется гораздо быстрее. Таким образом, оптимальная схема
выглядит так:
• для частых сохранений используйте комбинации клавиш Ctrl+S (или <HS+S).
Файл сохраняется практически мгновенно, что позволяет продолжить работу
без задержек;
• периодически архивируйте файл, чтобы предотвратить потерю данных и при
необходимости иметь возможность вернуться к предыдущей версии;
• время от времени выполняйте команду File • Save As или File • Save and Compact
(например, в конце дня или перед архивацией файлов), чтобы сохранить файл
со сжатием;
• прежде чем создавать постоягшую архивную копию FLA-файла, создайте ре-
зервную копию. Затем удалите лишние ресурсы из библиотеки (помните, что
ресурсы, используемые из ActionScript, удалять нельзя). Затем сохраните
и сожмите файл одним из способов, описанных ранее, чтобы свести к мини-
муму его объем при хранении.
Итоги
Проблема с разрастанием файлов была учтена в Flash MX 2004, однако вы все
равно должны хорошо разбираться в сути этой проблемы, чтобы эффективно
организовать свой рабочий процесс. В ходе Flash-разработки часто происходят
многочисленные изменения в дизайне и наборах ресурсов, поэтому файлы раз-
растаются очень быстро. Минимизация размера FLA-файлов ускоряет их за-
грузку в среде разработки и экономит место при архивировании и пересылке.
Аналогичные проблемы существуют и в других коммерческих программных про-
дуктах, в том числе в Macromedia Director и Microsoft Word.
R
*** ^'i5i^ffr,^ ..^LocalW^tetonbcalhaiddnve)
,Ht Name Ил Foidl! .
~~" i C:\Documents and SettinqtASham B\My Documents^Flash Sites Щ>.
: : IJik Utilization % . : — | 5 T 3 I
1ЩШ • • •-.•' , I.
f Allow ВFowser.Caching,.; :
Fife Ve
i w. Server '.-..Help.
I l i i i i i i i i i i i
Waiting for web accesses.. ;Uptirne: OOhOBrn
Итоги
Хотя WebSpeed Simulator распространяется не бесплатно (программа стоит $99,
но пользователям предоставляется 30-дневный пробный период), эта среда луч-
ше всего подходит для тестирования требований к пропускной способности ка-
нала в процессе разработки веб-сайтов, особенно многофайловых.
Если WebSpeed Simulator будет постоянно находиться у вас под рукой во время
разработки, это поможет избежать многих неприятных сюрпризов. Программа
настраивается элементарно, поэтому вы сможете, например, продемонстриро-
вать клиенту работу сайта в имитируемых условиях на портативном компьюте-
ре. Подобные демонстрации помогут клиенту лучше понять, как пропускная
способность канала отразится на работе сайта, и принять более обоснованные
решения. Этот способ подходит для приложений Flash, загружающих большое
количество динамических данных, поэтому он окажет бесценную помощь как
разработчикам RIA, так и дизайнерам компьютерных анимаций.
№67 качества
Повышение быстродействия и сохранение внешней привлекательности
за счет маскировки последствий снижения качества.
Повышение качества неизбежно приводит к снижению быстродействия, поэто-
му в Flash существуют несколько режимов визуализации с разным качеством.
Хорошо разобравшись в этой теме, вы сможете принимать правильные решения
в конкретных ситуациях и обходить некоторые недостатки встроенных режимов
визуализации.
Механизм визуализации обычно использует сглаживание для маскировки рез-
ких краев векторных контуров и субъективного повышения качества. Резкие
переходы между областями контрастных цветов сглаживаются за счет добавле-
ния пикселов промежуточных оттенков. На кривой в левой части рис. 9.4 хоро-
шо видны неровности, возникшие из-за того, что слишком большой размер пик-
селов не позволяет точно воспроизвести кривую. Сглаженная кривая справа
выглядит более ровной.
Учтите, что сглаживание не исправляет ошибки, а лишь скрывает их от чело-
веческого глаза посредством смягчения перехода между контрастными цве-
тами.
314 Глава 9. Быстродействие и оптимизация
'•..
"ч.
Рис. 9.4. Исходная (слева) и сглаженная (справа) кривые
Другие приемы
Существуют и другие способы маскировки неровностей на векторных контурах.
Попробуйте сделать так, чтобы фигуры в ваших анимациях были заполнены
прямоугольными заливками (по возможности), быстро перемещались или со-
стояли только из вертикальных и горизонтальных линий.
Горизонтальные и вертикальные линии, в том числе и стороны прямоугольни-
ков, не нуждаются в сглаживании. С другой стороны, на быстро движущейся
фигуре неровности просто не разглядеть. Последнее обстоятельство может ис-
пользоваться в видеоиграх, написанных на Flash. На начальной заставке или
экране с инструкциями для игрока использование режимов "HIGH" и "BEST" не
повредит быстродействию, но при переходе к самой игре быстрая графика выхо-
дит на первый план, поэтому с большой вероятностью качество стоит снизить.
Кроме того, если объекты в игре движутся достаточно быстро (а статическая
графика состоит только из вертикальных и горизонтальных линий, как в игре
Pacman), пользователь даже не заметит снижения качества.
Впрочем, следует учитывать некоторые обстоятельства: при проектировании
графики для вывода на видео избегайте горизонтальных линий толщиной 1 пик-
сел. Поскольку на обычном телевизоре используется чересстрочный видеосиг-
нал, линии должны иметь толщину минимум 2 пиксела, чтобы предотвратить
мерцание. Даже при воспроизведении видеороликов в некоторых алгоритмах
сжатия могут возникать проблемы с очень тонкими линиями, поэтому проведи-
те тестирование перед выбором окончательного варианта дизайна.
Впрочем, даже идеально горизонтальные и вертикальные линия иногда выигры-
вают от сглаживания. Это особенно заметно для ярких цветов, воспроизводи-
мых на белом фоне.
Растровые шрифты
Сглаживание текста, выполняемое в той или иной степени во всех режимах,
кроме "LOW", серьезно расходует ресурсы процессора (особенно для больших
блоков текста или при движущемся тексте). С другой стороны, несглаженный
текст шрифтов, предназначенных для печати, плохо выглядит на экране. И на-
оборот, сглаживание затрудняет чтение при малых размерах букв (обычно ниже
8 пунктов, хотя это зависит от шрифта).
При работе с большими объемами текста или с мелким текстом следует исполь-
зовать растровые (пиксельные) шрифты, которые лучше смотрятся без сглажи-
вания (рис. 9.6).
Рис. 9.6. Растровые шрифты и мелкий текст лучше смотрятся без сглаживания
Итоги
Работая над созданием сложных анимаций в Flash, неизбежно начинаешь пони-
мать, что скорость визуализации векторной графики ограничена. Снижение каче-
ства изображения за счет отключения сглаживания (режим "LOW") позволяет
легко повысить быстродействие, но тогда начинают бросаться в глаза неровности
векторных контуров. Как было показано в данном разделе, существует несколько
способов снижения или маскировки снижения качества. Впрочем, неровности
даже можно сделать частью дизайна для создания эффекта «ретро». Конечно,
снижение качества визуализации - не единственный способ. В оставшихся трю-
ках этой главы будут представлены другие способы оптимизации быстродействия.
false, вместо того чтобы обнулять свойство _alpha. Иначе говоря, графика
быстрее всего воспроизводится при свойстве _alpha=100. Присваивание
временной диаграмме клипа пустого ключевого кадра (то есть полное от-
сутствие отображаемого контента) обычно способствует повышению быстро-
действия. Впрочем, иногда Flash пытается воспроизводить невидимые кли-
пы; попробуйте задать свойствам _х и _у значения (-1000, -1000) помимо
задания свойства _visible=false, чтобы полностью предотвратить подобные по-
пытки.
• Избегайте применения градиентных заливок. По возможности старайтесь за-
менять их растровыми заливками.
• Скорость графического вывода зависит от количества точек в кадре. Всегда
оптимизируйте сконструированные фигуры - откройте подменю Modify •
Shape и выберите одну из команд, Smooth, Straighten или Optimize (в зависи-
мости от типа фигуры), чтобы сократить количество точек, необходимых для
прорисовки фигуры. Замена контуров волосяными линиями (или их полная
отмена) существенно снижает количество необходимых точек. Чтобы узнать
количество точек в контуре, выделите его инструментом Subselection; если
теперь щелкнуть на любом из участков, вы увидите входящие в него точки.
• Скорость графического вывода в Flash также связана с количеством пиксе-
лов, изменяющихся между кадрами, поэтому постарайтесь избегать больших
изменений. Анимированный контент должен занимать как можно меньше
места - например, при уменьшении изображения на 10 % по каждому на-
правлению его общая площадь сокращается на 19 %. Если сцена содержит
несколько копий одного символа, экономия быстро накапливается.
• По возможности используйте пустые (лишенные заливок) фигуры или дру-
гие фигуры, сокращающие количество выводимых пикселов.
ПРИМЕЧАНИЕ
без применения альфа-эффектов пикселы, не изменяющиеся между кадрами,
практически не влияют на быстродействие.
Итоги
Итоговое быстродействие анимации Flash определяется многими факторами.
Оптимизация графики - одна из областей, оказывающих наиболее серьезное
влияние. Вообще говоря, оптимизация графики может выполняться на любой
стадии разработки, но наибольший эффект она приносит на более ранних стади-
ях. Если ждать до последней минуты, у вас останется мало времени, и многие
меры, которые можно было бы принять раньше (например, отмена прозрачнос-
ти), создадут гораздо больше трудностей. Мораль: оптимизируйте как можно
раньше и как можно чаще.
Сторонние программы оптимизации векторной графики - такие как Optimaze
(http://www.vecta3d.com) - уменьшают размер файлов до 60 % и ускоряют вы-
вод, потому что оптимизированные векторные данные проще обрабатываются.
320 Глава 9. Быстродействие и оптимизация
ТРЮК Хронометраж
№69 Bandwidth Profiler и утилиты независимых фирм позволяют оценить вре-
мя загрузки проекта Flash. Эталонное тестирование быстродействия так-
же поможет оптимизировать процесс воспроизведения.
Встроенный Bandwidth Profiler и программа WebSpeed Simulator (см. трюк 66)
оценивают предполагаемое время загрузки, но не решают проблему хронометра-
жа на стадии выполнения. Если скорость загрузки зависит от скорости подклю-
чения, то скорость выполнения определяется вычислительной мощностью ком-
пьютера, на котором воспроизводится ролик. Общее впечатление пользователя
складывается из времени загрузки и скорости воспроизведения, поэтому вы дол-
жны выбрать разумный компромисс между этими факторами - например, заме-
нить векторные изображения растровыми (см. трюк 72).
Многие склонны связывать скорость воспроизведения с частотой смены кадров,
выбранной разработчиком. Если Flash успевает прорисовать все за время, отве-
денное для вывода следующего кадра, тогда не так уж важно, остается у него
свободное время или нет. Но при таком подходе упускаются из виду проблемы,
которые могут возникнуть при повышении частоты смены кадров. Лучше зара-
нее определить, анимация какой графики занимает больше всего времени и ка-
кие сценарии ActionScript выполняются дольше других. Это позволит оптими-
зировать выполняемые операции и зарезервировать процессорное время для
других целей (например, для воспроизведения звука).
Далее приводится программа, которую я использую для проверки результатов
оптимизации. Вместо события onEnterFrame, привязанного к частоте смены кад-
ров, в ней используется интервальный таймер продолжительностью 1 мс, со-
зданный функцией setlnterval() (см. трюк 27). Программа заставляет Flash пе-
рерисовывать экран с максимальной частотой, хотя перерисовка и не будет
выполняться каждую миллисекунду по ограничениям, обусловленным быстро-
действием (скорее, это будет происходить примерно раз в 3 мс).
function animate(target) {
// Сценарий для перемещения клипа target по сцене
target._х = (target._х + I) % 400;
count++;
updateAfterEventO;
}
function controller() {
clearlnterval(animater);
// Вывод среднего времени перерисовки (в миллисекундах).
trace(clip[clipPointer]+ " " + 20000/count):
// 20-секундная анимация следующего клипа
// (если еще остались клипы для тестирования).
clipPointer++;
i f (clipPointer < clip.length) {
count = 0;
animater = setlnterval(animate. 1. c l i p [ c l i p P o i n t e r ] ) ;
} else {
// Если клипов не осталось - остановиться.
Хронометраж 321
clearlnterval(timer);
// Настройка
var clip:Array = new ArrayO;
var clipPointer:Number = 0;
var count .-Number = 0:
clip[0] = clipOl:
c l i p [ l ] = clipO2;
clip[2] = clipO3;
var animater:Number = setlnterval(animate. 1. clip[cl1pPointer]);
var timerNumber = setlnterval (controller, 20000):
Если clipOl, clipO2 и clipO3 являются тремя экземплярами одного клипа (напри-
мер, тремя версиями одной фигуры с разными уровнями оптимизации кривой
из подменю Modify • Shape), программа анимирует каждый экземпляр с макси-
мально возможной скоростью в течение 20 с. Далее выводится среднее время
перерисовки клипа в миллисекундах, и полученные результаты используются
для сравнительного анализа.
П
ПРИМЕЧАНИЕ
Представленная программа предназначена для тестирования умеренно слож-
ных фигур. Она не учитывает времени, потраченного на выполнение кода, но
дает представление о соотношении времен перерисовки.
Итоги
Применяя программный хронометраж, вы получите более реалистичную оценку
быстродействия, чем полагаясь на общие правила оптимизации. Хронометраж
поможет провести сравнительный анализ разных приемов экономии ресурсов
процессора. Например, сложные фигуры с большим количеством точек могут
анимироваться быстрее, чем простой, но большой круг. Более того, однородная
фигура, движущаяся перед растром, может снизить быстродействие в большей
степени, чем клип с прозрачностью, движущийся на гораздо более простом фоне.
Программный хронометраж позволит лучше понять, какой фактор оказывает
наибольшее влияние на быстродействие в конкретной анимации. Такой тип хро-
нометража лучше всего подходит для сравнения приемов, а не для получения
оценок скорости анимации или приложения в реальных условиях (см. трюк 70),
поскольку этот показатель сильно зависит от компьютера конечного пользовате-
ля и текущей загрузки системы.
322 Глава 9. Быстродействие и оптимизация
№70 анимации
Измерение производительности Flash Player во время выполнения по-
зволяет выполнить динамическую регулировку эффектов или анимации
для достижения оптимального быстродействия как на мощных, так и на
слабых компьютерах.
Ранее мы рассматривали приемы повышения быстродействия, основанные на
оптимизации ресурсов Flash на стадии разработки; эти приемы не зависели от
компьютера, на котором воспроизводится анимация. В сущности, оптимизация
такого рода составляет минимальный набор «на все случаи жизни». Трюк, опи-
санный в этом разделе, позволяет повысить до максимума качество анимации
и других эффектов на мощных компьютерах, но при этом сохранить нормаль-
ную работоспособность на более медленных машинах.
Хотя Flash Player 7 работает быстрее предыдущих версий, он все еще не идеа-
лен. Проектировщики Flash стремились оптимизировать размер файлов (для
уменьшения времени загрузки), а не добиться потрясающего быстродействия.
Хотя быстродействие можно улучшить посредством снижения качества
(см. трюк 67), во многих случаях отключение сглаживания оказывается непри-
емлемым из-за того, что сайт начинает выглядеть слишком убого.
Другой, более правильный способ повышения быстродействия основан на регу-
лировке сложности (то есть объема работы, выполняемой за один кадр) графи-
ческого эффекта, а не качества или частоты смены кадров. В широком диапазоне
пользовательских систем с разной вычислительной мощностью такой подход
дает лучший результат, чем «универсальная» оптимизация.
Регулировка сложности часто является итеративным процессом, основанным
на экспериментах (со временем она станет вашей второй натурой и потребует
меньшего числа итераций):
• задайте нужную частоту смены кадров - например, 18 fps;
• измерьте фактическую частоту смены кадров (см. далее);
• если нужная частота смены кадров недостижима на тестовом компьютере,
уменьшите сложность эффекта;
• если эффект воспроизводится достаточно быстро, значит, его сложность можно
повысить.
Теперь, когда вы знаете основную схему динамической регулировки эффектов,
попробуем автоматизировать ее, чтобы Flash принимал решение об уменьшении
или повышении сложности анимации. Тем самым мы избавимся от «торможе-
ния» на медленных компьютерах и добьемся улучшения эффектов (при грамот-
ной реализации) на быстрых.
Изменяться будет не частота смены кадров, а сложность эффекта, причем
так, чтобы модификация полностью завершалась перед началом следующего
кадра.
Динамическая настройка скорости анимации 323
}
// Переменной FRAME_RATE присваивается целевая частота смены кадров.
var FRAME_RATE:Number = 18;
var FRAMEJUR: Number = (1 / FRAME_RATE) * 1000:
var time:Number = 0;
vdr lastTime:Number = getTimerO;
performanceMonitor():
Переменная slow=false означает, что Flash Player может выполнить дополнитель-
ную работу без снижения быстродействия, потому что вся необходимая работа
выполняется до начала следующего кадра. В идеальном случае Flash Player дол-
жен завершать обработку текущего кадра непосредственно перед началом сле-
дующего кадра. Мы узнаем об этом, когда скользящее среднее time сравняется
с ожидаемой продолжительностью вывода кадра FRAME_DUR.
}
function moverO {
this._y += this.speed:
this._yscale += this.speed;
i f (this._y>275) {
this._y = 0;
this.speed = Math.ceil (Math.randomO * 10);
this._yscale = 100:
function starFieldO {
var star:MovieClip = this.createEmptyMovieClipC'star" + stars, stars);
star._rotation = Math.randomO * 360:
star._x = 275;
star._y = 200;
var dot:MovieClip = star.createEmptyMovieClip("dot". 0);
dot.speed = Math.ceil(Math.random()*10);
dot.lineStyled. OxFFFFEO. 100);
dot.moveTo(0. 2);
dot.lineTo(0. 5):
dot.onEnterFrame = mover;
Динамическая настройка скорости анимации 325
У -v .'-*.*« ->-
I #>/••••/
44>\<4WM№Bti*' * • *
JH*#* .''" 'I
1 f
, / ' '^ -
FSAHE RATE
bstTime
3
• j ^ ^ -
ч чч ^ mover
/ / i, iUrFssS
stsrs isss
tin» 154
.Stack
Количество звезд растет до тех пор, пока time не приблизится к FRAME_DUR. При
достижении этой точки программа начинает добавлять или удалять звезды для
сохранения равновесия. Если выполнить какую-либо операцию, нарушающую
это равновесие (например, запустить другую программу или изменить размеры
SWF), изменение быстродействия приведет к поиску новой точки равновесия.
Обратите внимание: частота смены кадров Flash иногда подвержена случайным
изменениям даже при достижении равновесного состояния, поэтому эффект будет
постоянно создавать и удалять клипы. Для таких случаев можно реализовать
буферизацию: например, удаление или добавление клипов будет производиться
только в том случае, если фактическое время вывода кадра отличается от целе-
вого более чем на 15 %.
326 Глава 9. Быстродействие и оптимизация
Итоги
Графические эффекты, хорошо работающие на компьютере разработчика, неред-
ко начинают «тормозить» на менее производительных компьютерах конечных
пользователей. Чтобы содержание Flash нормально воспроизводилось на как
можно более широком спектре компьютеров (включая гораздо менее мощные
мобильные устройства), постарайтесь обеспечить его масштабируемость, то есть
адаптацию к компьютеру пользователя. В этом трюке представлен довольно про-
стой подход: мы вычисляем скорость работы компьютера пользователя и вносим
соответствующие изменения в сложность графики. Измерение фактического
быстродействия во время выполнения обычно выполняется проще и дает более
надежные результаты, чем, например, попытки оценить быстродействие по типу
устройства или разрешению экрана.
Среди многочисленных изменений, обеспечивающих динамическую регулиров-
ку сложности анимации, можно выделить следующие:
• ограничение числа объектов на экране (звезды в звездном потоке, монстры
в игре, пользователи в чате с использованием аватаров);
• уменьшение количества используемых альфа-каналов;
• уменьшение альфа-эффектов (например, отключение прозрачности на мед-
ленных компьютерах);
• ограничение движений или их частоты (например» уменьшение числа кадров
в цикле ходьбы - см. трюк 28). Художники, работающие в области компьютер-
ной графики и не знакомые с требованиями к быстродействию, обычно соз-
дают слишком много промежуточных позиций. Вместо типичных 15-20 по-
зиций, создаваемых художником, часто хватает 3 или 5;
• уменьшение размеров экрана или его активной области. Чтобы экран выгля-
дел больше, добавьте статическую графику вокруг активной области - напри-
мер, бордюр для реализации эффекта «картины в раме» или статические дат-
чики, создающие эффект «приборной панели»;
• использование статических растров или видеоклипов с цветовыми эффекта-
ми (см. трюк 8).
Часто оказывается, что некоторые изменения оказывают сложное влияние на
быстродействие и обеспечивают выигрыш как на мощных, так и на слабых ком-
пьютерах. Например, в игре, имитирующей работу бармена, можно уменьшить
количество посетителей и частоту, с которой они обращаются с заказами. Это
приведет к сокращению количества выводимых объектов и используемых звуко-
вых каналов. С другой стороны, можно уменьшить размеры посетителей, чтобы
они занимали меньше места на экране. На мощных компьютерах это позволит
разместить в баре больше посетителей, а на слабых - ускорит вывод изображения.
Быстродействие компьютера конечного пользователя - не единственная причи-
на для динамического изменения содержания Flash. Иногда подобная методика
применяется для регулировки интерактивных упражнений в зависимости от ре-
зультатов пользователя. Например, если пользователь сделал что-то не так или
потратил слишком много времени на выполнение операции, можно вывести зву-
ковую или визуальную подсказку. В то же время, если пользователь постоянно
Смета быстродействия 327
Фокусная область
Смета быстродействия; как и все сметы, должна определять приоритеты. Иначе
говоря, не все аспекты презентации равноценны. Например, с точки зрения пользо-
вателя, перебои в воспроизведении звука более заметны, чем перебои в видео
или анимации. Некоторые дизайнеры также склонны уделять особое внимание
тем аспектам, на которые рядовой пользователь обычно не обращает внимания.
Пользователи внимательно рассматривают только те объекты, с которыми взаи-
модействуют в данный момент, то есть входящие в «фокусную область», поэто-
му таким объектам следует назначать высокий приоритет в смете быстродей-
ствия. Периферийные объекты пользователь либо не замечает, либо обращает
на них внимание только тогда, когда происходит что-то неожиданное (напри-
мер, если объект сдвигается). Следовательно, распределение сметы быстродей-
ствия и проектирование интерфейса, обеспечивающего потребности пользователя,
являются взаимодополняющими задачами.
Если фокусную область можно предвидеть (или эффективно управлять ею),
у пользователя создастся ощущение хорошего общего быстродействия даже в том
случае, если периферийные объекты остаются статичными или работают с мень-
шим быстродействием.
328 Глава 9. Быстродействие и оптимизация
Расстановка приоритетов
Как же выделить фокусной области приложения основную долю сметы быстро-
действия? Это можно сделать множеством разных способов. Проще всего назна-
чить фокусной области «обработчик изменений», а для обновления остальных
частей ролика использовать периодические события. Например, в реализации
классической видеоигры «пинг-понг» для управления ракеткой игрока может
использоваться обработчик события onMouseMove, а для управления ракеткой
противника и шариком - обработчик onEnterFrame. Если часть игры, с которой
непосредственно взаимодействует пользователь, хорошо реагирует на его дей-
ствия, то все приложение кажется более чувствительным.
Тем не менее, простое разделение приоритетов на две категории не обеспечивает
точного контроля над распределением ресурсов. Более правильное решение - ис-
пользовать несколько разных приоритетов. В следующем примере приоритеты
назначаются на основании степени взаимодействия пользователя с процессом:
• высокий приоритет - процессы, с которыми пользователь непосредственно
взаимодействует;
• нормальный приоритет - процессы, с которыми пользователь взаимодействует
косвенно;
• низкий приоритет - процессы, с которыми пользователь взаимодействует
редко (или не взаимодействует вообще).
В игровом контексте (именно игры составляют большинство Flash-приложений
с потребностью в высоком быстродействии) высокоприоритетный процесс пред-
ставляет корабль или игрока. Процессы с нормальными приоритетами представ-
ляют графические объекты противника; хотя пользователь ожидает, что враги
будут двигаться с нормальной скоростью, небольшие замедления останутся не-
замеченными, если высокоприоритетные объекты будут двигаться без торможе-
ния. Если корабль противника замедляет движение, пользователь решит, что
так и должно быть.
Низкоприоритетные процессы представляют такие объекты, как обновляющий-
ся индикатор текущего счета или прокрутку фона. Конечно, пользователь заме-
Смета быстродействия 329
тит, если эти объекты совсем перестанут работать, но пока все идет более или
менее нормально, он обычно не обращает на них внимания.
Проектировщикам игр иногда бывает трудно выделить низкоприоритетные про-
цессы, потому что разработчики склонны дорожить каждым пикселом и каждой
нотой. Возможно, вам будет проще избавиться от этих заблуждений, если вы
поймете, что снижение приоритета для одних объектов позволит выделить боль-
ше внимания (а соответственно, и ресурсов) другим, более важным объектам.
Также не стоит забывать, что даже самый симпатичный звуковой эффект надо-
едает после того, как пользователь услышит его в тысячный раз. Самое правильное
решение - предложить бета-тестерам прототип приложения и спросить, что им
понравилось, что показалось слишком медленным, что раздражало и т. д. По
определению, перед вами те самые люди, которых вы пытаетесь развлекать, про-
свещать, чьи потребности обеспечивать и т. д., так что прислушайтесь к их мнению.
Еще один полезный прием - создать у аудитории иллюзию того, будто прило-
жение делает нечто большее, чем в действительности. Например, на время выво-
да статической таблицы рекордов можно создать звездный поток с большим
количеством звезд, но сразу же после начала игры уменьшить сложность анима-
ции (см. трюк 70). Если количество звезд будет уменьшаться постепенно, а игра
будет становиться все более быстрой и сложной, пользователь даже не заметит
происходящего. Скорее всего, он будет думать о том, как попасть на следующий
уровень!
Реализация
После выбора приоритетов необходимо реализовать их на ActionScript. Поскольку
вы не можете просто указать Flash на важность некоторого события, приоритеты
приходится внедрять косвенно, на уровне приемов программирования и исполь-
зуемых событий.
Высокоприоритетные события могут использовать:
• интервальный таймер, установленный функцией setlnterval() на период, мень-
ший интервала смены кадров (см. трюк 27);
• обработчик события onMouseMove (см. трюк 26).
Частота высокоприоритетных событий превышает частоту смены кадров, поэто-
му их обработчики должны включать команду updateAfterEvent(), обеспечиваю-
щую перерисовку сцены между кадрами.
События с нормальным приоритетом могут использовать обработчик события
onEnterFrame, чтобы операции выполнялись с частотой смены кадров.
В реализации низкоприоритетных событий используются:
• интервальный таймер, установленный функцией setlntervalQ на период, боль-
ший интервала смены кадров;
• событие, время от времени инициируемое из обработчика событий с нор-
мальным приоритетом onEnterFrame.
33D Глава 9. Быстродействие и оптимизация
Итоги
«Смета быстродействия» не ускорит работу Flash Player, но создаст субъективное
ощущение скорости, подобно тому как индикатор прогресса субъективно ускоряет
загрузку. Идентифицируйте элементы, которые должны обновляться как молено
чаще, и выделите им больше ресурсов. Также определите низкоприоритетные
процессы и снизьте частоту их обновления, чтобы оставить больше ресурсов
высокоприоритетным процессам. Если повысить быстродействие в фокусной
области пользователя, ему покажется, что игра быстрее реагирует на его дей-
ствия, и он не заметит областей с более низким быстродействием.
332 Глава 9. Быстродействие и оптимизация
/~_ м ^ &
/з у*, д %
С// С ^ >
/I У
Lorem ipsum dotor sit amet,:cons€ctetuer adipiscing
elit, sed diam попитту пШЬ euismod ti«ddunt ut
laoreet clolore magna atiquam erat votutpat.
Итоги
Растровая графика имеет больший объем, но у нее есть и свои преимущества.
Его содержимое не нужно строить во время выполнения, а применение допол-
нительных эффектов на стадии разработки в таких программах, как Photoshop,
избавит от необходимости динамически обсчитывать тот же эффект.
Векторная графика обычно (хотя и не всегда) занимает меньший объем. С дру-
гой стороны, вывод векторных изображений может потребовать от Flash Player
серьезных вычислений в реальном времени.
Оптимизация загрузки и использования компонентов 335
№73 компонентов
В комплект поставки Flash входит множество компонентов, предназна-
ченных для решениях стандартных задач. Сведите к минимуму задержку,
которая может возникнуть из-за них в начале SWF.
Во многих Flash-презентациях (особенно коммерческих приложениях и роли-
ках, имитирующих рабочую область других программ) используются стандарт-
ные элементы пользовательского интерфейса - кнопки, раскрывающиеся спис-
ки и т. д. Macromedia предоставляет их в виде готовых компонентов (рис. 9.11).
ПРИМЕЧАНИЕ
Если выбрать в списке File • Publish Settings • Flash • Version формат экспорти-
рования Flash Player 7, некоторые исходные компоненты Flash MX v1 не работа-
ют в Flash MX 2004.
Некоторые компоненты vl, поставляемые с Flash MX, были написаны без учета
регистра символов, поэтому при попытке экспортировать их в формат Flash
Player 7 из Flash MX 2004 компилятор выдает ошибку (независимо от того, для
Оптимизация загрузки и использования компонентов 337
какой версии ActionScript они компилируются -1.0 или 2.0). Обновленные версии
правильно учитывают регистр символов, поэтому они будут работать в Flash
MX 2004 для любой комбинации форматов ActionScript 1.0/2.0 и Flash Player 6/7.
В Flash Exchange представлено несколько разных наборов компонентов. Также
обратите внимание на пакет Macromedia Pocket PC CDK (Content Development
Kit), доступный по адресу http://www.macromedia.com/devnet/clevices. Одну из
частей этого пакета составляют компоненты Pocket PC, оптимизированные для
малого размера файла и работающие в Flash Player для настольных систем (они
работают в Flash Player 6 и похоже, успешно работают в Flash Player 7 при
экспортировании в формат ActionScript 2.0).
Если в приложении используется минимальное подмножество функций компо-
нента, подумайте о создании собственных версий компонентов. Многие сайты
обходятся простейшими кнопками и полосами прокрутки, которые легко создать
в виде пары 1-килобайтных клипов. По адресам http://www.flashcomponents.com
и http://www.flashcomponents.net представлены альтернативные компоненты, соз-
данные сообществом Flash-разработчиков. Некоторые из них оптимизировались
для минимального размера файла.
Итоги
Компоненты v2 поставляются вместе с Flash MX 2004, но, конечно, это не един-
ственные компоненты, которые вы можете использовать в своих программах.
Компоненты v2 ориентированы на веб-приложения в условиях высокой пропуск-
ной способности канала. В других ситуациях можно использовать компоненты
Flash MX vl и даже другие компоненты от Macromedia или независимых фирм
(например, компоненты Pocket PC).
ГЛЙВД IB
ActionScript
Трюки № 74-85
ActionScript определяет истинную мощь Flash. Без ActionScript возможности Flash
ограничивались бы созданием тривиальной линейной анимации. С добавлением
минимального кода ActionScript реализуются базовые средства управления (кноп-
ки и активные зоны). Освоение нетривиальных возможностей ActionScript от-
крывает доступ к таким возможностям, как создание локальных общих объектов
(в просторечии - Flash-cookie). Без применения ActionScript не удастся создать
Flash-сайт, который бы взаимодействовал с браузером, обменивался данными с
серверными приложениями или загружал МРЗ-файлы.
Многие новые средства Flash MX 2004 или Flash MX Professional 2004 реализо-
ваны в предположении, что разработчик владеет ActionScript. Даже те из них,
которые не требуют опыта программирования (например, Behaviors и Timeline
Effects), при определенном уровне владения ActionScript реализуются более гиб-
ко и лучше структурируются.
Освоить анимацию на временной диаграмме несложно, но на то, что на ActionScript
легко делается за считанные минуты или часы, при «ручной» реализации уходят
дни и даже месяцы. А если дизайнер хочет, чтобы его приложение обладало
улучшенной интерактивностью, содержало логику принятия решений или обме-
нивалось данными с другими приложениями, ему не обойтись без изучения
ActionScript. RIA-программирование, онлайновые игры, улучшенные графические
интерфейсы - все это работает на базе сценариев.
Хотя настоящая глава полностью посвящена ActionScript, сценарии в том или
ином виде присутствуют практически в любом трюке книги. Так, в разделе «По-
вышение быстродействия кода» главы 9 рассматриваются проблемы оптимиза-
ции ActionScript. Кроме того, в книге представлены и другие трюки, относящие-
ся к быстродействию, - например, оптимизация байт-кода (см. трюк 100). Таким
образом, один из путей изучения ActionScript - практические эксперименты с трю-
ками и внесение в них всевозможных изменений. Кроме того, в предисловии
обсуждается проблема преобразования ActionScript 2.0, широко использующего-
ся в книге, в ActionScript 1.0.
Action Script 339
LiveDocs
:. Tacfa
ф navigate • •• function I
Щ. posTransitian •• -• function 0
«? Щ fatfeTexs *• function jfacigVaiuei i
® colTransition •• function ii i ;
~€ Щ, populateTltes ••• function
populateEvents •-•• function ip»g*lnd»x) i
if ipage!p3gsind*nl.pUnk{0i t» -IS (
tricoloi".unpO_mc*unRe!*ase « navigate,
tricolor.stnpO mc.sm№arfC.!jrr><;r •-1 true;
>
if ipag«lp»g«lnd«>a.pUnm.}!»-IS {
tricoiur.stripl г
true:
If lpae*{p»gelnd«»3.pUnkU! f- - 1 ! С
4
tricoto!".strip2_nx.:i'Si B.V!viO;":;f;i' •••• true:
popua
l tsErents
::
function {{>agelnd№(}'{
ипрсраЫ advents •• function У (
botom
top »*o
:; tncotor,sfrip1_rac.BnRetesse - navigate;
>}
!
0 >tf (page|pagein:dexj.pLinStf2] fa -tj f
>; • ttiootor,sSrip2_mc~3ftR*le33e « navijate;
•• tric^ar.sirip2_mc;s-S!!Hs<;s-S!".:.:.' ss- •• troe:
ф unpapuiiateEvents- •- f u t K t i o n - ^ {
127 Щ buftiteon •
••
•• function i page index;
CSS
HTML
JavaScript
Peri
PHP
Properties
Python
Text
SML
Используя SciTE|Flash для написания кода ActionScript 1.0 (а также кода Action-
Script 2.0 при использовании обновленных конфигурационных файлов с mizubitchy),
сохраняйте свои классы ActionScript во внешних файлах с расширением .as.
Чтобы протестировать сценарий, откройте новый документ FLA и свяжите с кад-
ром 1 сценарий с директивой включения внешнего файла:
#include "test.as"
346 Глава 10. ActionScript
Итоги
Если вам потребуется быстрый и компактный внешний редактор для написания
серьезных приложений, непременно опробуйте SciTE]Flash. Он покажется осле-
пительно быстрым всем, кто испытывает приступы клаустрофобии при работе
с длинными сценариями на панели Flash Actions (механизм свертки SciTE|Flash
помогает ориентироваться в больших сценариях). Однако SciTE|Flash гораздо
компактнее внешнего редактора Dreamweaver, который явно избыточен для на-
писания небольших фрагментов XML-кода.
Конечно, существуют и другие внешние редакторы, кроме SciTE|Flash. К их числу
принадлежат SE|PY (http://www.sephiroth.it/python/sepy.php) - бесплатный редак-
тор с открытыми исходными кодами, работающий на платформах Мае и Windows,
и PrimalScript (http://www.sapien.com/primalscript.htm) с минимальной ценой $179
(предоставляется 30-дневная бесплатная пробная версия без ограничения функ-
циональности). Оба редактора обеспечивают автоматическое завершение кода
ActionScript 2.09 и просмотр классов ActionScript 2.O.
О пользе жесткой типизации 347
var ball:MovieClip:
for (var i:Number = 0: i < 100: i++) {
ball = this.createEmptyMovieClipC'dot" + i . i ) :
ball._x = Math.randomO * Stage.width:
ball._y = Math.randomO * Stage.height:
ball.onEnterFrame = mover:
ball .sX = Math.randomO * 8 + 2:
ball.sY = Math.randomO * 8 + 2:
makeDot(ball);
}
Обратите внимание: объявление var balkMovieClip означает, что переменная ball
является экземпляром класса MovieClip (то есть что ball принадлежит к типу
MovieClipfc, поскольку объявление класса, фактически, определяет пользователь-
ский тип данных с тем же именем). Объявление ball с типом MovieClip сообща-
ет компилятору, что переменная должна содержать ссылку на клип. Позднее
переменная ball будет использоваться для хранения ссылок на клипы, создан-
ные во время выполнения программы функцией createEmptyMovieClip(): dotO,
dot1 и т. д.
Тип данных следует после двоеточия, и при каждом указании типа переменной
ее имени должно предшествовать ключевое слово var.
При попытке присвоить переменной значение, не являющееся ссылкой на клип:
ball - 0;
ball = "dot+i";
компилятор Flash выводит на панели Output сообщение о несоответствии типов.
На стадии разработки такие ошибки исправляются быстро и легко, тогда как без
проверки типов вы будете смотреть на пустую сцену во время выполнения и га-
дать, в чем же дело.
Также обратите внимание на то, что в приведенном примере функции и обработ-
чики событий тоже типизированы. Функция, которая не возвращает никакого
значения, объявляется с типом возвращаемого значения Void:
function myName():Void {
// Тело функции
}:
Если функция вернет какое-нибудь значение (чего она делать не должна), Flash
выведет сообщение об ошибке во время компиляции.
Функция, которая вызывается с аргументами и возвращает значение, записыва-
ется следующим образом:
function myName(argument:тип):возвращаемый_тип {
II Тело функции
return someValue:
}:
Если попытаться передать аргумент неправильного типа или если функция возвра-
щает неправильный тип (то есть someValue не относится к возвращаемому__ти-
ny), Flash снова выводит сообщение об ошибке компиляции.
О пользе жесткой типизации 349
Ограничения
Не стоит полагать, что жесткая типизация быстро и легко применяется во всех
случаях. Давайте рассмотрим некоторые ограничения проверки типов на стадии
компиляции.
Тип динамических свойств не проверяется. Так, в предыдущем примере свой-
ства ball.sX и ball.sY объявляются без указания типа данных. При динамическом
связывании пользовательских свойств с клипами на стадии выполнения ключе-
вое слово var использоваться не может. Запрет на использование var также озна-
чает, что вы не сможете задать тип данных таких свойств. Более того, поскольку
в нетипизированных переменных могут храниться данные произвольного типа,
компилятор Flash не выдаст сообщение об ошибке для следующей команды (не-
смотря на то, что свойство ball.sX создавалось для хранения числовой, а не стро-
ковой информации):
ball.sX = "cat";
Хотя в дальнейшем мы обращаемся к свойству ball.sX в виде this.sX внутри функ-
ции moverQ и передаем его функции checkl_imits() в параметре с именем speed,
объявленным с типом Number, компилятор Flash не обнаруживает подобные кос-
венные ошибки. Нетипизированная переменная проходит все проверки без выда-
чи сообщений об ошибках.
Чтобы использовать жесткую типизацию для проверки типов данных свойств,
необходимо создать пользовательский класс. Далее в определении класса зада-
ются типы всех свойств класса и свойств экземпляров. Например, сохранение
следующего кода во внешнем файле Ball.as дает возможность создать пользова-
тельский класс Ball, производный от MovieClip:
// Этот код ActionScript 2.0 должен храниться во внешнем файле Ball.as
class Ball extends MovieClip {
var sX:Number;
var sY:Number;
}
После этого в коде из предыдущего примера переменная ball объявляется с типом
Ball вместо типа MovieClip:
val ball:Ball: ,
При таком определении класса Flash проверяет типы свойств экземпляров (та-
ких, как ball.sX и ball.sY).
Условные команды затрудняют проверку типов. Flash поддерживает проверку
типов только на стадии компиляции, поэтому проверяемый код во время проверки
350 Глава 10. ActionScript
Итоги
ActionScript 2.0 обладает средствами проверки типов, отсутствующими в Action
Script 1.0. Эти средства не влияют на производительность на стадии выполнения
и не конфликтуют со старым кодом ActionScript 1.0, не обновленным до версии
2.0. Механизм проверки типов выявляет ошибки, часто упускаемые программис-
тами, и поэтому способствует написанию правильного, надежного кода.
Хотя ActionScript 2.0 не выполняет проверку типов во время выполнения, а провер-
ка типов на стадии разработки в некоторых ситуациях затруднена, применение жест-
кой типизации сэкономит немало времени и усилий разработчику любого уровня.
Кодовые подсказки
Вывод подсказок на панели Flash Actions упрощает написание сценариев
и предотвращает опечатки. Пользуйтесь подсказками, и вам не придется
снабжать переменные суффиксами, обозначающими их тип данных.
В Flash MX появилась система подсказок, отображаемых на панели Actions (F9).
Кодовые подсказки отображаются в виде контекстного раскрывающегося списка
с именами методов и свойств, соответствующих типу данных текущего объекта.
Flash MX определяет тип данных объекта по суффиксу имени. Например, для
активизации кодовых подсказок для экземпляра класса Color имя экземпляра
должно заканчиваться суффиксом _color. При нажатии клавиши «.» (точка) пос-
ле идентификатора с суффиксом появляется кодовая подсказка (рис. 10.4).
my color.
getRGB
getTransform
setRGB
setTrsnsform
Рис. 10.4. Раскрывающийся список кодовой подсказки заполняется
в соответствии с суффиксом объекта (например, _color)
return с;
354 Глава 10. ActionScript
}
var sData:Object = new ObjectO;
sData.x = 275;
sData.s = 4;
for (var i = 0: i < 500; i++) {
var dot:MovieClip = this.createEmptyMovieClipC'dot" + i .
this.getNextHi ghestDepth());
dot.onEnterFrame = animate;
}
В этом коде представлена стандартная методика копирования анимационных
клипов по ссылке. Переменная dot содержит ссылку на экземпляр клипа dot/.
Она всегда ссылается на клип, созданный в цикле, без создания дубликата это-
го клипа.
Все клипы уникальны, поэтому каждый из них обладает независимым набором
свойств, определяющих его размеры и позицию. Программа создает простейшую
имитацию броуновского движения (случайного перемещения частиц) - рис. 10.7.
Все 500 клипов независимы друг от друга.
356 Глава 10. ActionScript
Если изменить первую строку функции animate() так, чтобы копирование осуще-
ствлялось по ссылке, а не посредством клонирования:
this.sData = sData:
результат будет совершенно иным (рис. 10.8).
Итоги
Ссылки на существующие клипы часто используются в циклах, когда требуется обо-
значать разные клипы одним именем. Например, в следующем цикле ссылка должна
указывать на текущий клип, только что созданный методом createEmptyMovieClip().
К новым клипам гораздо проще обращаться по имени myClip, чем писать код,
который бы ссылался на них по конкретным именам экземпляров от clipO до clip9:
for (i = 0; i < 10; i++) {
var myC1ip:MovieClip = this.createEmptyMovieClipC'clip" + i . i ) :
// Операции с текущим клипом по имени myClip
myClip._rotation = 50;
}
Иногда копирование по ссылке свидетельствует об ошибке са стороны програм-
миста, который намеревался создать независимый объект. Метод Object.clone(),
представленный в этом трюке, поможет легко создавать независимые объекты.
Тайм-аут по бездействию пользователя 357
Тайм-аут по бездействию
ТРЮК
№78 пользователя
В приложениях, критичных по быстродействию, не стоит тратить процес-
сорное время на постоянные проверки действий пользователя. Создайте
событие «тайм-аута по бездействию», которое не будет мешать воспро-
изведению мультимедийной информации.
Однажды мне заказали Flash-приложение для сбора информации, которое долж-
но было работать на экранах, размещенных на спинках кресел в самолетах. Когда
пользователь на некоторое время переставал работать с приложением, оно долж-
но было переключаться на воспроизведение видеоролика. Но как только пользо-
ватель перемещал мышь или щелкал ее кнопкой, приложение должно было быс-
тро вернуться в режим ввода данных. Я написал код, выявляющий бездействие
со стороны пользователя, но без оптимизации этого кода видео воспроизводи-
лось неравномерно.
В Macromedia Director существует событие idle, инициируемое по бездействию
и позволяющее использовать свободное время для полезных целей (например,
для запуска фоновых задач). Flash-разработчики нередко повышают частоту сме-
ны кадров, пока у Flash остается свободное время (хотя его всегда меньше, чем
в Director, потому что Flash обладает более низким быстродействием). Собствен-
но, по этой причине в Flash отсутствует встроенное событие, которое бы иници-
ировалось при отсутствии полезной работы.
Пришлось крепко задуматься. Задача - создать событие, которое бы обнаружи-
вало отсутствие взаимодействия с пользователем. При получении этого события
приложение должно переключиться на выполнение других действий - скажем,
запустить анимацию или выдать звуковое приглашение. В Director такие собы-
тия называются событиями тайм-аута, но, как уже говорилось ранее, в Flash не
существует встроенных средств для обнаружения бездействия пользователя.
Пользователи часто оставляют Flash-сайты открытыми на время загрузки видео
или звука и работают в другом окне браузера. Было бы неплохо, если бы вместо
окна с надписью «содержимое загружено» SWF выдавал звуковую информацию
о завершении загрузки. Или, скажем, в автоматическом киоске при отсутствии
взаимодействия с пользователем по истечении периода тайм-аута SWF может
запустить видеоролик для привлечения покупателей.
Но как создать функцию обнаружения бездействия, которая бы не потребляла
вычислительных мощностей во время общения пользователя с SWF? Самый оче-
видный кандидат для обнаружения пользовательской активности - событие
onMouseMove (мышь в руке пользователя не может оставаться абсолютно непод-
вижной - если, конечно, пользователь не забывает дышать). Но во время активной
358 Глава 10. ActionScript
Итоги
Для обеспечения оптимального быстродействия в Flash необходимо свести к ми-
нимуму выполнение фоновых операций на время воспроизведения материалов,
требующих больших затрат ресурсов (видео, звук или сложная анимация). Это
означает, что фоновые задачи должны быть хорошо оптимизированы. Код про-
верки бездействия пользователя, представленный ранее, выиолняется относительно
редко, поэтому во время работы пользователя с сайтом он не замедляет воспро-
изведение основного содержания.
Если пользователь на некоторое время перестает работать с программой, активи-
зируется циклическое воспроизведение рекламного ролика или заставки. Такой
режим работы хорошо подойдет для автоматизированных киосков: если взаимо-
действие с пользователем прекращается, Flash-ролик сбрасывается в начало. Не
забудьте, что интервал тайм-аута (например, 30 с) должен быть длиннее любой
анимации, которая, как предполагается, не требует ответных действий от пользо-
вателя. Возможно, вам придется увеличить интервал тайм-аута, чтобы сделать
возможными вынужденные периоды бездействия, когда пользователь следит за
работой приложения. Впрочем, если пользователю приходится пассивно ожи-
дать в течение, скажем, 90 с и более, вместо простого увеличения интервала тайм-
аута лучше пересмотреть структуру приложения.
События нажатий клавиш также должны приводить к сбросу интервального тай-
мера. Представьте, что пользователь вводит текст на форме, но не двигает мышь;
бесцеремонный переход к заставке весьма удивит его. Следовательно, если авто-
матический киоск оснащен клавиатурой, воспользуйтесь методом Key.addListener()
для вызова обработчика onKeyDown, сбрасывающего интервал бездействия.
360 Глава 10. ActionScript
}
return false:
}:
method2 = function 0 {
// Поиск с интерпретацией массива как объекта
var i:String:
for (i in arr) {
if (arr[i] == nr) {
return true;
return false:
}:
method3 = function () {
// Поиск в массиве с предварительным преобразованием
// элементов в строку.
var searchPos:Number = arr.join(" ").indexOf(nr.toString())
if (searchPos != -1) {
return true;
}
return false:
}:
// Создание массива с последовательностью чисел от 0 до 999.
var arr:Array = new ArrayO:
var el em:Number = 1000:
Быстрый поиск в ActionScript 361
Итоги
Циклы часто применяются для выполнения повторяющихся операций, но в Flash
циклы приводят к большим затратам времени. Хорошее понимание сильных и сла-
бых сторон всех трех типов поиска (последовательного перебора элементов, пе-
ребора свойств, поиска в строке без применения циклов) позволит вам создать
оптимизированный код для любого конкретного приложения.
Материей предложен Эдвином Хейджменом
Блокировка слоя actions 363
Блокировка слоя
Чтобы слой actions сохранял свою специализацию и использовался только для
хранения сценариев, держите его постоянно заблокированным. Flash позволяет
заблокировать любой слой временной диаграммы - для этого следует щелкнуть
на точке в столбце с замком (рис. 10.9). Чтобы снять блокировку со слоя, щелк-
ните на замке, обозначающем заблокированный слой (на рис. 10.9 слой Layer 2
заблокирован). Блокировка слоя не запрещает его редактирование, как можно
было бы предположить, однако она не позволит добавлять объекты со сцены
в заблокированный слой.
364 Глава 10. ActionScript
Рис. 10.9. Чтобы заблокировать слой, щелкните на точке с столбце с изображением замка
Даже после того как слой будет заблокирован, с ним возможны следующие опе-
рации:
• добавление ключевых кадров (сценарии присоединяются только к ключевым
кадрам). Чтобы добавить ключевой кадр, выделите кадр заблокированного
слоя и нажмите клавишу F6 (или выполните команду Insert • Timeline • Keyframe).
Операция выполняется точно так же, как на любом незаблокированном слое;
• присоединение и редактирование сценариев, связанных с ключевыми кадра-
ми слоя, с применением панели Actions (F9);
• вставка кадров на заблокированном слое. Чтобы вставить кадр, выделите один
из кадров заблокированного слоя и нажмите клавишу F5 (или выполните ко-
манду Insert • Timeline • Frame). Операция выполняется точно так же, как на
любом незаблокированном слое. Следующие кадры автоматически сдвигают-
ся вправо.
Итак, блокировка слоя actions предотвращает размещение на нем графических
объектов или связывание символов с его ключевыми кадрами, в результате слой
может использоваться только для хранения сценариев. Тем не менее, блокировка
слоя не мешает добавлению и редактированию ключевых кадров и сценариев.
Итоги
Никто не запрещает вам хранить код во внешних файлах с расширением .as.
Более того, во многих ситуациях это даже рекомендуется делать вместо хранения
всего кода в первом кадре временной диаграммы. Но в отдельных случаях такое
решение оказывается непрактичным:
• создание больших анимаций с управлением временными диаграммами из
ActionScript - таких, как «The Goober Story» (http://www.humbugz.com/hela.htm);
• тривиальное управление временными диаграммами. Например, создавать специ-
альный класс для остановки клипа на кадре 12 было бы явным излишеством.
Гораздо проще (и эффективнее) добавить операцию stop() в нужный кадр;
• присоединение обработчика события к экземпляру клипа, не существующему
в первом кадре. Невозможно связать обработчик события с экземпляром до
того, как он будет существовать. Если анимационный клип не существует на
временной диаграмме до кадра 34, то присоединить к нему обработчик собы-
тия можно будет только в сценарии слоя actions в кадре 34, но не в кадре 33.
Хотя все эти ситуации способствуют распылению кода, основной код все же мо-
жет храниться в кадре 1 слоя actions - запишите все сценарии и обработчики
событий в виде функций и вызывайте функции из нужных кадров. При такой
схеме практически весь код ActionScript остается в кадре 1.
Отладка и трассировка 365
Команда
trace(z.join("\n");
выводит элементы в разных строках:
10
20
30
40
При работе с объектами для перебора перечисляемых свойств применяется цикл
for.jn. Для предыдущего определения w фрагмент
for (var i in w) {
traceC'w." + i + " = " + w[1]):
}
выведет следующий результат:
w.pl = 10
w.p2 = hello
w.p3 = true
Неперечисляемые свойства (например, встроенные свойства и методы, скрытые
от ActionScript) можно вывести недокументированной функцией ASSetPropFlags()
(см. трюк 82).
Часто сценарий ActionScript делает не то, что требуется, и вы не можете понять,
почему это происходит. Нередко причина кроется в недействительности экзем-
пляра (вы думаете, что переменная содержит действительный клип или экземп-
ляр объекта, а на самом деле в ней хранится «мусор») из-за ошибки программи-
рования или опечатки в имени экземпляра на панели свойств. К сожалению, если
Flash Player не может выполнить операцию из-за недействительности экземпля-
ра, он не выдает сообщений об ошибке. Диагностика таких проблем осложняется
рядом факторов:
• обычно проблема возникает при динамическом создании клипов и в больших
иерархиях временных диаграмм; отладчик загромождается информацией, что
затрудняет процесс диагностики;
• даже если экземпляр отображается в отладчике, он может не существовать
в начале кадра или область видимости переменной может отличаться от ожи-
даемой. Чтобы выявить подобные проблемы в отладчике, необходимо расста-
вить точки прерывания и вручную выполнять код в пошаговом режиме, строка
за строкой. Отладка такого рода занимает много времени.
Чтобы проверить действительность экземпляра на момент использования, вклю-
чите в программу отладочную команду trace() следующего вида:
for (var i in this) {
i f (i.indexOfC'myClip". 0) != -1) {
trace(myClip._name + " is on timeline " + this):
Итоги
Отладочная информация обычно выводится только на стадии разработки. Чтобы
предотвратить вывод отладочной информации в работающем приложении, от-
кройте диалоговое окно File • Publish Settings • Flash и установите флажок Omit
Trace Actions. Flash игнорирует вызовы trace() при экспортировании, и результат
будет таким же, как если бы все вызовы trace() в FLA были закомментированы.
Для решения более сложных задач отладки и сокращения объема данных, выво-
димых командами traceQ, можно создать пользовательскую, централизованную
функцию трассировки, исключаемую из окончательной версии сайта перед пуб-
ликацией.
В следующем листинге продемонстрирована простая схема изменения детализации
отладочных сообщений. Сообщения ставятся в очередь функцией сТгасе {сообще-
ние,приоритет). Если приоритет ниже пороговой величины verboseLevel, сообще-
ние не отображается на панели Output. В следующем примере при нулевом значе-
нии verboseLevel выводятся оба сообщения, а если переменная verboseLevel равна 1,
будет выведено только первое сообщение:
сТгасе = function (message, priority) {
i f (priority >= verboseLevel) {
trace(message):
}
// Применение:
verboseLevel = 1:
cTraceCImportant message", 1); // Сообщение выводится
cTrace("Low-priority message". 0): // Сообщение не выводится
Еще одно возможное усовершенствование - фильтрация сообщений. Например,
при большом количестве ошибок было бы логично начать с исправления самых
существенных проблем, а затем перейти к менее важным. Следующая программа
368 Глава 10. ActionScript
}
// Применение:
verboseLevel = 0:
cTraceC'XML f i l e not loading". 2);
cTrace("Unexpected characters found in XML f i l e " . 1);
Наконец, если тестирование должно осуществляться за пределами среды разра-
ботки (скажем, в браузере), отладочная информация может выводиться в тексто-
вых полях. В следующем листинге диагностические данные перенаправляются
в текстовое поле myText - предполагается, что поле уже существует на сцене
(изменения выделены жирным шрифтом). Чтобы прекратить вывод отладочной
информации, проще всего переместить текстовое поле на опорный слой:
сТгасе = function (message, p r i o r i t y ) {
i f ( p r i o r i t y > verboseLevel) {
verboseLevel = p r i o r i t y :
myText.text += messsage + "\n";
Недокументированные возможности
ТРЮК
№82 ActionScript
Недокументированные возможности ActionScript интересны всем. В на-
стоящем разделе рассматривается недокументированная область види-
мости _global.
Нередко для решения какой-то важной задачи требуется перебрать свойства объек-
та. Допустим, вы хотите вывести значения свойств на панели Output для получения
отладочной информации. Другой пример - декодирование неизвестных свойств
объекта, возвращенного, скажем, при обращении к базе данных на сервере. Есте-
ственно, нам хотелось бы перебрать скрытые (недокументированные) свойства
ActionScript и посмотреть, не найдется ли в них чего-нибудь интересного.
Недокументированные возможности ActionScript 369
slice
lastlndexOf
indexOf
concat
charCodeAt
charAt
toLowerCase
toUpperCase
toString
valueOf
_proto
constructor
Как видите, сначала перечисляются методы и свойства классов, а за ними следу-
ют методы и свойства экземпляров, объединенные в категорию prototype.
Попробуем обратиться к методам и свойствам класса из функции traceQ и посмот-
рим, что они вернут. В следующем примере вызывается метод String.fromCharCode(),
получающий один числовой аргумент (мы знаем об этом, поскольку метод fromChar
Code является документированным):
trace(String.fromCharCode(65)); // Вывод: А
Однако в список также входят недокументированные классы:
Cookie
setCookie
getCookie
proto_
constructor
Нам придется гадать, что представляет элемент списка - свойство или метод,
а если метод - с какими параметрами он вызывается. Например, команда
trace(Cookie.getCookieO):
выводит следующее сообщение:
Error opening URL "fi1e:///Сj/WINDOWS/PROFILES/SHAM^20B/
APPLICATIONX20DATA/MACROMEDIA/FLASHX20MXX202004/EN/
CONFIGURATION/Mmfdata/mmfdata3ff9fldf.xml"
В сообщении говорится об ошибке открытия конкретного файла, хотя при вызо-
ве метода никакое имя не указывалось!
Поэтому я попытался создать cookie методом Cookie.setCookie():
Cookie.setCookieC'footest data");
Далее последовал повторный вызов getCookie():
trace(Cooki e.getCooki e()):
На этот раз ошибки не было! Напрашивалось логичное предположение, что ме-
тод setCookie() успешно сохранил файл, который искал метод getCookieQ.
Я нашел файл mmfdata3ff9f1df.xml в каталоге, указанном в сообщении об ошибке,
открыл его в текстовом редакторе - и действительно, файл содержал положен-
ный текст:
footest data
372 Глава 10. ActionScript
Итоги
Конечно, недокументированные возможности Flash Player не документируются
и не имеют официальной поддержки по вполне определенным причинам.
Возможно, некоторые из них еще не прошли полноценного тестирования или
не были реализованы в полном объеме. Нет гарантий, что недокументированные
возможности сохранятся в будущих версиях Flash Player, поэтому пользоваться
ими необходимо с осторожностью. Даже если они работают в конкретном бра-
узере и на конкретной платформе, это еще не значит, что они будут работать
везде.
Итоги
Поиск недокументированных возможностей Flash Player до того, как Macromedia
сообщит о них, превратился в любимую игру многих пользователей Flash. На стра-
нице FlashCoders Wiki (http://chattyfig.figleaf.com/flashcoders-wiki/index.php7ASnative)
приводятся подробнейший отчет о текущем состоянии дел, а также дополнитель-
ная информация о методе ASnativeQ и его параметрах.
Нетривиальное применение
ТРЮК
№84 операторов
Недокументированные возможности ActionScript — не единственная благо-
датная почва для любопытных программистов. Оказывается, некоторым
операторам ActionScript также можно найти нетривиальное применение.
Типичный разработчик решает 90 % своих задач при помощи 10 % возможностей
ActionScript. Прочие возможности ActionScript используются очень редко или
в крайне специфических ситуациях. Впрочем, некоторые средства ActionScript
применяются редко лишь потому, что разработчики не умеют ими правильно
пользоваться или не знают, как найти им неочевидные применения.
В настоящем разделе описаны альтернативные способы использования некото-
рых команд и операторов ActionScript.
374 Глава 10. ActionScript
// Создание линии
t h i s . l i n e S t y l e ( n u l l . 0x0. 100);
this.moveToOOO. 190):
this.lineTo(300. 210);
var speed = 4;
// Создание анимации
ball.onEnterFrame = clamp;
Оператор % также может применяться для усечения величины до ближайшего
числа, кратного заданному. Если х=а%Ь, то прибавление или вычитание х%Ь из х
позволяет привести х к целому числу, нацело делящемуся на Ь. Следующие ко-
манды выводят 300 и 400 соответственно:
х = 350;
trace(x - х$100): // Ближайшее меньшее число, делящееся на 100
traceCx + хЯЮО); // Ближайшее большее число, делящееся на 100
В следующем примере этот прием используется для реализации перетаскивания
мышью с привязкой к координатной сетке. Клип ball следует за мышью и автома-
тически выравнивается по координате, кратной 30 пикселам:
ball.onMouseMove = function О {
this._x = _xmouse -_xmouse%size;
this,_y = _ymouse -_ymouse%size:
updateAfterEventO:
}:
size = 30:
Нетривиальное применение операторов 375
В файле dragger.fla на сайте книги этот код используется для создания набора
мозаичных пластинок, которые могут располагаться только в фиксированных
позициях вдоль сетки. Запустите пример и попробуйте перетаскивать мышью
цветные квадраты - вы увидите, что они привязываются к ближайшему узлу
сетки и плотно прилегают друг к другу, как показано в правой части рис. 10.10.
Итоги
Как видите, у стандартных операторов ActionScript находится много неочевид-
ных применений, которые часто превосходят типовые решения по компактности
или скорости. Помните о них, если быстродействие действительно критично для
вашего приложения.
Импортирование ASC-файлов
ТРЮК
Формат ASC
Файл в формате ASC представляет собой последовательный ASCII-файл, содер-
жащий серию строк с данными, разделенными пробелами. Каждая строка завер-
шается символом новой строки (или другим ограничителем):
data data data data data<CR>
data data data data data<CR>
}
readXMLstart = function () {
my3dFile = xObj.firstChild.nodeValue;
readASCO:
}:
readASC = functionО {
var olndex:Number = 0:
var гIndex:Number = 0;
var el em: String = "";
while (rlndex != -1) {
rlndex = my3dFile.index0f("\n". olndex):
elem = my3dFile.substring(oIndex. rlndex);
// Пропускаем дополняемые строки (длина менее 30 символов)
if (elem.length > 30) {
shape[shape.length] = elem:
}
olndex = rlndex + 1;
}
var xObj:XML = new XMLO:
var my3dFile:String = new StringO:
var shape:Array = new ArrayO:
xObj.onLoad = handlelncoming;
xObj.load("torus.asc");
Метод String.substring() просматривает содержимое my3dFile и извлекает символы
между начальной позицией первого необработанного символа olndex и позицией
следующего перевода строки rlndex:
rlndex = my3dFile.indexOf("\n". olndex);
elem = my3dFile.substring(oIndex. rlndex):
Значение rlndex определяется поиском следующего вхождения \п с использова-
нием метода String.indexOf(). Программа узнает о достижении конца ASC-файла,
когда метод String.indexOf() возвращает -1 - признак того, что искомая строка не
найдена.
382 Глава 10. ActionScript
Вообще говоря, в нашем примере эти смещения одинаковы для всех строк, начи-
нающихся со слова «Vertex», но выполнение этого условия не гарантировано,
поэтому мы ищем начальные позиции данных и не пользуемся никакими предпо-
ложениями.
По найденным смещениям из строки извлекаются координаты х, у и z. Начальное
смещение увеличивается на 2, чтобы в подстроку не вошел префикс из буквы
и двоеточия:
рХ = Number(elem.slice(posX + 2. posX + 6 ) ) :
pY = Number(elem.slice(posY + 2, posY + 6));
pZ = Number(elem.slice(posZ + 2, posZ + 6));
Наконец, точка (х, у, z) создается в виде структурированного объекта Flash. По-
зднее объект может использоваться в ActionScript для построения трехмерной
фигуры (см. трюк 37). В данном случае координаты точки добавляются в виде
свойств элемента массива shape (рис. 10.14):
shape[sPointer] = new ObjectO:
shapeCsPoi nter].x = pX;
shape[sPointer].y = pY;
shape[sPointer].z = pZ;
}
readXMLstart = function О {
my3dFile = xObj.firstChild.nodeValue;
readASC();
}:
readASC = functionO {
var olndex:Number = 0;
var rlndex:Number = 0;
var elem:String = "":
var posX:Number = 0;
var posY:Number = 0:
var posZ:Number = 0;
while (rlndex != -1) {
384 Глава 10. ActionScript
}
olndex = rlndex + 1;
}
}
var xObj:XML = new XMLO:
var my3dFile:String = new StringO;
var shape:Array = new ArrayO;
var sPointer:Number = 0;
xObj.onLoad = handlelncoming;
xObj.load("torus.asc"):
Читатель может ознакомиться с полной версией этого приложения, написанной Эд-
вином Хейджменом, в разделе «Experiments» сайта http://www.poeticterror.com. Пол-
ная версия строит по точкам интерактивное трехмерное изображение (рис. 10.15).
Итоги
По мере того как Flash завоевывает все большую популярность как универсаль-
ная мультимедийная веб-платформа, все чаще возникает задача импортирования
данных в SWF из других приложений, в том числе и не связанных с Веб. Даже
Импортирование ASC-файлов как формата XML 385
Интеграция с браузером
Трюки № 86-96
С первых дней своего существования технология Flash был тесно связана с веб-
браузерами. Правда, Flash позволяет создавать специальные приложения, исполь-
зующие Standalone Player для воспроизведения SWF-файлов, и все же большая
часть Flash-контента просматривается через веб-браузеры благодаря вездесуще-
му модулю Flash Player (в Internet Explorer для Windows он реализован в форме
элемента ActiveX).
Как ни странно, отношение многих пользователей к Flash (как хорошее, так
и плохое) часто строится на неправильных представлениях. Многие веб-разра-
ботчики и пользователи толком не понимают, как Flash работает с браузерами.
В этой главе показано, как Flash интегрируется со стандартными средствами
браузера (например, кнопкой возврата - см. трюк 94) или поисковыми система-
ми вроде Google.
Кроме того, здесь рассматривается оригинальный способ проверки браузерного
модуля Flash Player (см. трюк 87). Если Flash Player установлен, он периодически
проверяет наличие обновлений на сайте macromedia.com. Как говорится в доку-
ментации Macromedia Flex «Managing Flash Player Auto-Update» (http://livedocs.
macromedia.com/flex/1/flex_docs/wwhelp/hhwimpl/common/html/wwhelp.htm?context =
=Flex_Documentation&file=38_dept42.htm#wp154069), конфигурация автоматиче-
ского обновления задается в файле mms.cfg в домашнем каталоге пользователя
или посредством настройки параметров, о которых пойдет речь далее.
Безопасность и конфиденциальность сыграли важную роль в принятии Flash
как платформы распространения контента. Большинство разработчиков знают
о контекстном меню Flash, вызываемом щелчком правой кнопки мыши (Windows)
или щелчком с кнопкой 8£ (Мае). Важнейшая команда этого меню, Settings, от-
крывает диалоговое окно параметров Macromedia Flash Player. На вкладках это-
го окна настраиваются параметры конфиденциальности, локального хранилища,
микрофона и камеры. Но лишь немногие разработчики (и еще меньше пользова-
телей) знают о существовании дополнительных параметров Flash Player, настра-
иваемых только через веб-сайт Macromedia. Пользователи могут вызвать Settings
Manager (http://www.macromedia.com/support/documentation/en/flashplayer/help/
settings_manager.html) кнопкой Advanced на вкладке Privacy. На сайте Macromedia
Интеграция с браузером 387
mozilla
также можно найти старые версии модулей Flash, позволяющие легко переклю-
читься на нужную версию Flash Player для Windows/Mac.
Версии Flash Player существуют и для других операционных систем, включая
Linux и OS/2. Их можно найти на странице http://www.macromedia.com/shockwave/
download/alternates.
Также стоит упомянуть и о таком полезном «браузере», как Any Browser. Эта
утилита эмулирует предельно упрощенный, минимальный браузер (HTML 3.2
с поддержкой таблиц, но без поддержки Flash и JavaScript). Хотя AnyBrowser не
позволяет отображать содержание Flash, это хороший инструмент для тестиро-
вания худшего случая (отсутствие поддержки Flash). Если веб-страница способ-
на сообщить пользователю о возникших проблемах и подсказать действия, кото-
рые нужно выполнить в браузере, вы идете по правильному пути!
Если вас заинтересует AnyBrowser, щелкните на ссылке Site Viewer на сайте http:/
/www.anybrowser.com и найдите ссылку.
жок Display Menu, все равно, будет отображаться контекстное меню с командами
Settings и About Macromedia Flash. В прошлом предлагалось немало способов по-
давления контекстного меню, в основном непрактичных. Например, в одном из
вариантов сцена накрывалась выделяемым текстовым полем - но тогда вместо
контекстного меню Flash отображалось контекстное меню редактирования тек-
ста, что выглядело весьма странно (к тому же пользователь не мог щелкнуть на
другом объекте сцены!)
Вопрос об отключении контекстного меню довольно часто встречается на форумах,
поэтому я не могу обойти его стороной. Контекстное меню можно полностью от-
ключить за счет умного применения HTML и JavaScript, как описано на сайте Грега
Вигоника (Gregg Wygonik) по адресу http://www.broadcast.artificialcolors.com/stories/
2003/09/21/disableFlashMovieRightClickMenu.html. Существует еще более удобный
вариант - загрузите написанный Грегом компонент gwContextKiller (http://
www.artificialcolors.com/experiments/gwContextKillerlnfo.html), отключающий вызов кон-
текстного меню в браузерах IE 6+ и Mozilla 1.3+ (также работает в IE 5, но не в IE
5.5). Просто перетащите компонент на сцену Flash, обычно - за пределы экрана,
а затем задайте параметру Window mode на вкладке File • Publish Settings • HTML зна-
чение Windowless Opaque. Но учтите, что в этом случае Flash-ролики превратятся в
черные квадраты для пользователей, запретивших плавающие рекламные окна Flash
(http://www.jessewarden.com/archives/000507.html) или отключивших автоматическое
обновление (http://livedocs.macromedia.eom/flex/1 /flex_docs/wwhelp/wwhimpl/comrnon/
html/wwhelp/htm?context=Flex_Documentation&file=38)dep42.htm#wp154069).
Итоги
Существует несколько путей улучшения совместимости Flash-сайтов с браузе-
рами. Как правило, следующие меры позволяют заметно сократить процент
пользователей, для которых ваш сайт остается недоступным:
• тестирование в разных браузерах;
• ручная правка HTML-кода, благодаря которой информация о сайте будет
отображаться в поисковых системах с осмысленными описаниями и ключе-
выми словами;
• проверка наличия модуля Flash у конечного пользователя и разумное пове-
дение сайта в зависимости от ее результатов.
Возможные проблемы
Иногда оказывается, что ранние версии Flash Player распознают функцию getURL(),
поддерживаемую с Flash Player 2, но не воспроизводят весь контент Flash-сайта.
Допустим, вы хотите использовать видео, поддерживаемое Flash Player версий 6
и выше, а у пользователя установлен Flash Player 5. Flash Player 5 поддерживает
метод getURLQ, но не воспроизводит видео, внедренное в SWF-файл. В подоб-
ных случаях приходится проверять минимальную версию модуля Flash Player.
Flash-ролик для проверки версии Flash Player должен быть SWF-файлом Flash
Player 4 или Flash Player 5. Он проверяет версию Flash Player, а затем загружает
Универсальный анализатор поддержки Flash 395
Ш _global
Nsme [Value
^version
Итоги
Трюк, представленный в настоящем разделе, проверяет отсутствие Flash Player -
это проще, чем активное определение наличия Flash Player. Если Flash Player
присутствует в системе, мы проверяем его версию (если потребуется). Вместо
проверки Flash Player из JavaScript мы просто предлагаем Flash Player иденти-
фицировать себя.
Наш анализатор не зависит ни от поддержки JavaScript, ни от версии модуля
Flash Player. Минимальным требованием является поддержка тега <meta>,
обеспечиваемая браузерами версий 3.x и выше. Как максимум, требуется модуль
Flash Player, способный опознать команду if и свойство $version (а именно Flash
Player 4 и выше).
Конечно, рассмотренное решение представляет собой трюк (если на то пошло,
вся книга посвящена трюкам) и не обеспечивает абсолютной надежности. В за-
висимости от конфигурации пользователям Internet Explorer без Flash Player
может быть предложено установить соответствующий элемент ActiveX. В то же
время, в зависимости от временных характеристик (от того, сколько времени
уйдет на вывод сообщения и ответные действия) пользователь может не попасть
на страницу без Flash.
Сценарии обнаружения модулей не бывают идеальными - у любого из них най-
дутся свои недостатки. Рассматривайте этот прием как лишнюю стрелу в своем
колчане, а не как серебряную пулю. За информацией о более традиционных
методах идентификации поддержки Flash обращайтесь к ресурсам, перечислен-
ным во введении к настоящей главе.
№88 Flash
Тестирование приложений с разными версиями Flash Player без перехо-
да на другой компьютер или ручной установки/удаления других версий.
Многие клиенты требуют, чтобы их сайт оставался совместимым с предыдущей
версией Flash Player (на момент написания книги - Flash Player 6) до тех пор,
пока текущая версия (Flash Player 7) не достигнет пользовательской базы при-
мерно в 90%. Столь широкое распространение обычно достигается через 18 ме-
сяцев после выхода новой версии.
Тестирование с разными версиями Flash 397
FlashPfuginSwltcher
Рис. 11.4. Логотип Flash Plugin Switcher
Итоги
Помните, что программа Flash Plugin Switcher существует на пожертвования
пользователей. Если вы будете работать с ней, не забудьте поблагодарить Алекса
через систему PayPal.
Genera!
?>• General- - —• • - •>••- •
Undo levels: j W%k \
Printing options: f3 Disable PostScript
! Selection options: Щ Shift «feet
|3 Show tooltips
Panel options: £3 Disable panel docking
I TimeSne options: H Disable timeline docking
E ] Span based selection
If) Named anchor on Scene
Highlight color: Ф Use this color В
© Use layer color
I Font mapping default: jsans j§s
Cancel
Если в списке Version выбирается строка Flash Player 6, флажок Optimize for Flash
Player 6r65. Flash Player 6r65 имеет много общего с Flash Player 7, поэтому этот
выбор повышает совместимость до повсеместного распространения Flash Player 7.
Учтите, что Flash Player 6r65 поддерживает не все новые возможности Action-
Script, включенные в Flash Player 7 (см. главу 10). Дополнительная информация
о совместимости компонентов v2 с последними версиями Flash Player приведена
в блоге BIT-101 (http://www.bot-101.com/blog/archives/000047.html).
Window Mode: W i n d o w v
;
: ' • ' • . • •. . : .
Scale:
•: • : • • • . .
N o s c a l e
3 • • • : : - . ' :
|
:
• / ; . • • • • • • : : l
: : ; •torizontal V e r t i c a l
••:•:•••'•'• - -^: -::/Д^Г . • • • , . . : ; •: •
F l a s h a l i g n m e n t : C e n t e r v ! C e n t e r
. . i l l .
: | . P u b l i s h [ c a n c e l
1 1 O K
Выравнивание по центру
ТРЮК
Параметры публикации
Для примера возьмем SWF-ролик, показанный на рис. 11.9.
О : V ;. . ..•
_
• •
Тестовая таблица закрывает сцену, а четыре угловые фигуры (два круга с впи-
санными квадратами и два квадрата) находятся за пределами сцены. Светло-
серая рамка тоже не входит в сцену.
Если масштабировать сцену по размерам окна браузера (выполните команду
File • Publish Settings • HTML, выберите в списке Dimensions значение Percent), то
четыре внешние фигуры не будут видны.
Однако у такого решения есть серьезный недостаток. Если пользователь запус-
тит браузер в большом окне, то большой размер полученного SWF-файла суще-
ственно замедлит работу сайта. Если выбрать в списках Horizontal и Vertical стро-
ку Center, а в списке Scale - строку No Scale (см. рис. 11.8 из предыдущего
трюка), центровка будет выполнена так, как показано на рис. 11.10.
SWF-ролик выровнен по центру, но в окне также отображается контент, находя-
щийся за пределами сцены. Иногда это не создает проблем, но многие сайты
содержат скрытый контент, находящийся полностью или частично вне сцены.
При создании анимаций находящийся вне сцены контент обычно скрывается
для организации панорамирования и наплывов.
Посмотрите на рис. 11.11. Перед вами фрагмент анимации, созданной Адамом
Филипсом, с которым мы работали над некоторыми проектами
Выравнивание по центру с применением CSS 405
40°**
Рис. 11.10. Тестовая таблица, выровненная по центру без масштабирования
vjj311им
Iliili
III; |
^Ш^^^яИ HI
1
Щ HЩ
l
I
i
i 1
шШ I
1i
•
I
1H P
</td>
</tr>
</table>
</body>
</html>
Добавление тега <table> не только выравнивает SWF по центру, но и скрывает
контент, находящийся вне сцены. К сожалению, этот способ не работает в Flash
MX 2004. Flash MX 2004 экспортирует код XHTML, а не HTML, а вертикальное
выравнивание таблиц HTML плохо работает в XHTML. В принципе, проблема
решается внедрением файлов Flash 7 в HTML, но лучше ограничиться XHTML
и использовать теги <div> и <span> вместо устаревших тегов <table> и атрибутов
выравнивания.
body
{
margin: Opx
}
#centercontent
{
text-align:center;
position: absolute:
top: Б0%;
l e f t : Ь0%:
</style>
Теоретически это должно приводить к размещению SWF на расстоянии 50% от
левого и верхнего полей браузера (а также удалению лишних промежутков вдоль
краев страницы), но есть одно неожиданное обстоятельство: CSS предполагает,
что точка регистрации находится в левом верхнем углу SWF. Чтобы увидеть
ошибку выравнивания, заключите теги <object> и <embed> в тег <div> с атрибу-
том centercontent, как показано в следующем листинге (дополнения выделены
жирным шрифтом):
<div id="centercontent">
<object...
.. .</object>
>i1
Fie E •* F*v<e*ieT5o* -<e!p
- ^ ;.
Рис. 11.13. Левый верхний угол SWF выравнивается по центру окна браузера
Выравнивание по центру с применением CSS 409
Итоги
В выборе между HTML и XHTML/CSS нам, Flash-разработчикам, не пристало
отдавать предпочтение старым технологиям. Наверное, правильное центрирование
SWF с применением CSS неочевидно, но стоит узнать пару трюков, и вы без
труда добьетесь от браузера нужного поведения.
Динамическое масштабирование
ТРЮК
№92 контента
В идеале Flash-контент сохраняет свои размеры даже в том случае, если
пользователь изменил размеры окна браузера. Динамическое масшта-
бирование контента в ответ на изменение размеров браузера поможет
сохранить исходный дизайн.
Динамическое масштабирование SWF по размерам окна браузера вроде бы не
должно создавать проблем, но похоже, многие разработчики не умеют правиль-
но организовать его. Давайте разберемся, как это делается.
Хотя Flash Player поддерживает масштабирование SWF по размерам окна брау-
зера, делать этого не стоит по нескольким причинам:
• слишком большое увеличение отрицательно отразится на быстродействии
(особенно на больших экранах);
Динамическое масштабирование контента 411
вручную изменяет размеры окна браузера). Для этого размеры будут читаться
в обработчике события:
var stageListener - new ObjectO;
stageListener.onResize = functionO {
trace(Stage.height);
traceCStage.width);
}:
Stage.sealeMode = "noScale":
Stage.addLi stener(stageListener);
Допустим, мы работаем с двумя клипами. Первый, scaleable_mc, используется
в качестве фона и заполняет окно браузера. Второй, centered_mc, всегда остается
в центре браузера и не масштабируется.
На рис. 11.16 клип scaleablejnc представлен светло-серым градиентным фоном,
а прямоугольник с текстом «content» в центре изображает основное содержание
сайта centered me.
: • • " . : • • .
ф ;
" • " " " : ¥ 1
Итоги
Многие Flash-сайты, эмулирующие «операционную систему в окне браузера»,
состоят из одного большого фонового SWF-ролика, всегда полностью закрыва-
ющего окно браузера. Перед ним располагается несколько SWF меньших разме-
ров и не масштабируемых. Аналогичная методика может успешно применяться
и для традиционных сайтов, с заменой векторного фона растровой графикой.
Умеренное масштабирование существенно улучшает восприятие сайта без нару-
шения стиля текстовых Flash-сайтов с мелкими шрифтами. Возможности адап-
тации интерфейса к размеру окну браузера практически не ограничиваются. По
адресу http://www.it2004.jp/index2.html приведен пример сложного интерфейса,
который автоматически изменяет свою конфигурацию в соответствии с измене-
ниями размеров окна. Повышение быстродействия за счет буферизации собы-
тий Stage.onResize с использованием интервальных таймеров описано по адресу
http://chattyfig.figleaf.eom/ezmlm/ezmlm-cgi71:msn:62581:dggpkifkacibblilcmok.
414 Глава 11. Интеграция с браузером
ТРЮК
Создание ссылок HTML в Flash
№93 Ссылки в стиле HTML обычно не включаются в Flash-контент, но, в принципе,
такая возможность существует. Настоящий трюк показывает, как создать
гиперссылку в стиле HTML для управления временной диаграммой Flash.
Средства форматирования CSS, поддерживаемые в Flash MX 2004, позволяют
создавать стандартные ссылки HTML. К сожалению, такие ссылки и работают
стандартно - они выполняют переход к обычным страницам, не входящим в SWF.
На помощь приходит конструкция asfunction, которая позволяет ссылкам управ-
лять SWF из ActionScript.
Прежде всего следует воссоздать внешний облик гиперссылки в Flash, что дела-
ется относительно несложно.
Создайте файл в своем любимом текстовом редакторе (у меня это редактор
SciTE|Flash - см. трюк 74). Введите текст, показанный на рис. 11.17. Сохраните
файл под именем flash.ess.
P{
color: #000000;
font-family: sans-serif;
font-size; Юрх;
color: #O0O0FF;
a:hover{
Ю h text-decoratton: underline;
myHTML_txt.html = true;
myHTML_txt.htmlText = "<p>This is a <a href =
'http://www.oreilly.com'>link</a> to my site.</p>";
myHTML_txt.htmlText += "<p>Click i t and see!</p>";
Создание ссылок HTML в Flash 415
myHTML_txt.html = true:
myHTML_txt.html Text = "<p>This is a<a href =
'asfunction:asLink. 10'>1ink</a> to frame 10.</p>":
myHTML_txt.htmlText +» "<p>Click i t and see!</p>";
stopO:
Итоги
Благодаря тому, что Flash MX 2004 поддерживает HTML и подмножество средств
форматирования CSS, кнопки Flash в пользовательском интерфейсе могут ис-
пользоваться совместно с гиперссылками в стиле HTML. В этом трюке показа-
но, как использовать такие ссылки для перемещения по временной диаграмме
Flash (или просто выполнения кода ActionScript). Конечно, описанный меха-
низм также может использоваться и для построения традиционных гиперссылок
на внешние страницы.
Как известно, текстовые поля Flash теперь могут включать графику и текст в фор-
мате HTML (см. трюк 46), и это повышает практическую ценность данного трю-
ка и позволяет отображать мини-страницы HTML в Flash SWF. Текстовые поля
даже могут содержать другие SWF - довольно интересная альтернатива для
loadMovie() и /oadMovieNum()!
41В Глава 11. Интеграция с браузером
i Page
Basc •Fixed' Botom ; \
Dynamci Page Fixed Botom, Nested Left
Template Page Fixed Bottom, f4ested Rg
ih
Other Fixed Left
CSS Styte Sheets fixed Left, Nested Botom
Framesets • Fixed Left, Nested Top
Page Desgi ns Fixed Right
Page Desgi ns (Accessible) Fixed Right, Nested Bettor
Fixed Right, Nested Top
Fixed Top
Fixed Top., Fixed Botom
fixed Top, Nested Left
fixed Top., Nested Right
Split Horizontal Description:
Split Vertical JA frameset split horizontally with a
jfixed-size botom frame.
</head>
<frameset rows="*.80" frairieborder="NO" border="0" framespacing="O">
<frame src="flash.html" name="mainFrame">
<frame src="one.html" name="bottomFrame" scrolling="NO" noresize>
</frameset>
<noframes><body>
You should really get a more up to date browser before they phase out steam
power.
418 Глава 11. Интеграция с браузером
</body></noframes>
</html>
Переходим к построению скрытых страниц. Создайте пять пустых HTML-фай-
лов с именами one.html, two.html, three.html, four.html и five.html, сохраните их в од-
ной папке с файлом frame.html.
Отредактируйте файл one.html и приведите его к следующему виду (изменения
выделены жирным шрифтом):
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<tit1e>one</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-l">
</head>
<body bgcolor="#FFFFFF">
<script language='JavaScript'>
parent.mainFrame.flash.SetVariableChistory1, 1);
</script>
</body>
</html>
Обратите внимание: тег <title> соответствует конкретному файлу (в данном слу-
чае one), а во втором параметре строки JavaScript указывается параметр, переда-
ваемый SetVariable() - номер файла (1). Мы явно задаем цвет фона страниц
нижнего фрейма, чтобы они не были видны при выборе пользователем другого
набора фоновых цветов.
Внесите аналогичные изменения в четыре оставшихся HTML-файла. Например,
файл five.html должен выглядеть так:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>five</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-l">
</head>
<body bgcolor="#FFFFFF">
<script language='JavaScript'>
parent.mai nFrame.f1 ash.SetVari able('hi story', 5);
</script>
</body>
</html>
Чтобы набор фреймов заработал, остается создать секцию flash.html.
Создайте в Flash новый документ командой File • New. Выполните команду
File • Publish Settings, перейдите на вкладку HTML, выберите в списках Horizontal
и Vertical из группы Flash Alignment значение Center, а в списке Scale - строку No
scale, как это было сделано в трюке 90 (см. рис. 11.8).
Сохраните файл Flash под именем flash.fla в одной папке с сохраненными ранее
HTML-файлами. Выполните публикацию (File • Publish), чтобы создать файлы
flash.html и flash.swf.
Интеграция Flash с кнопкой возврата 419
content page
content.gotoAndStop(I):
}:
b2.onRelease = function О {
f ill BottomC two. html");
content.gotoAndStop(2);
}:
b3.onRelease = functionО {
fillBottomC"three.html");
content. gotoAndStopO):
}:
b4.onRelease - functionO {
fillBottomC"four.html"):
content.gotoAndStop(4);
}:
b5.onRelease = functionO {
fillBottomCfive.html");
content.gotoAndStopC5);
}:
function setHistory() {
i f (history == 1) {
hisEnabied = true:
content.onEnterframe = functionO {
i f (history !- 0) {
this.gotoAndStop(history);
history = 0:
clearlnterval(startHistory):
}
function fillBottom(doc) {
i f (hisEnabled) {
getURLCdoc. "bottomFrame"):
}
var history;
var hisEnabled = false;
startHistory = setlntervaKsetHistory, 500);
content. stopO:
Теперь при щелчке на каждой из кнопок не только Flash переходит к соответ-
ствующему кадру временной диаграммы, но и функция fillBottom() вызывает со-
ответствующую HTML-страницу в нижнем фрейме веб-страницы. Страницы не
видны пользователю, так как они не содержат видимого контента, однако брау-
зер включает их в историю.
Когда пользователь щелкает на кнопках Вперед (Forward) и Назад (Back), браузер
подгружает страницы HTML из истории, а размещенный в.них код JavaScript при-
сваивает переменной Flash history значение от 1 до 5, в зависимости от страницы.
Обработчик onEnterFrame перехватывает изменение и заставляет контент изме-
няться синхронно с изменениями HTML-страницы. Таким образом, история
браузера синхронизируется с передачей управления в Flash-ролике.
Интеграция Flash с кнопкой возврата 421
Итоги
При организации передачи управления кнопками Flash в браузере активизиру-
ются кнопки Вперед (Forward) и Назад (Back). Щелчки на этих кнопках позво-
ляют перемещаться по истории посещаемых страниц.
Отсутствие функциональности возврата считалось одним из главных неудобств
Flash. Как видите, проблема успешно решается!
Конечно, опытные пользователи Flash найдут в этом решении ряд недостатков.
Например, необходимость создания (и сопровождения) пустой HTML-стра-
ницы для каждой страницы Flash выглядит довольно утомительно и противо-
речит одному из главных достоинств Flash-дизайна - отсутствию страничной
ориентации. Резонно спросить: куда должен переходить пользователь при нажа-
тии кнопки возврата в Flash-приложении? В сайтах на базе HTML каждая стра-
ница представляет состояние приложения в конкретный момент времени. Но
в приложениях Flash каждая «сцена» может состоять из нескольких кадров
и содержать анимацию или материалы, занимающие некоторый промежуток
времени. Например, когда пользователь щелкает на кнопке возврата к преды-
дущей сцене, должен ли Flash-дизайнер перемотать и воспроизвести заново ани-
мацию, аудио или видео соответствующей сцены? При выборе страниц, пред-
ставляющих фиксированные моменты времени, следует учитывать состояние
вашего приложения.
Одно из возможных усовершенствований этого трюка - динамическое построение
HTML-страниц в скрытых кадрах средствами JavaScript. В этом случае количество
страниц в истории браузера не является фиксированной величиной, что обеспе-
чивает необходимую гибкость при построении сложных Flash-сайтов.
Взаимодействие JavaScript с Flash поддерживается не всеми браузерами; эта тема
обсуждается по адресу http://www.macromeclia.com/support/flash/ts/documents/
422 Глава 11. Интеграция с браузером
Итоги
Несмотря на столь краткое описание, этот трюк станет одним из тех мелких
штрихов, которые придают профессионализм вашей Flash-презентации. Ког-
да на экране появляется форма, пользователь ожидает, что он может сразу
приступить к вводу и переключаться между текстовыми полями без предвари-
тельного щелчка. Если приложение игнорирует нажатия клавиш, это вызовет
недоумение у пользователя. Данный трюк, как и предыдущий, не работает
в браузерах, не поддерживающих обмен данными JavaScript/Flash (например,
Mozilla).
Клавиши ускоренного вызова 423
ТРЮК
Клавиши ускоренного вызова
№96 Чтобы работа с Flash-приложением стала более быстрой и удобной, свяжите
с каждой кнопкой SWF специальную клавишу или комбинацию клавиш.
Клавиши ускоренного вызова делают сайт более удобным. В настоящем трюке
показано, как реализовать клавиатурные сокращения с минимальным объемом
программного кода. Стоит заметить, что идентификация ввода с клавиатуры не
сводится к простой проверке нажатой клавиши. Необходимо предусмотреть об-
работку комбинаций клавиш (например, Ctrl+Q) и обнаруживать как нажатия,
так и отпускания клавиш.
function down О {
i f (keys [Key. getCodeO] !- undefined) {
keys[Key.getCode()].onRelease();
Selecti on.setFocus(keys[Key.getCodC)]);
}
this.onKeyDown = undefined;
this.onKeyUp = up:
}
function up() {
this.onKeyUp = undefined;
this.onKeyDown = down;
«.А • А
# В • В
• С • С
Рис. 11.22. Кнопки без выделения (слева); кнопка А выделена (справа)
}
function up() {
//traceCup"):
this.onKeyUp = undefined;
this.onKeyDown = down;
}
//
var keys:Array = new ArrayO:
var keyListener:Object = new ObjectO;
keys[0] = {btn:buttonA. combo:[65]};
keys[l] = {btn:buttonB. combo:[Key.CONTROL. 66]};// Ctrl-В
keys[2] = {btn:buttonC. combo:[Key.CONTROL. 68]};// Ctrl-D
buttonA.onRelease = aHandler;
buttonB.onRelease = bHandler;
buttonC.onRelease = cHandler;
keyListener.onKeyDown = down;
Key. addLi stener(keyLi stener);
Я оставил некоторые полезные вызовы trace(), использовавшиеся в процессе
разработки. Если вы хотите увидеть, как и в каком порядке программа обнару-
живает и сбрасывает обработчики событий onKeyDown, onKeyUp и onRelease, убе-
рите комментарии в вызовах traceQ и проанализируйте порядок возникновения
событий на панели Output. Логика программы мгновенно прояснится.
428 Глава 11. Интеграция с браузером
Итоги
Поддержка клавиатурных комбинаций наряду с управлением мышью сделает
сайт более доступным как для пользователей с дефектами зрения, так и для
опытных пользователей с навыками слепой печати. Комбинации клавиш на удив-
ление редко поддерживаются Flash-сайтами - может быть, из-за того, что их
программная реализация относительно нетривиальна. Что же, теперь вы знаете,
как это делается!
ГЛАВА 12
Безопасность
Трюки № 97-100
Пользователь может быстро загрузить исходные файлы сайта иа базе HTML
и просмотреть их без разрешения разработчика. HTML-страница по определе-
нию представляет собой текстовый файл, передаваемый браузеру пользователя
или любому клиенту, от которого поступил запрос. Браузер или программа «за-
качки сайтов» легко загружает любой текст и графику, отображаемые на страни-
це. К сожалению, законы об авторских правах не предоставляют сколько-нибудь
серьезной защиты, особенно за пределами США и Европы, поэтому большин-
ство владельцев сайтов либо допускает возможность копирования контента, либо
пытается принять технологические меры защиты. В простейшем случае разра-
ботчик может включить в изображение визуальную информацию об авторских
правах; пиратам придется по крайней мере стереть этот знак, чтобы замести
следы. Если автор настроен более радикально, он может включить в изображе-
ние невидимый «водяной знак», предотвращающий несанкционированное вос-
произведение. Конечно, все меры «цифровой защиты» могут быть вскрыты, но
здесь мы не будем обсуждать все технические и политические аспекты этой темы.
Двоичный файловый формат SWF не удастся прочитать с такой же легкостью, как
текстовый файл, но особой дополнительной защиты он не обеспечивает. Для его
расшифровки достаточно воспользоваться программой чтения формата SWF, опи-
сание которого находится в открытом доступе по адресу http://www.macromedia.com/
software/flash/open/licensing/fileformat (лицензия выдается бесплатно, но формат
SWF является интеллектуальной собственностью Macromedia, а не обществен-
ным достоянием). Разработчикам, собирающимся писать программы для созда-
ния SWF-файлов, достаточно посетить OpenSWF.org (http://www.openswf.org) - сайт
ресурсов для разработчиков, работающих с форматом SWF.
В настоящее время существует немало декомпиляторов Flash SWF и программ
извлечения контента, включая ActionScript Viewer (http://buraks.com/asv) - пер-
вую программу такого рода, появившуюся на рынке несколько лет назад.
Итак, SWF-файлы уязвимы в той же степени, что и традиционные веб-ресурсы.
Ничто не помешает изобретательному хакеру просмотреть ваши ресурсы и код,
поэтому в файлах SWF не следует хранить конфиденциальную информацию
(например, пароли). И все же задачу хакера стоит по крайней мере усложнить,
потому что многие злоумышленники быстро сдаются, столкнувшись с трудно-
стями, или подыскивают более доступный сайт.
430 Глава 12. Безопасность
ПРИМЕЧАНИЕ
Разработчик Server-Side ActionScript должен настроить конфигурацию веб-сер-
вера так, чтобы файлы .asr не считались простыми текстовыми файлами.
Параметры конфиденциальности
Flash может получать доступ к потокам данных на локальном (клиентском) ком-
пьютере, в том числе и к данным с подключенного микрофона и видеокамеры.
Кроме того, Flash позволяет организовать локальное хранение информации
(см. трюк 44) с использованием класса SharedObject в так называемых объектах
LSO (Local Shared Objects).
Однако возможности получения ввода с микрофона или камеры, подключенной
к компьютеру, а также сохранения данных на жестком диске создают целый ряд
проблем из области конфиденциальности и безопасности. По этой причине Flash
Player должен иметь разрешение пользователя на выполнение любых действий,
способных повредить конфиденциальности. Такие разрешения предоставляются
на доменном уровне в окне Macromedia Flash Player Settings, показанном на рис. 12.1.
14 myMic.onStatus = micPermission:
15 myStatus.text = "Either user will always deny access to the " +
16 "microphone, or user is looking at the Microphone Settings panel " +
17 "and function micPermissionО will soon run.";
18 } else {
19 myStatus.text = "User has already given permission.";
20 }
В строках 10 и 11 создается экземпляр Microphone (хотя Flash позволяет выб-
рать микрофон из списка, лучше воспользоваться приведенным кодом, который
выбирает микрофон по умолчанию).
Flash считает, что микрофон подключен к любому оборудованию, к которому
его можно подключить; в эту категорию входят все звуковые платы, обнаружен-
ные в системе. На большинстве компьютеров микрофон по умолчанию является
единственным подключенным микрофоном!
При обращении к микрофону методом Microphone.get() Flash автоматически от-
крывает окно Settings, если соответствующее разрешение ранее не было предос-
тавлено пользователем. При желании используйте вызов System.showSettings(2)
и откройте окно «вручную» (например, если вы предпочитаете выдать запрос к
пользователю в начале работы приложения, не дожидаясь, пока приложение по-
пытается обратиться к микрофону). Если пользователь ранее разрешил исполь-
зовать микрофон на вашем сайте, то свойство myMic.muted равно false, сценарий
выводит текст «User has already given permission», и микрофон оказывается дос-
тупным для Flash. Если же свойство myMic.muted равно true, то пользователь
либо еще не разрешил использовать микрофон, либо задал параметры конфи-
денциальности таким образом, чтобы доступ к нему с вашего сайта стал невоз-
можным. Если потребуется, Flash вызывает окно Settings, и программа ждет сме-
ны разрешения пользователем.
После закрытия окна Settings вызывается функция micPermission, и дальнейшая
работа программы зависит от значения свойства muted (true или false). Но если
пользователь уже запретил доступ к микрофону при предыдущем посещении
вашего сайта, то разрешение не дается и функция micPermission() не выполняется,
поскольку состояние остается неизменным. Программа завершается с выводом
сообщения в строках 15-17. В принципе, вы можете потребовать у пользователя
необходимое разрешение, вызвав окно Settings методом System.showSettings(2),
но лучше кратко объяснить, почему ничего не происходит, и затем предоставить
пользователю самому выбрать курс дальнейших действий.
Междоменная политика
Фирма Macromedia определила систему жестких правил (в терминологии Macro-
media - изолированная среда), управляющих взаимодействием SWF-файлов друг
с другом, а также исполняемыми файлами в Веб или на локальном жестком дис-
ке. Многие из этих правил в Flash Player 7 были ужесточены по сравнению
с предыдущими версиями (и многими другими веб-технологиями). Некоторые
сайты, нормально работающие в Flash Player 6, отказываются работать в Flash
Player 7 из-за дополнительных ограничений безопасности; за дополнительной
434 Глава 12. Безопасность
П
ПРИМЕЧАНИЕ
Если при сохранении SWF-файла не был установлен флажок Protect from Import
(File • Publish Settings • Flash), файл можно открыть прямо в среде Flash. Это
хорошо для тех, кто пытается восстановить потерянный контент, и плохо для
тех, кто пытается скрыть свой контент от других (см. трюк 98).
\Docunwnts and
function soundtrack () {
soundtrack_snd. attachS ound(nextLoop); Property [Value
soundtrack snd.start(0,1);
} Timeisec.) 0.00
start_btn.onFielease = function () { | Has frame actions; yes
playQ; I Has clip actions no
Has start sound i no
soundtrack_snd = new Sound (this); Has sound strea... yes
nextLoop = "tracki"; Has sound strea... no
soundtrackQ;
soundtrack_snd.onSoundComplete = soundtrack;
gameScore = 0;
flash = new Color (back);
Извлечение ActionScript
Чтобы просмотреть весь код ActionScript, содержащийся в SWF, перейдите на
вкладку ActionScripts (рис. 12.3) и выделите любой из сценариев, перечисленных
на панели. Код отображается в левом нижнем углу. Чтобы сохранить сценарий
в виде текстового файла, выполните команду Utility • Save ActionScript (as Text).
Если окно Flash открыто в настоящий момент, код ActionScript также можно
скопировать из ASV в буфер и вставить в открытый документ FLA.
n l M M J L J
function soundtrack () {
soundtrack_snd. attachS ound(nextLoop);
souridtrack_snd.r.^""'""'*A
} i Щ\ Copy Actionscript (as Text) FS
start_btn.onReleasi
у ' UFj Change Actionsaript Font
soundtrack_snd - ij |jp show Long Actronscripts Ctrl-КЗ
»un*acku- ' a C i I I W o r d w a * > Actionscripts Ctrl +W
soundtrack_snd.orH||j Colorize Actionscripte Ctrl+Alt+Z
fff^JtshowA^ons.a.P-code FH
1- Force Flash 5 Mode FS
s \ S h e u n B V
3-е 4J
Щм
A3
Proper^ value
Swf version 6
Width 480
Heg i ht : 300
Fiarnerate : 18
Frame count 1 5
atwwwwwwwww^
Рис. 12.4. Вкладка Timeline в окне ActionScript Viewer 3.0
Экспортирование библиотеки
Чтобы экспортировать библиотеку, перейдите в ASV на вкладку Library (рис. 12.5),
щелкните правой кнопкой мыши (Windows) или щелкните с нажатой клавишей
J§ (Mac) на любом символе и выберите в контекстном меню команду Save all
Library Symbols as SWF.
Символы SWF импортируются в Flash командой File • Import • Import to Library.
После импортирования символам следует присвоить осмысленные имена и вруч-
ную определить для них идентификаторы компоновки (которые не экспортиру-
ются из ASV, хотя и отображаются в квадратных скобках на вкладке ASV Library
рядом с каждым именем символа).
440 Глава 12. Безопасность
Итоги
Хотя для больших или сложных SWF процесс декомпиляции занимает много
времени, это все равно быстрее, чем начинать нуля. Вам удастся восстановить из
SWF два самых важных ресурса: ActionScript и символы библиотеки. Даже если
ничего больше извлечь не удастся, все равно достигается существенная эконо-
мия времени.
Также декомпиляция SWF применяется для определения точной структуры SWF
и проверки оптимальности размера файла. Более того, декомпиляция поможет
лучше понять общие принципы работы контента Flash и осознать, какие именно
данные использует Flash Player.
Конечно, декомпиляция также позволяет красть ваш контент или (что более
вероятно) тайком заимствовать творческие идеи.
Открытие SWF в декомпиляторе или редакторе кода (таком, как URL Action
Editor - http://buraks.com/uae) дает злоумышленнику еще больше шансов для
похищения вашей работы, чем при использовании обычных технологий HTML:
• Flash SWF содержат большую часть контента вашего сайта в минимальном
количестве файлов, а это упрощает поиски;
• создание мультимедийных ресурсов обычно обходится дороже, чем создание
статических веб-страниц. Для создания аудио/видео, графики и сценари-
ев, содержащихся в вашем Flash-творении, необходимы более богатые спо-
собности, чем для создания HTML-страниц, состоящих из простой графики
и текста;
Защита и шифрование файлов Flash 441
Защита SWF
Среда разработки Flash позволяет любому желающему загрузить незащищен-
ный SWF-файл. Вообще говоря, SWF можно защитить от импортирования в Flash,
установив флажок Protect from Import (File • Publish Settings • Flash). Тем не менее,
файл может быть открыт в другом приложении (например, в текстовом редакторе),
442 Глава 12. Безопасность
ПРИМЕЧАНИЕ
При использовании этого трюка храните информацию о настоящем типе каждо-
го файла. Храните «фальшивые» файлы для размещения на сайте отдельно от
файлов, задействованных в разработке. Не забудьте выработать политику ар-
хивирования, потому что однажды защита может обернуться против вас, если
вам потребуется декомпилировать SWF.
Итоги
Нет ничего плохого в том, что кто-то будет черпать вдохновение в вашей работе.
Даже если вас это не устраивает, у вас нет никаких юридических и практических
средств помешать этому. Вы можете запатентовать свое выражение идеи, но не
саму идею. Большинство идей имеет слишком общий характер, чтобы стать объек-
тном патентной защиты, а оформление патента требует слишком больших зат-
рат времени и средств. Наконец, во многих случаях даже патент не обеспечит
реальной защиты. Малоизвестная разновидность патентов (так называемые ди-
зайнерские патенты) защищают дизайнерские решения - скажем, форму и по-
лупрозрачность корпуса исходного варианта iMacs. Но даже юридический отдел
Apple не смог помешать производителям PC имитировать дизайн продукта.
444 Глава 12. Безопасность
// Бесконечный цикл
} while (true);
}
При такой защите хакеру будет труднее разобраться в том, что делает SWF.
Чтобы происходящее стало еще более непонятным, добавьте длинные задержки,
при которых диалоговое окно с предупреждением не выдается, но создастся ил-
люзия «зависания» SWF. В следующем листинге функция задержки будет вы-
полняться каждую миллисекунду:
myLocation = this._url:
i f (myLocation != "http://www.futuremedia.org.uk/test/test.swf") {
II Вызывать функцию задержки каждую миллисекунду
setlnterval (delayMe. 1);
}
function delayMeО {
// Выполнить 10 000 итераций просто для замедления работы Player
for (var i = 0; i < 10000: i++) {
x = Math.randomO;
Перекрестная защита
Хакеру гораздо проще работать с одним файлом, чем разбираться с сайтом, раз-
деленным на несколько SWF, - особенно если вы также присвоите фиктивные
имена некоторым из SWF (см. трюк 98) и привяжете их к конкретному серверу.
Также попробуйте разместить код защиты в другом SWF, отличном от защища-
емого (я называю это перекрестной защитой). Например, включите следующий
код в SWF, загружаемый главным SWF:
myLocation = levelO._url;
i f (myLocation != "http://www.futuremedia.org.uk/test/test.swf") {
do {
} while (true):
}
Попробуйте разместить логику защиты в постороннем SWF, не представляю-
щем интереса для хакера. Например, включите ее в SWF-файл с контентом вме-
сто основного SWF-файла с фирменным пользовательским интерфейсом, чтобы
защиту было труднее найти.
Запускайте код защиты по интервальному таймеру, установленному функцией
setlntervalQ (вместо того чтобы запускать его сразу же после загрузки SWF).
Хакеру будет труднее найти этот код, потому что он не сразу поймет, какой из
загруженных SWF содержит код защиты. Пример:
function test О {
clearlnterval(m);
var myLocation:String = JevelO._url;
i f (myLocation != "http://www.futuremedia.org.uk/test/test.swf") {
do {
} while (true):
Итоги
Сразу же после появления декомпиляторов SWF появился целый поток сайтов-
двойников и примеров FLA, подозрительно напоминавших ранее не публико-
вавшийся код. Примите необходимые меры, чтобы ваша работа не попала в по-
сторонние руки!
Разработчики Flash часто спрашивают, как защититься от клиентов, которые
«забывают» заплатить после получения всех материалов по контракту. Один из
стандартных способов - удержание исходных FLA-файлов до получения опла-
ты (клиент получает SWF для размещения на сайте, но и разработчик получает
частичную страховку). Обычный трюк с проверкой местоположения в таких си-
туациях не применим, потому что SWF будет запускаться с клиентского сайта,
но вы можете разместить XML-файл на удаленном сервере, находящемся иод
Просмотр откомпилированного кода ActionScript 447
№100 ActionScript
Анализ откомпилированного кода способствует низкоуровневой оптими-
зации и разработке общего стиля кодирования, направленного на опти-
мизацию.
Декомпилятор SWF восстанавливает исходный код ActionScript (см. трюк 97)
на основании байт-кода в SWF.
Декомпиляторы SWF помогают восстановить (или украсть!) исходный код
ActionScript, но в некоторых ситуациях - например, при оптимизации кода по
скорости или размеру - требуется просмотреть откомпилированный байт-код.
Утилита Flasm, распространяемая с открытыми исходными текстами (http://
flasm.sourceforge.net), предназначена для просмотра байт-кода, полученного в ре-
зультате компиляции ActionScript.
Не путайте Flasm с декомпиляторами, это совершенно разные программы. Flash
предназначается для настоящего эксперта ActionScript, желающего оптимизиро-
вать свой код. Кроме того, эта программа поможет узнать, как выглядит ваш код
к тому моменту, когда он попадает в Flash Player. В документации Flasm доста-
точно подробно описан процесс обработки откомпилированного кода ActionScript
виртуальной машиной Flash в Flash Player; полагаю, читатель найдет этот мате-
риал как интересным, так и поучительным.
Последняя версия Flasm (версия 1.51) поддерживает формат Flash MX 2004.
Полезно сравнить методику оптимизации кода Flash Player 7 по сравнению с Flash
Player 6 (если, конечно, этот код работает быстрее предыдущей версии) - это
поможет вам писать хорошо оптимизируемый код. Flasm - не экзотическая ди-
ковинка для хакеров, а действительно полезный инструмент.
Flasm
Flasm работает в режиме командной строки, поэтому вам придется либо исполь-
зовать режим командной строки (Windows), либо открыть окно терминала (Мае).
Шариф Айна (Shariff Aina) написал пользовательский интерфейс для Windows,
который называется WinFlasm; его текущий URL можно найти в документации
Flasm или на сайте http://flasm.sourceforge.net. Для простоты мы будем исполь-
зовать его в данном трюке.
Чтобы установить Flasm, загрузите ZIP-файл и распакуйте его в каталог по сво-
ему выбору. WinFlasm распаковывается из архива в один каталог с Flasm. К со-
жалению, пользователям Мае придется работать в режиме командной строки.
Документация Flasm содержит более подробные инструкции об интеграции Flasm
в среду разработки Flash. Эта информация пригодится разработчикам, интере-
сующимся созданием высокооптимизированного кода.
После компиляции SWF-файла в среде разработки Flash запустите WinFlasm и
откройте SWF-файл для просмотра Командой Open.
Выберите операцию при помощи переключателей на нижней панели (рис. 12.6).
Open About
j Execute .;
secMensbsr
push riS, "сп£.е1еазе'
function2 () (ril^'this1)
push 0.0, r:this, 'stcpDrag'
callMethod
pop
pasis r:tfcis, ' oisHouaeMove •
delete
pop
end // of function
secMensber
push r:2
return ii
end // of function drawPip
functicn2 drawCurve (r:3='pointi', r:2»'point2', r:4=•curvePoinc'
push 0.0> r:thia, 'clear*
callMethod
pep
push 102, 14530253, 1, 3, r:chia, 'lineStyle'
callKetfcod
pep
push r:poi nt1, " у'
gecMensber
push rrpointl, "jt1
geeMeraber
push 2, r:this, 'rooveTo'
cellMethod
ж
Рис. 12.7. Откомпилированный файл ActionScript в WordPad
Работа с Flasm
Рассмотрим пример использования Flasm для получения эффективного кода с мо-
дульной структурой. Однажды мне захотелось узнать, как применение функций
отражается на общем быстродействии. Хотя вызовы функций улучшают струк-
туру программы, у меня были некоторые сомнения относительно целесообраз-
ности их применения в участках кода, критических по быстродействию, - здра-
вый смысл подсказывал, что вызов функции сам по себе требует дополнительного
времени. Так или иначе, я решил, что эту тему стоит поподробнее исследовать
в Flasm.
Возьмем фрагмент кода без вызова функций:
var х = 5:
var у = 6:
var z = х*у;
trace(z);
Flasm выдает следующий байт-код Flash Player 7:
frame 0
constants 'x', 'у', 'z'
push 'x', 5
varEquals
push 'y'. 6
varEquals
push 'z', 'x'
getVariable
push 'y'
getVariable
multiply
varEquals
push 'z'
getVariable
trace
end //of frame 0
При использовании системы типизации ActionScript 2.0:
var x:Number = 5;
var у:Number = 6:
var z:Number = x*y;
trace(z):
результат был бы точно таким же. Из этого можно сделать вывод, что типизация
не приводит к снижению быстродействия или увеличению размера файла (и это
вполне логично, поскольку проверка типов осуществляется на стадии компиля-
ции, а не во время выполнения). На моем компьютере обе версии, типизирован-
ная и нетипизированная, выполнялись примерно в течение 0,06 мс (без команды
trace(), поскольку операции вывода обычно выполняются довольно медленно).
Просмотр откомпилированного кода ActionScript • 451
push 'x'. 5
varEquals
push 'y'. 6
varEquals
push 'z'. 'y'
getVariable
push 'x'. 5
getVariable
push 2. 'multiply'
call Function
push 'z'
getVariable
trace
end / / o f frame 0
Если в программе применяется функция с аргументами, Flash Player использует
более эффективные прямые обращения к регистрам вместо ячеек памяти (со-
держимое которых перед использованием все равно приходится заносить в реги-
стры или в стек). Это весьма интересное открытие наводит на мысль, что
Macromedia развивает ActionScript в направлении более структурированного
стиля программирования, для которого характерны функции, ссылки и парамет-
ры, а не отдельные переменные.
Эксперименты показывают, что время вызова функции компенсируется увели-
чением объема кода в каждой функции; написание логичного, модульного кода
способствует повышению быстродействия во многих приложениях.
Итак, оптимизации Flash Player 7, о которых говорит Macromedia, в наибольшей
степени проявляются при использовании объектно-ориентированного стиля про-
граммирования, элементы которого появились в ActionScript 2.O.
Просмотр откомпилированного кода ActionScript 453
Если попробовать повторить эти примеры в Flash Player 6 (Flash MX), результат
будет иным. Исключение составляет разве что Flash Player 6r65 (флажок Optimize
for Flash Player 6r65 на вкладке File • Publish Settings • Flash), который ведет себя
почти так же, как Flash Player 7 (наверное, потому что он, фактически, представ-
ляет собой Flash Player 7 без новых классов ActionScript, добавленных в Flash
MX 2004). При просмотре в Flasm кода старых версий Flash Player становится
очевидно, что оптимизации Flash Player 7 и Flash Player 6r65 связаны в основ-
ном с эффективным использованием регистров и стека.
Но чтобы извлечь пользу из этих оптимизаций, необходимо активно применять
такие возможности, как передача аргументов функциям, объявление локальных
переменных и передача целевого объекта в аргументе вместо обращения к нему
через свойство this.
Также стоит провести серию тестов для выявления различий между объявлениями
классов ActionScript 2.0 и наследованием на базе прототипов в ActionScript 1.0.
Небольшая подсказка: жесткая типизация ActionScript 2.0 реализуется на ста-
дии компиляции и не влияет на быстродействие, а в ООП с применением клас-
сов используются четко определенные функции и локальные данные (что спо-
собствует оптимизацию байт-кода за счет использования регистров вместо
памяти). Это означает, что для кода ActionScript 2.0, использующего классы,
генерируется высокооптимизированный байт-код; то же можно сказать о любом
структурном стиле программирования, использующем функции и локализацию
данных в функциях и аргументах.
Итоги
Программа Flasm полезна прежде всего тем, что она показывает, во что превра-
щается код ActionScript в итоговом SWF. На первый взгляд разобраться в лис-
тингах непросто, но вы довольно быстро освоите псевдоассемблер Flash Player,
если начнете с коротких простых сценариев, как это было сделано в предыду-
щих примерах.
Кроме того, Flasm помогает выявлять узкие места ActionScript. Учтите, что в гра-
фических приложениях критическим для быстродействия фактором часто явля-
ется механизм визуализации (см. трюк 68), а не байт-код.
Конечно, столь краткое описание дает крайне поверхностное представление
о Flasm и оптимизации кода. Если вы принадлежите к числу опытных програм-
мистов ActionScript, с Flasm определенно стоит познакомиться поближе - по-
лученная вами бесценная информация о среде Flash Player поможет выжать еще
немного быстродействия из ваших SWF.
Алфавитный указатель
н метод, 354
MovieClip.setMask(), метод, 28
HTML MP3, 266
импортирование формул, 219
HTTPS, протокол, 430
onEnterFrame, обработчик, 48, 139, 172
J
onMouseMove, обработчик, 139,
JSFL (Flash JavaScript), 290 173, 190
onPress, обработчик, 191
onRelease, обработчик, 191
KoolMoves, пакет, 146 onReleaseOutside, обработчик, 191
onSoundComplete, метод, 253
L
OpenSWF.org, 429
LiveDocs, 342 Output, панель, 401
456 Алфавитный указатель
s A
н
зернистость, эффект, 39 Найквиста, теорема, 280
недействительные экземпляры, 366
имитация
броска, 190 объекты, клонирование, 352
гравитация и трение, 186 ООП
зернистости, 39 ActionScript 2.0, 75
интеграция с браузером, 386 имена переменных, 75
интерактивное тестирование, 291 оптимизация, 306
время загрузки, 308
К интервальная проверка, 375
кадрированная анимация, 149 поразрядный сдвиг, 377
ключевые кадры, 151 размер файла, 306
кнопочные клипы, 298 субъективная, 308
колоризация, 39 хронометраж, 320
компоненты, 335 остаток, оператор, 374
458 Алфавитный указатель
отладка
trace(), 365 тайм-аут, 357
детализация вывода, 367 твипы, 377
оцифровка, 275 текст, 203
ошибка дискретизации, 275 HTML,
п форматирование, 221
разбиение, 248
панорамирование, 174 сглаживание, 316
потоковый звук, 264 тестирование сайта
браузеры, 389
модули Flash, 397
разбиение текста, 248 трассировка, 365
растровая графика трение, имитация, 186
размывка краев, 119 трехмерная анимация
растровые шрифты, 316 имитация, 169
расширяемость, 290 поддержка, 168
регистр символов
ActionScript 2.0, 341
рекурсия, 96 ускорение, 187
X
свойства экземпляра, 74 хронометраж, 320
сглаживание, 119, 313
сепия, 81 ц
Flash и Photoshop, 81 цветовые схемы, 76
сжатие FLA, 309 цветовые эффекты, 62
симметрия, 129 альфа-канал, 71
синхронизация речи, 259 сепия, 81
системные шрифты, 204 цикл ходьбы, 142
сложные маски, 112 циклы, эффективность, 362
слои, 159
статические свойства, 74 ч
стек, 449 частицы, эффект, 161
Алфавитный указатель 459
ш э
шрифты, 204 Эшер, М. К., 103
анимация текста, 204
внедрение, 238
повороты, 204 якорные ссылки, 416
системные, 238
шум дискретизации, 275
Шам Бхангал
Flash. Трюки
100 советов и рекомендаций профессионала
Перевел с английского Е. Матвеев
Главный редактор Е. Строганова
Заведующий редакцией А. Кривцов
Руководитель проекта А. Пасечник
Научный редактор Е. Матвеев
Технический редактор В. Шендерова
Литературный редактор А. Пасечник
Художник Е. Дьяченко
Корректор А. Моносов, Н. Рощина
Верстка Л. Родионова
НЗПЛТЕПЬСКПП ПОМ
Вы можете заказать бесплатный
журнал «Клуб Профессионал»
VtfWW-PITER.
'JO® СПЕЦИАЛИСТАМ
КНИЖНОГО БИЗНЕСА!
WWW.PITER.COM
РОССИЯ
Москва м. «Калужская», ул. Бутлерова, д. 176, офис 207, 240; тел./факс (095) 777-54-67;
e-mail: sales@piter.msk.ru
Санкт-Петербург м. «Выборгская», Б. Сампсониевский пр., д. 29а;
тел. (812) 103-73-73, факс (812) 103-73-83; e-mail: sales@piter.com
Воронеж ул. 25 января, д. 4; тел. (0732) 39-61 -70;
e-mail: piter-vrn@vmail.ru; piterv@comch.ru
Екатеринбург ул. 8 Марта, д. 2676; тел./факс (343) 225-39-94, 225-40-20;
e-mail: piter-ural@isnet.ru
Нижний Новгород ул. Совхозная, д. 13; тел. (8312) 41 -27-31;
e-mail: piter@infonet.nnov.ru
Новосибирск ул. Немировича-Данченко, д. 104, офис 502;
тел./факс (3832) 54-13-09,47-92-93,11-27-18,11-93-18; e-mail: piter-sib@risp.ru
Ростов-на-Дону ул. Ульяновская, д. 26; тел. (8632) 69-91 -22;
e-mail: jupiter@rost.ru
Самара ул. Новосадовая, д. 4; тел. (8462) 37-06-07; e-mail: piter-volga@sama.ru
УКРАИНА
Харьков ул. Суздальские ряды, д. 12, офис 10-11; тел. (057) 751 -10-02, (0572) 58-41 -45,
тел./факс (057) 712-27-05; e-mail: piter@kharkov.piter.com
Киев пр. Красных Казаков, д. 6, корп. 1; тел./факс (044) 490-35-68,490-35-69;
e-mail: office@piter-press.kiev.ua
БЕЛАРУСЬ
Минск ул. Бобруйская, д. 21, офис 3; тел./факс (37517) 226-19-53;
e-mail: office@minsk.piter.com
Башкортостан
Уфа, «Азия», ул. Зенцова, д. 70 (оптовая продажа),
маг. «Оазис», ул. Чернышевского, д. 88,
тел./факс (3472) 50-39-00. Красноярск, «Книжный мир»,
E-mail: asiaufa@ufanet.ru тел./факс (3912) 27-39-71.
E-mail: book-world@public.krasnet.ru
Дальний Восток
Владивосток, «Приморский торговый дом книги», Нижневартовск, «Дом книги»,
тел./факс (4232) 23-82-12. тел. (3466) 23-27-14, факс 23-59-50.
E-mail: bookbase@mail.primorye.ru E-mail: book@nvartovsk.wsnet.ru