Как мы уже не раз
говорили, эта книга предназначена для программистов,
участвующих в большом Флэш-проекте. Однако все большие
проекты отличаются тем, что необходимо прикладывать
много усилий для поддержания порядка в них. Обычно
требуется заводить центральное хранилище исходных файлов,
принимать меры к повторному использованию кода, грамотно
применять статическую и динамическую линковку, иметь
средства для автоматической сборки версий и т.д. Удастся
ли навести подобный порядок во Флэш-проекте и может ли
Flash МХ предоставить для этого необходимые средства?
Этому вопросу и посвящена данная лекция. И начнем мы с
возможностей повторного использования кода.
Механизм author time
sharing
Повторное
использование кода - это первое, зачем в большом
Флэш-проекте нужен программист. То есть, ряд компонентов
должен быть написан заранее и использоваться всеми
участниками проекта. Здесь обычно не возникает вопросов
до тех пор, пока в компонентах не возникает ошибок. А
вот дальше начинаются мучения. Несчастный программист
рассылает всем письмо: "Вот в таком-то файле лежит
исправленный компонент (или просто клип), откройте его и
перетащите в разрабатываемый вами модуль". А несчастный
дизайнер, который по пять раз на дню проделывает эту
операцию, кроет программиста последними словами. Или же
забывает (забивает?) сию операцию проделывать. А потом
через три дня снова кроет программиста, за то, что "ничего
не работает". Знакомая ситуация? Совсем другое дело,
когда в каком-нибудь Java или C++ проекте можно указать,
где лежит библиотечный исходный файл. И когда
разработчик библиотеки этот
файл подменяет, никто ничего не замечает, просто после
перекомпиляции все вдруг заработало (или наоборот,
перестало, но тут уж не принцип повторного использования
кода виноват). Итак, нам нужна возможность компилировать
Флэш-анимацию из нескольких кусков, лежащих в разных
файлах: один кусок правит дизайнер, делающий свой
модуль, другой - разработчик
библиотеки.
Что происходит при
author time sharing
Author time sharing -
это такое средство повторного использования кода, при
котором во флэш-ролике, являющемся "клиентом"
author time sharing,
хранятся не сами символы (клипы, компоненты), а,
фактически, ссылки на них; сами же символы лежат в
другом файле. При компиляции происходит встраивание в
собираемый *.swf-файл символов, на которые указывают
ссылки. Теперь мы повторим то же самое на языке, более
адекватном интерфейсу Флэш МХ.
Итак, если для символа
библиотеки ролика (author
time sharing можно включать/выключать на уровне
каждого символа) включен author
time sharing (ниже мы остановимся подробнее на
том, как это сделать), то во время компиляции ролика
этот символ фактически заменяется указанным символом
(чаще всего с таким же именем) из
библиотеки другого (указанного) файла. Заменяется
полностью весь символ: графическая часть, код,
размещенный в любых кадрах, а также настройки символа
библиотеки.
Если в символ
вставлены экземпляры других символов, они тоже
"высасываются" из внешнего файла (не зависимо от того,
установлен ли непосредственно для них режим
author time sharing).
Обратите внимание:
если у вас в каком-нибудь клипе, который вы хотите
подменять с помощью author time
sharing, используется
attachMovie, помните, что те символы, которые вы
создаете с помощью attachMovie,
не будут заменены автоматически. Можно для каждого из
них настроить author time sharing
отдельно, но это не самый лучший способ, есть более
изящный и безопасный. Сделайте в клипе, для которого вы
настраиваете author time sharing,
отдельный слой типа "guide" (чтобы это никак не
повлияло на работу) и положите в него по одному
экземпляру каждого клипа, которые вы создаете с помощью
attachMovie в данном
клипе. Тогда они всегда будут импортироваться вместе с
главным клипом.
В каком-то смысле
механизм author time sharing
похож на использование уже упоминавшейся директивы
#include, за исключением
того, что #include
позволяет загрузить только кусок кода ActionScript, а с
помощью author time sharing
можно заменить компонент целиком (см. также раздел
"Использование #include"
этой же лекции).
Как включить и
выключить author time sharing
Сразу хочется
заметить, что термин author time
sharing не является достаточно стандартным (в
отличие, например, от термина
runtime sharing). Вы не найдете его в среде
разработки Флэш МХ. Последняя оперирует термином
"источник" (source), соответствующие параметры
настраиваются в одноименной области свойств символа
библиотеки (если вы не
видите этой области, нажмите кнопку Advanced).
Итак, что можно
сделать с помощью этой области source:
- заменить
имеющийся в библиотеке
символ на символ из другой
библиотеки. Для этого нужно нажать на кнопку
Browse, выбрать файл с роликом, после чего из
его библиотеки выбрать
символ, на который заменится символ из локальной
библиотеки (этого же
результата можно достигнуть, если открыть две
библиотеки и перетащить
символ из одной библиотеки
в другую). Это одноразовая замена символа;
- собственно
включить author time sharing.
Для этого нужно включить флажок "Always update
before publishing" (если соответствующий чекбокс
disabled, это значит,
что Флэш не знает никакого другого "источника" для
данного символа, кроме его локальной библиотечной
копии (нажав кнопку Browse, можно указать
этот источник). Вот теперь замена символа будет
производиться при каждой компиляции ролика.
Возможные проблемы
В целом механизм
author time sharing
работает довольно хорошо и стабильно, но все же авторы
нашли парочку проблем, которые могут проявиться.
Первая проблема
связана с использованием "многозвенного"
author time sharing, то
есть когда символ А
содержит в себе символ B,
при этом символ А во всех
флэш-роликах обновляется из файла
А, а символ B во
всех флэш-роликах (в том числе в файле
А) обновляется из файла
B.
При наличии такой
конфигурации author time sharing
Flash MX не сможет нормально компилировать флэш-ролики,
в которых используется символ A,
он "падает" каждый раз с ошибкой "Pure virtual function
call". Если вы непременно хотите использовать именно
такой способ работы, то из этой ситуации есть выход,
который, правда, носит немного "хакерский" характер:
нужно отключить author time
sharing либо для всего компонента, либо для
группирующего символа во флэш-ролике, после чего
скомпилировать его, а затем можно будет заново включить
author time sharing. Но, в
целом, авторы не рекомендуют такой способ работы
(использование "двухуровневого" author time sharing1)).
Вторая проблема
связана с тем, что при обновлении author time shared
символов, которые лежат в подпапках
библиотеки, зачастую
создаются лишние подпапки в
библиотеке "клиентского" ролика. Например, если
правильная папка называется core,
то возможно создание папок core
copy, core copy (1),
core copy (2) и т. п.,
причем при каждой следующей компиляции создается новая
папка.
Это может вылиться в
раздувание файлов, и, кроме того, привести к
использованию неправильных версий символов. Как решить
эту проблему нормальным способом - неизвестно.
Единственное, что можно предложить - это не использовать
папки в библиотечном файле, то есть рекомендуется
складывать компоненты прямо в корневую папку
библиотеки ролика. В
клиентском же файле, например, в
шаблоне (см. далее в этой лекции), можно класть
эти компоненты в папки.
Механизм runtime
sharing
Аналогов
runtime sharing в
традиционных средах разработки проектов (Java, C/C++)
можно найти много (например, так работают
библиотеки DLL, загрузчики
классов Java и т. п.). Самым правильным определением
runtime sharing во Flash MX
будет, наверное, динамическая линковка. То есть,
повторно используемые компоненты загружаются уже после
запуска клиентского приложения (флэш-плеера).
Преимущества данного
подхода очевидны: не нужно перекомпилировать ролик для
того, чтобы обновить некоторые библиотечные компоненты,
вы просто заменяете один или несколько библиотечных
*.swf-файлов, и все работает. Данный подход обладает
теми преимуществами перед альтернативными (например,
использование loadMovie),
что всю работу по загрузке внешнего кода берет на себя
флэш-плеер.
Иногда без этого даже
нельзя обойтись, например, в тех случаях, если вы
хотите, чтобы ваши флэш-ролики поддерживали сменные
скины, и при этом используете разработанные не вами
контролы пользовательского интерфейса, которые скины не
поддерживают. В таком случае вы можете просто настроить
для всех символов-элементов скинов
runtime sharing из отдельного *.swf-файла, и
подкладывать *.swf с нужным скином.
Что происходит при
runtime sharing
Во Flash MX
runtime sharing может быть
настроен для любого символа
библиотеки, причем должно быть жестко задано имя
*.swf-файла (это может быть абсолютный или относительный
путь, см. также раздел "возможные проблемы"), из
которого данный символ будет загружаться. После
установки этой галочки Флэш МХ берет на себя всю
ответственность за загрузку символов из внешнего
*.swf-файла, и вы уже почти никак (см. раздел "возможные
проблемы") не можете повлиять на этот процесс. Вы не
можете узнать, в каком порядке загружаются *.swf, какая
часть *.swf загружена, сколько еще осталось и т. п. Это
означает, что вы, например, не можете создать нормальный
загрузчик своих флэш-роликов, который показывает
"честные" проценты, если вы используете
runtime sharing. Иногда это
может также привести к неудобствам синхронизации
выполнения кода (см. раздел "возможные проблемы").
Как включить и
выключить runtime sharing
Управление параметрами
runtime sharing
производится в области Linkage свойств символа
(можно просто выбрать Linkage из контекстного
меню символа, это то же самое).
Итак, вам нужно задать
идентификатор (тот же самый идентификатор, что нужен для
использования символа из ActionScript), поставить одну
из двух галочек (Export for runtime sharing,
Import for runtime sharing) и заполнить поле URL
именем *.swf-файла, из которого будет производиться
импорт символа.
Удобно настроить эти
параметры для экпорта, в том числе URL, в библиотечном
файле, а из него просто перетаскивать библиотечные
символы в клиентские флэш-ролики. Тогда в последних
останется правильно заполненным поле URL, а галочка
Export for runtime sharing автоматически превратится
в галочку Import for runtime sharing.
Во Flash MX больше
нигде (кроме вышеописанного места) нельзя настроить
что-то, относящееся runtime
sharing.
Из ActionScript тоже
нет никакой возможности управлять настройками
runtime sharing, и это
очень неудобно.
Если совершенно
необходимо держать под контролем то, что происходит при
динамической загрузке повторно используемых компонентов,
лучше отказаться от употребления
runtime sharing и рассмотреть вариант с
использованием loadMovie.
Возможные проблемы
Обсудим детальнее,
какие неприятности могут вас ожидать при использовании
runtime sharing.
- URL файла, из
которого подгружаются библиотечные символы, жестко
прописывается в параметрах символов
библиотеки для каждого
экспортируемого/импортируемого символа. Это
означает, что впоследствии изменить этот URL будет
довольно сложно (см. раздел про замену путей
runtime sharing с
помощью author time sharing,
а также раздел "Изменение текущей директории"
(атрибут BASE) из
следующей лекции).
- Забудьте о
нормальном загрузчике с "честными" процентами, если
вы используете runtime sharing.
Вы просто ничего не сможете узнать о процессе
загрузки.
- Для каждой
флэш-платформы (имеется в виду OS + Browser)
существует один "стандартный" способ задания
библиотечного файла в поле URL. К счастью, для
большинства платформ эти способы одинаковы и
выглядят так: <имя файла>.swf. Есть и исключения,
например, для Internet Explorer на MacOS это
file:///<полный путь к *.swf-файлу>.
Если вы укажете URL к
*.swf-файлу "нестандартным" для данной платформы
способом, то при каждом использовании импортируемых
символов флэш-плеер будет загружать их в память
заново (по предположениям авторов, флэш-плеер
сравнивает путь, прописанный в поле URL, c путем,
возвращенным ему платформой, и загружает символ
повторно, если пути не совпадают с точностью до
символа)! Поэтому ничего не стоит написать
флэш-ролик, который через 5 минут своей работы съест
всю свободную оперативную память. С этим нужно быть
очень аккуратным.
Вы спросите: "А
как же написать флэш-ролик, работающий корректно в
ситуациях с разными флэш-платформами" (в том смысле,
что у них разные "стандартные" способы записи URL)?
Авторам известен только один способ: нужно полностью
динамически сгенерировать все содержимое тегов
<OBJECT> и
<EMBED> с помощью
JavaScript, в котором выясняется тип браузера и, в
зависимости от типа браузера, подставить нужное
значение атрибута BASE
тегам <OBJECT> и
<EMBED> (см. также
раздел "Изменение текущей директории" (атрибут
BASE) из следующей
лекции).
- "Многозвенный" (multi-tier)
runtime sharing. Это
такой вид runtime sharing,
когда клип А
загружается из файла А.swf,
а в клипе А лежит клип
B, который загружается
из файла B.swf и так
далее. Во флэш-плеере до версии 6.0.65.0 была
довольно условная поддержка этой функциональности,
что выражалось в падениях флэш-плеера вместе с
браузером (правда, Macromedia и не обещала, что это
будет работать). Начиная с версии 6.0.65.0 во
флэш-плеере официально добавлена поддержка
"многозвенного" runtime
sharing.
runtime-загрузчики
При использовании
runtime sharing вы можете
столкнуться с еще одной проблемой. Ваши флэш-ролики
почему-то прекрасно работают с локального диска, но не
работают с web-сервера. Или не работают на MacOS.
Точнее, вроде бы работают, но символы, которые
подгружаются с помощью runtime
sharing, не работают. Почему это так, до конца не
ясно. Но мы придумали способ, с помощью которого можно
решить эту проблему.
В каждый *.swf-файл,
из которого импортируются символы, нужно положить один
дополнительный пустой символ и настроить ему такие же
параметры runtime sharing,
как и всем остальным символам из этого *.swf-файла.
Затем в "клиентском" флэш-ролике нужно создать
специальную предварительную сцену (если вы забыли, как
создавать сцены, см. третью лекцию). По одному
экземпляру каждого из вышеупомянутых пустых символов
(один символ на каждый *.swf-файл, откуда что-либо
импортируется) нужно затем поместить на эту сцену
(которая будет проигрываться до основного содержимого
вашего ролика).
Это действие приводит
к нужному результату: похоже, что в таком случае весь
*.swf-файл загружается заранее, после чего все другие
определенные в нем символы можно использовать без
проблем.
Контролируемая
загрузка клипов
Представьте себе такую
ситуацию. Вы выкладываете свой готовый, протестированный
проект на удаленный сервер и видите, что ничего не
работает. По крайней мере, при первом открытии
веб-страницы, потому что после нажатия Refresh
все, скорее всего, загрузится нормально.
В чем же дело?
Видимо, произошла
"рассинхронизация" разных клипов. Не забывайте, что
каждый клип живет своей жизнью. Пока все файлы лежали в
локальной сети, порядок выполнения кода был один, а
после того, как файлы положили в Интернет, - он
изменился.
Например, код в уже
загруженных клипах "убежал" вперед и выполнился до
выполнения кода еще не загруженных клипов, хотя
планировалось все наоборот.
Чтобы решить эту
проблему, нужно как-то отследить момент загрузки всех
клипов, и только после этого начать выполнять нужный
код. Как это сделать?
У runtime-shared
модулей есть такое свойство: пока модуль (*.swf)
полностью не загрузится, никакие клипы в нем играть не
начнут. Этим можно воспользоваться.
Создадим в каждом из
*.swf-модулей по пустому символу, в каждом из которых
поместим приблизительно такой код:
if
(_global.swfModulesCounter == undefined)
_global.swfModulesCounter = 0;
global.swfModulesCounter++;
Этот код увеличивает
счетчик загруженных .swf-модулей на единицу.
Теперь можно поместить
в отдельной сцене флэш-ролика все эти пустые символы, а
в нужном месте (в котором и предстоит ожидать загрузки
всех модулей) сделать трехкадровый цикл с проверкой
значения счетчика. Если оно достигло общего числа нужных
*.swf-модулей - значит, можно продолжать выполнение.
Особенности совместной
работы механизмов sharing
Выше мы рассмотрели
возможности применения author time
sharing и runtime sharing
по отдельности.
Теперь приведем два
примера, когда может быть полезно использовать оба
механизма совместно.
Замена путей runtime
sharing с помощью author time sharing
Представьте себе такую
ситуацию: вы используете только
runtime sharing (без author
time sharing) для своих нужд. В один прекрасный
день возникает необходимость положить библиотечные файлы
не в подкаталог library, а
в тот же каталог, в котором лежат все флэш-ролики.
Что делать?
Об этом нужно
побеспокоиться заранее. Для всех компонентов, с которыми
вы используете runtime sharing,
можно настроить author time
sharing из какого-нибудь центрального места.
Тогда при возникновении необходимости вы просто
изменяете настройки export for runtime sharing
для всех компонентов в библиотеке,
после чего все флэш-ролики, использующие
библиотеку, получают новые
параметры runtime sharing
из библиотеки во время
компиляции.
Правда, по имеющейся у
авторов неприятной статистике, что в сложных случаях
данный механизм срабатывает лишь на 90%, в остальных
случаях сами символы меняются, а параметры
runtime sharing - нет. В
любом случае, если у вас есть достаточно много
флэш-роликов, подгружающих общие компоненты во время
выполнения, лучше воспользоваться данным приемом, ведь
поменять 100% путей в библиотеке
и 10% путей во всех флэш-роликах может все же оказаться
намного дешевле, чем поменять 100% путей в
библиотеке и 100% путей во
всех флэш-роликах.
Насколько известно
авторам, во Флэш МХ не существует другого сколько-нибудь
приемлемого способа изменения этих путей2).
Подключение нужной
комбинации runtime-загрузчиков
Рассмотрим теперь
такую ситуацию. У нас есть несколько флэш-проектов,
каждый из которых использует часть библиотечных
компонентов, загружаемых с помощью
runtime sharing. Скорее всего, мы используем
runtime-загрузчики, иначе
бы ничего не работало.
Но в одном проекте нам
нужна одна часть библиотечных компонентов, а в другом -
другая. Тем не менее, все флэш-ролики созданы на базе
одного и того же шаблона,
то есть в первой сцене там лежат все
runtime-загрузчики.
Кроме того, мы знаем,
что если во Флэш МХ на сцену положен хоть один символ,
который импортируется с помощью
runtime sharing, и флэш-плеер не может найти
соответствующий *.swf-файл (а у нас сейчас получается
именно такая ситуация), ничего вообще работать не будет.
Что же делать?
Вручную заходить в
каждый флэш-ролик и удалять соответствующий
runtime-загрузчик? Это
плохой вариант, похожий на дублирование кода.
Есть лучшее решение:
положить все runtime-загрузчики
в отдельный клип (назовем его группирующим
runtime-загрузчики клипом),
который лежит в каждом флэш-ролике и импортируется с
помощью только author time sharing.
Тогда достаточно будет поменять содержимое этого клипа в
библиотеке для конкретного
проекта - и готово, все нужные "runtime-загрузчики"
будут выкачаны автоматически, а ненужные - пропадут.
Это же решение можно
(и нужно) применить к контролируемой загрузке клипов
(см. выше в этой лекции): регулировать количество
счетчиков в зависимости от действительно необходимого
числа *.swf-модулей с помощью группирующего клипа.
Использование #include
Как мы видели,
использовать механизмы sharing часто бывает
удобно, однако это сопряжено и с рядом неприятностей.
Если вам нужно всего лишь определить несколько функций
(или классов) для общего пользования, то есть ничего
кроме кода на ActionScript не нужно делать, проще
воспользоваться инструкцией
#include.
Шаблоны для разработки
Если в рамках проекта
создается много похожих флэш-роликов, то, даже если они
используют общие компоненты, в каждом ролике отдельно
придется сделать много сходных действий.
Чтобы избежать этого,
можно использовать шаблоны
для разработки.
Шаблоном мы будем
называть заготовку, *.fla-файл, в который программист
тщательно собирает все элементы общего пользования,
которые могут понадобиться дизайнерам. Разработку своего
модуля дизайнер начинает с того, что сохраняет готовый
шаблон в свою рабочую
директорию - естественно под новым именем. Впрочем, эта
простейшая операция в сочетании с
author time sharing имеет некоторые особенности,
про которые мы расскажем далее в этой лекции в разделе "Библиотеки").
Нужно помнить, что с того момента, как дизайнер забрал к
себе этот файл, мы практически не будем иметь доступа к
тому, что там находится. Практически - потому, что есть
еще author time sharing.
Таким образом, разумно будет все, что мы положим в
шаблон, разместить в одном
или нескольких клипах, для которых
author time sharing включен.
Рассмотрим в качестве
примера кое-какие вещи из тех, что могут лежать в
шаблоне (практически все
они по отдельности уже упоминались выше).
Библиотека компонентов
Первое, что вы,
вероятно, захотите увидеть в
шаблоне, - это библиотека
ваших повторно используемых компонентов (или клипов),
чтобы разработчики просто перетаскивали нужные контролы
на сцену и могли ими пользоваться, ни о чем не
задумываясь.
Скорее всего, вы
применяете runtime sharing
или author time sharing
(или оба вместе) для своих компонентов повторного
использования. В таком случае в
шаблоне у всех этих компонентов должны быть
установлены настройки для импорта (из библиотечных
файлов).
#include
Если во всех
флэш-роликах вы пользуетесь какими-то общими функциями и
классами, вполне можно сразу подключить эти #include-файлы
в шаблоне.
Возможно, лучше
подключение всех #include-файлов сгруппировать в
клипе (опять-таки, author time shared), чтобы
всегда можно было добавить или удалить какой-то из них
централизованно.
Сцена с
runtime-загрузчиками
Вы помните, что для
корректной работы runtime-shared компонентов
необходимо сделать специальную процедуру (см. ранее в
этой лекции).
Авторы предлагают
выделить для этой цели в шаблоне
отдельную сцену во флэш-ролике (самую первую), в которую
и положить группирующий
runtime-загрузчики клип.
Чтобы сделать сцену,
откройте панель Scene (Shift-F2) и нажмите
на кнопку с изображением плюса. Сцены можно менять
местами с помощью перетаскивания их мышью.
Сцена со счетчиками
загруженных модулей
Авторы предлагают
выделить в шаблоне еще одну
сцену (вторую), в которую положить клип, группирующий
все счетчики числа загруженных модулей. Таким образом,
первая сцена будет инициировать загрузку всех нужных
*.swf-файлов, а вторая - дожидаться окончания этой
загрузки.
Управление процессом
Вероятно, что в
процессе загрузки всех флэш-роликов можно будет выделить
некоторые шаги, связанные с выполнением каких-то команд.
Например:
//скрытие всего
_root'а (пока идет загрузка);
_root._visible = false;
// ожидание в трехкадровом цикле, пока не загрузятся
всe
// .swf-модули (см. ранее в этой лекции);
if (_global.SWFModulesLoaded < _global.TOTAL_SWF)
gotoAndPlay (2);
//применение нужных стилей ко всем контролам,
которые теперь
// уже успели загрузиться;
_global.locTextStyleFormat.applyChanges(); //
_global.btnTextStyleFormat.applyChanges(); //
//посылка каких-то внутренних управляющих событий;
this.raise("InitializationComplete",
"InitializationComplete",
EVT_TYPE_STRING);
this.raise("ModelInitializationComplete",
"ModelInitializationComplete", EVT_TYPE_STRING);
//обработка XML-скриптов;
if (_global.iniFileParams.xmlSetupString !=
undefined)
_global.ext.importFromXml(_global.iniFileParams.xmlSetupString);
_global.ext.sendRestoreStateEvent();
}
//открывание всего _root'а (все загружено);
_root._visible = true;
//остановка главного клипа
stop();
Все подобные действия
нужно проделывать в шаблоне,
чтобы не дублировать их. И опять же, лучшим решением
будет положить в шаблон
специальный author time shared клип, в котором
производятся все эти действия, чтобы их всегда можно
было скорректировать.
Некоторые проблемы со
сложными шаблонами
Иногда в сложных
шаблонах начинает
происходить одна очень неприятная вещь - среда
разработки Flash MX падает с сообщением "Pure virtual
function called". Скорее всего, это связано с
"многозвенным author time sharing".
Изложим способ борьбы с этим явлением (если уже некогда
выяснять, в чем причина, а нужно как-то "жить").
Просматриваете самые "сомнительные" (особенно с
многозвенным author time sharing)
символы из библиотеки и
убираете в их параметрах галочки "always update
before publishing". Пробуете откомпилировать. Если
работает - значит, виноват этот символ. Теперь
попробуйте опять поставить галочку и еще раз
откомпилировать. В большинстве случаев это помогает.
HTML-шаблоны
Во Flash MX есть очень
полезная вещь - HTML-шаблоны.
Они позволяют один раз сделать нужный
шаблон HTML-страницы, в
который для каждого нового флэш-ролика будут
подставляться правильные уникальные значения.
Зачем это нужно?
- Для простого
контроля над общими настройкми, задаваемыми из
HTML-страницы (цвет фона, доступность меню и т. п.)
- Для выполнения
более специфических задач, например, передача
специальных параметров флэш-роликам.
- Для генерации
тегов <OBJECT> и
<EMBED> с необходимыми
параметрами с помощью JavaScript (ранее в этой
лекции упоминалось, для чего это может быть нужно).
Напомним, что тег <OBJECT>
(с соответствующим параметром
CLSID) служит для демонстрации флэш-ролика в
Internet Explorer, а <EMBED>
- (с соответствующим MIME-type) в браузерах,
основанных на технологии Mozilla (собственно
Mozilla, Netscape или Firefox).
Как сделать
HTML-шаблон
Во-первых, нужно
создать HTML-файл, содержащий нужный вам код,
параметризовав его специальными шаблонными переменными
(см. далее).
Во-вторых, нужно
положить этот файл в папку C:\Program
Files\Macromedia\Flash MX\First Run\HTML (или
аналогичную). Кстати, там же можно посмотреть примеры
шаблонов. При каждом
запуске Flash MX все файлы оттуда копируются в
соответствующую папку в пользовательском профиле:
С:\Documents and Settings\User\Application
Data\Macromedia\Flash MX\Configuration\HTML (или
аналогичную). Характерные пути к данным Flash MX в
пользовательском профиле вы можете найти в предыдущей
лекции в параграфе об установке online-документации.
Если вы не хотите, чтобы
HTML-шаблоны копировались всем пользователям,
которые работают на данном компьютере, можете
скопировать их сразу себе в profile.
И, в-третьих, нужно
перезапустить Flash MX, после чего этот
шаблон станет доступен для
выбора в диалоге File \ Publish Settings,
закладка HTML.
Как пользоваться
переменными HTML-шаблона
Пусть вы редактируете
HTML-шаблон и дошли до того
места, где требуется вставить имя *.swf-файла, которое
будет разным для каждого флэш-ролика. Здесь нужно
использовать шаблонную переменную: вместо имени
*.swf-файла (которое вы не знаете заранее) вставляете
такой код: $MO. Когда Флэш
при публикации ролика
встретит такую переменную, он подставит вместо нее имя
*.swf-файла данного ролика. Аналогичные шаблонные
переменные (под названием $WI
и $HE) нужно вставить в
тех местах, где указываются ширина и высота флэш-ролика.
Все шаблонные
переменные начинаются со знака '$'
(если вам нужно будет вставить просто символ доллара,
перед ним нужно будет поставить '\'),
после которого следуют две большие латинские буквы,
идентифицирующие переменную.
Ниже мы перечислим
наиболее употребительные переменные
HTML-шаблона. А полный
список всех переменных можно увидеть, например, по
адресу
http://livedocs.macromedia.com/flash/mx2004/main_7_2/wwhelp/wwhimpl/common/html/wwhelp.htm?context=Flash_MX_2004&file=00000499.html
(правда, это параметры для Flash MX 2004, но список по
сравнению с параметрами для Flash MX почти не
изменился). Если вам не хочется набирать такой сложный
URL, этот же список вы найдете по адресу
http://www.pdesigner.net/Flash_MX_Tutorials/20_publish16.html,
а также по адресу
http://www.123flashchat.com/flash/20_publish16.html.
Самые нужные
переменные HTML-шаблона
приведены в
таблице 13.1.
Таблица
13.1. Переменные HTML-шаблона
Название шаблонной переменной |
Код |
Пояснение |
Заголовок
шаблона |
$TT |
Строчка, указанная после этой
переменной будет показываться в комбо-боксе
выбора
HTML-шаблона в
диалоге Publish Settings. |
Начало описания
шаблона |
$DS |
Описание
шаблона можно
получить по кнопке Info в диалоге
Publish Settings. Описание может
занимать несколько строк. В окончательный
HTML оно не попадет. |
Конец описания
шаблона |
$DF |
См. предыдущий комментарий. |
Имя файла флэш-ролика |
$MO |
Например,
mymovie.swf. |
Заголовок ролика |
$TI |
Например,
mymovie (то
же, что $MO,
но без расширения). |
Ширина ролика |
$WI |
В пикселах. |
Высота ролика |
$HE |
В пикселах. |
Цвет фона |
$BG |
Цвет, установленный в
качестве дефолтового в вашем ролике
(устанавливается в диалоге Modify /
Document). |
Качество изображения |
$QU |
Качество перевода векторной
графики в изображения растровую в плеере
(задается в закладке HTML диалога Publish
Settings). |
Параметры тега
<EMBED> |
$PE |
Генерирует сразу несколько
стандартных параметров тега
<EMBED>:
src (имя файла флэш-ролика), bgcolor
(цвет фона) и quality (качество
перевода векторной графики в растровую). |
Параметры тега
<OBJECT> |
$PO |
Генерирует сразу несколько
стандартных параметров тега
<OBJECT>:
movie (имя файла флэш-ролика),
bgcolor (цвет фона) и quality
(качество перевода векторной графики в
растровую). |
Библиотеки
Если вы собрались
написать свою библиотеку
компонентов, то вы, скорее всего, уже представляете, как
это сделать.
Приведем соображения
авторов по поводу устройства
библиотек.
Из чего состоит
библиотека
Состав
библиотеки может выглядеть
так:
- Набор #include-файлов
с часто используемыми функциями и классами;
- Набор исходных
*.fla-файлов с повторно используемыми компонентами;
-
Шаблон для разработки
(*.fla-файл);
-
HTML-шаблон;
- Набор
*.swf-файлов с повторно используемыми компонентами,
если применяется runtime
sharing или другие методы динамической
загрузки (loadMovie).
Модульность
На любом уровне (будь
то #include-файлы, *.fla-файлы или *.swf-файлы)
очень полезно соблюдать модульность, то есть помещать
все компоненты в отдельные файлы. Тогда вы всегда
сможете без особых проблем сконфигурировать
библиотеку для любого
проекта (убрать из нее ненужные части и поместить
дополнительные). Разумеется, если какие-то компоненты
имеют общие части (возможно - базовые классы), эти части
тоже полезно выделять в отдельные файлы.
Размещение
библиотечных *.fla-файлов
Мы пока ни словом не
обмолвились о том, где удобно хранить эти файлы
(понятно, что это все имеет значение, только если вы
пользуетесь механизмом author time
sharing).
Из опыта авторов
следует, что удобнее всего хранить эти библиотечные
файлы на каком-нибудь подключаемом диске, например,
М:. Допустим, у вас есть
один библиотечный файл:
library.fla. Тогда во всех флэш-роликах (то есть,
в шаблоне) символы должны
ссылаться на M:\library.fla.
Это очень удобно тем, что вы в любой момент можете
использовать нужную версию
библиотеки, путем простого переключения диска
M:. Например, для
разработчиков флэш-роликов этот диск может ссылаться на
\\myserver\myshare\FlashMXLibrary,
а для разработчиков библиотечных компонентов - ссылаться
на
C:\FlashMXLibrary\TheLatestTestVersion.
Теперь вспомните, в
разделе, посвященном шаблонам
для разработки, мы говорили о некоторой особенности
копирования шаблонов в
рабочие директории дизайнеров, если те используют
author time sharing.
Дело в том, что Flash
MX ведет себя каким-то странно-интеллектуальным образом
с путями, заданными в области source свойств символа
(собственно, с настройками путей
author time sharing). А именно, он "оптимизирует"
эти пути, то есть сохраняет там не полный путь, а
относительный. Причем, он еще и просматривает эти пути
при сохранении файлов. Поэтому просто скопировать файл
шаблона в рабочую
директорию дизайнера нельзя, а нужно именно сохранить
шаблон из среды Флэш под
новым именем, и при этом рекомендуемыми условиями
являются следующие:
-
шаблон находится на
сетевом диске, подключенном, например, как
M:
- рабочая
директория дизайнера не находится на
M:
-
шаблон открывается (для
последующего сохранения) так, чтобы текущим
каталогом был именно M:
(а не соответствующий этому сетевой или какой-нибудь
еще путь).
"Компилятор
флэш-файлов"
Представьте себе, что
у вас есть большой проект с большим количеством не очень
сложных флэш-роликов, которые должны быть достаточно
"легкими", не требовать никаких дополнительных файлов
для своей загрузки (весь флэш-ролик в одном
*.swf-файле).
Но все-таки есть
некоторые вещи, которые вы хотите менять одним махом во
всех этих флэш-роликах, например, какие-то цвета, язык
или что-нибудь еще.
Понятно, что в этом
случае очень неудобно каждый раз вручную
перекомпилировать все 50 флэш-роликов, особенно это
чревато соблазном сохранять результаты прошлых
компиляций, а это, в свою очередь, опасно тем, что
некоторые последние изменения могут не попасть в сборку.
Именно для такого
проекта "компилятор
флэш-роликов". Ведь в любой среде разработки (Java,
C/C++ и др.) обязательно есть command-line
компилятор, которым удобно
в командном режиме собирать большие проекты. Во Flash MX
такого компилятора нет.
Как же работает наш
компилятор? Это отдельная
Windows-программа, которая активно использует Win32 API.
Она умеет:
- открывать разные
*.fla-файлы с помощью функции
ShellExecute();
- находить окно с
флэш-роликом по его заголовку,
- посылать разные
клавиатурные сообщения в его окна (имитация действий
пользователя),
- закрывать
вспомогательные окна с запросами подтверждениями
(таким же способом).
Ниже приведен
откоментированный код этого
компилятора на C с применением WinAPI
(компилировался при помощи Microsoft Visual C++ 6.0).
Фактически, наша
программа просто делает вид, что пользователь открыл
некоторый файл во Флэш МХ и выбрал из меню пункт File
/ Publish или пункт Control / Test Movie.
Чтобы воспользоваться этим "компилятором",
вам нужно будет взять приведенный ниже код (написанный
на С для пущей переносимости) и либо откомпилировать его
при помощи Microsoft Visual C++ 6.0, как поступали мы,
либо (возможно, внеся некоторые изменения)
воспользоваться другим С-компилятором.
(Надо учесть, что наша программа использует WinAPI и
рассчитана только на работу под Windows. Если вы
работаете на Макинтоше, вам придется написать свой
вариант "флэш-компилятора".)
После того, как вы соберете программу, вы получите
приложение командной строки, которому можно будет
передать первым аргументом полное имя *.fla-файла,
который вы хотите откомпилировать, а вторым - слово
compile или
publish. Во втором случае
будет произведена публикация
файла с теми настройками, которые вы выбрали. Затем
составьте пакетный файл (*.bat-файл), который будет
компилировать все нужные вам ролики.
#include "stdafx.h"
#define WINVER 0x0500
// чтобы можно было использовать функции Windows
2000
#include "windows.h"
#include "winuser.h"
#include "shellapi.h"
int main(int argc, char* argv[])
{
const int PUBLISH_MENU_ID = 40057;
// Номера получены из MSSPY
const int COMPILE_MENU_ID = 33371;
// с помощью этой утилиты были определены
const int CLOSE_CHILD_ID = 57602;
// идентификаторы интересующих нас пунктов меню
const int SAVE_ID = 57603;
if (argc != 3) {
// проверка на корректность исходных значений
puts ("First parameter: full .fla file name to
compile,");
puts ("Second parameter: \"publish\" or
\"compile\"");
return 0;
}
int MENU_ID = (!strcmp (argv[2], "publish")) ?
PUBLISH_MENU_ID :
COMPILE_MENU_ID;
// в зависимости от пожеланий пользователя либо
компилируем
// (ctrl-Enter), либо публикуем (ctrl-F12)
char buffer[200] = "Macromedia Flash MX - [";
char buffer1[200] = "Macromedia Flash MX - ";
// два варианта заголовка окна: иногда бывает так, а
иногда иначе
char tmpbuf[200] = "";
char one[2] = " ";
for (int i = 0; i < strlen (argv[1]); i++) {
// формируем возможные названия окон
if (argv[1][i] == '\\') {
strcpy (tmpbuf, "");
continue;
}
else {
one[0] = argv[1][i];
strcat (tmpbuf, one);
}
}
strcat (buffer, tmpbuf);
strcat (buffer1, tmpbuf);
strcat (buffer, "]");
LPCSTR window_name = (LPCSTR) buffer;
//сформировали заголовки
LPCSTR window_name1 = (LPCSTR) buffer1;
WORD low = (WORD)MENU_ID,
// младший байт - идентификатор меню,
// старший должен быть равен 1.
high = 1; //accelerator
char param[400];
strcpy (param, "\"");
strcat (param, argv[1]);
strcat (param, "\"");
printf ("%s\n", param);
puts ("Trying to open file");
//открываем нужный *.fla-файл
ShellExecute (0, "open", param, NULL, NULL, SW_SHOW);
HWND h = 0, h1 = 0;
puts ("Trying to find the main window");
do {
Sleep (100);
h = FindWindow ("SmartSketchMDIFrame",
window_name);
//ищем окно
h1 = FindWindow ("SmartSketchMDIFrame",
window_name1);
} while (!h && !h1);
if (!h) h = h1; //нашли одно или другое окно
puts ("Sending commands");
// посылаем сообщение о компиляции или публикации
SendMessage (h, WM_COMMAND, MAKEWPARAM (low, high), NULL);
//сейчас мы закроем все ненужные окна
low = (WORD)CLOSE_CHILD_ID;
puts ("Closing child windows");
if (MENU_ID == COMPILE_MENU_ID)
// если была компиляция, то закрываем это окно
SendMessage (h, WM_COMMAND, MAKEWPARAM (low,
high), NULL);
low = (WORD)SAVE_ID;
// сохраняем файл
SendMessage (h, WM_COMMAND, MAKEWPARAM (low, high), NULL);
// полностью закрываем сhild-окно.
// SendMessage работает синхронно, а PostMessage -
// асинхронно. Здесь можно использовать PostMessage(), потому
// для продолжения работы ничего дожидаться не нужно.
low = (WORD)CLOSE_CHILD_ID;
PostMessage (h, WM_COMMAND, MAKEWPARAM (low, high), NULL);
//пробуем отыскать диалоговое окно
HWND hMain = 0, hDialog = 0;
puts ("Searching for the dialog boxes");
do {
// ищем диалог о сохранении файла, который,
возможно,
// появился как результат выполнения команды
закрытия окна.
hMain = FindWindow ("SmartSketchMDIFrame", "Macromedia Flash MX");
if (hMain) {
puts ("There were no dialog");
break;
}
hDialog = FindWindow (NULL, "Flash MX");
if (hDialog) {
high = BN_CLICKED;
low = IDNO;
SendMessage (hDialog, WM_COMMAND, MAKEWPARAM(low,
high), NULL);
//закрываем диалог
break;
}
Sleep (100);
} while (true);
printf ("Main = %Xh, Dialog = %Xh\n", h, hDialog);
return 0;
}
Использование subst и
hardlink'ов
subst - исключительно
полезная утилита для создания виртуальных дисков,
которые, как уже упоминалось, очень удобно использовать
в качестве места размещения файлов-источников для
author time sharing.
Альтернативой команде subst
является функция Map Network Drive, доступная из
Windows Explorer.
Синтаксис:
-
subst <drive>: <directory>
для создания виртуального диска;
-
subst <drive>: /d для
удаления виртуального диска. При выполнении этой
команды убедитесь, что текущая директория не лежит
на виртуальном диске.
Жесткие ссылки (hard
links) - функция файловых систем UNIX, в Windows
появилась начиная с версии 2000. Вы можете сделать
несколько ссылок на один файл из разных каталогов,
причем все они будут равноправны. Иными словами, на файл
всегда существует минимум одна жесткая ссылка. Если
последняя ссылка на файл удаляется, файл уничтожается.
Как это можно использовать? Представьте, что у вас есть
библиотека, которой
пользуются много разработчиков, и у каждого из них в
разных рабочих директориях лежат разные флэш-ролики,
использующие одну runtime-shared
библиотеку, размещенную в
подкаталоге library. Вы
можете организовать автоматическое обновление символов в
библиотеках .fla-файлов с
помощью author time sharing
с виртуального или сетевого диска. Но вы не можете с
помощью виртуального диска подменить подкаталог
library или файлы, лежащие
в нем. Вот для этого как раз и служат жесткие ссылки:
эти файлы можно залинковать на сетевой диск, и они будут
обновляться автоматически.
Есть программы,
которые позволяют это делать, например, Far 1.5 (Alt-F6).
Обязательное условие: все ссылки должны лежать в одном
томе NTFS, то есть дизайнеры флэш-роликов не могут
держать свои каталоги для разработки на локальных
дисках.
Способы применения
системы контроля версий
Обычно
системы контроля версий (а
точнее, системы конфигурирования программного
обеспечения - это более корректное название) применяются
для:
- контроля над
внесением изменений в код (в частности, ограничения
одновременного внесения изменений несколькими
разработчиками)
- отслеживания и
хранения версий;
- сборки и
интеграции проекта.
Разработка
флэш-проектов здесь абсолютно не является исключением.
Поэтому рассмотрим некоторые аспекты этой проблемы более
подробно.
Системы контроля
версий
Существуют разные
системы контроля версий от
разных производителей. Самыми популярными являются CVS,
ClearCase, MS Visual SourceSafe. CVS - в каком-то смысле
открытый стандарт, но для нее нет удобных (для
использования во флэш-проектах) графических оболочек.
ClearCase - очень сложная и дорогая система, которую
вряд ли имеет смысл использовать для управления
флэш-проектами. MS Visual SourceSafe (далее называемая
сокращенно MS VSS) - неплохая и достаточно простая
система с удобным графическим интерфейсом.
Подробно рассматривать
достоинства и недостатки каждой из них мы не станем, а
примеры, приводимые ниже, будут касаться MS VSS, потому
что именно ею мы пользовались для управления одним из
флэш-проектов.
Выбор был сделан
вполне тривиально: MS Visual SourceSafe - это наиболее
простая система. Правда, позже мы обнаружили, что MS VSS
очень хорошо подходит для флэш-проектов. Например, в ней
по умолчанию запрещены multiple checkouts
(которые не имеют смысла при работе с двоичными файлами
*.fla), а также есть очень удобные инструменты links
и shadow folders, о которых мы расскажем далее.
Контроль над внесением
изменений в код
Что для флэш-проектов
является характерным - так это то, что исходные файлы
имеют двоичный формат, что отнюдь не способствует
совместной работе над ними и последующему слиянию (merge)
файлов. Что ж, тем жестче нужно ограничивать
одновременные изменения .fla-файлов (и запрещать
unreserved, или multiple, check-outs).
MS VSS по умолчанию и
работает в таком режиме.
Разумно также (как уже
неоднократно замечалось ранее) выносить максимум кода за
рамки *.fla-файлов (в include-файлы). Тогда можно
настроить возможность одновременной работы над этими
файлами.
Интеграция
При интеграции очень
удобно пользоваться такими механизмами (или их
аналогиями), как ссылки (links) и теневые папки (shadow
folders), которые есть в VSS.
Ссылки VSS - это
аналог жестких ссылок (hard link)
в файловых системах (см. ранее в этой лекции). Теневые
папки позволяют "отобразить" все изменения в каком-то
проекте VSS на каталог файловой системы, то есть
обновить там все файлы.
Приведем пример.
Предположим, вы изменили файл
core.fla и выполнили check-in (внесли
изменения). Поскольку на core.fla
существуют ссылки в проектах
$/core/ и $/author-shared,
он изменился сразу в двух проектах. У проекта
$/core/ настроен shadow
folder в \\myshare\myProject\src
(здесь под \\myshare
имеется в виду абстрактный сетевой путь, являющийся
корнем для флэш-проектов), а у проекта
$/author-shared - в
\\myshare\\myProject\author-shared,
в результате чего файл изменился сразу в двух каталогах:
в архивном каталоге проекта (src)
и каталоге, который подключен в качестве сетевого диска
(например, как M:) и из
которого обновляются все флэш-ролики при компиляции (author-shared).
Точно так же с помощью
links и shadow folders можно обновлять *.swf-файлы,
причем если вы еще используете жесткие ссылки в файловой
системе, то *.swf-файлы могут автоматически обновиться в
рабочих директориях дизайнеров.
1)
Если "двухуровневый"
author-time sharing
используется в комбинации с
runtime sharing , то есть весь компонент
обновляется как с помощью
author-time sharing, так и с помощью
runtime sharing (и то же
самое происходит с группирующим символом элементов
скинов в составе компонентов), то все, похоже, работает
нормально.
2)
Во Flash MX 2004 для этого можно пользоваться .jsfl
(JavaScript Flash)-скриптами. |