Рассуждение о "прелоадере"
(Macromedia Flash 5.0).
,
Обзор прелоадеров (предварительных загрузчиков, индицирующих степень загрузки Flash-ролика) дает понять, что некоторые авторы допускают множество ошибок, например: считывание исходного размера файла в цикле, усложнение 1-го кадра, использование устаревших версий (некоторые команды уже не поддерживаются). В этом уроке разговор пойдет не о "художественном" оформлении, а именно о принципе реализации.
Нам нужны всего две конструкции:
GetBytesTotal() и   GetBytesLoaded()
Первая возвращает размер ролика в байтах, а вторая - размер в байтах загруженной части ролика.
Напишем простейший прелоадер, для этого создадим новый файл. На Scene1 разместим надписи: Bytes Total, Bytes Loaded, Percent и три "пустые" надписи. Получается примерно следующее:
Теперь в окне Text Options определяем надписи как динамические и назначаем имена переменных для этих надписей (сверху вниз), например: TotalField, LoadField и PercentField:
Для первого кадра в окне Actions (установите режим Expert Mode) пишем код (все кадры - ключевые):
Total = _root.GetBytesTotal();
Переменной Total (можно не объявлять) присваиваем размер файла в байтах;
TotalField = Total;
Переменной для надписи TotalField присваиваем значение переменной Total.
Больше к этому кадру ролик не обращается. (Маловероятно, что размер вашего файла будет изменяться в процессе загрузки).
Во втором кадре пишем код:
Load = _root.getBytesLoaded();
LoadField = Load;
Percent = int(Load / Total * 100);
PercentField = Percent + "%";
Переменной Load присваиваем значение загруженной части файла;
Переменной для надписи LoadField присваиваем значение переменной Load.
Переменной Percent присваиваем увеличенное в 100 раз округленное значение отношения загруженной части файла к размеру файла, т. е. процентное значение загрузки;
Переменной для надписи PercentField присваиваем значение переменной Percent и знак "%".
Третий кадр:
if (load < Total){gotoAndPlay (2);};
Если загружено меньше, чем размер файла - перейти к кадру 2. В первом кадре мы уже все сделали. Зачем туда обращаться?
Кадр 4:
Stop();
В этом же кадре, но на другом слое уже начинается сам ролик. Разумно нарисовать кнопку Play и передавать управление на начало ролика.
Если вы сделали все правильно, то получится примерно следующее (это только картинка):
Если не вышло - вот .
В этом уроке описаны только конструкции, позволяющие реализовать любой прелоадер, например с линейкой загрузки и т. п., но необходимо учитывать, что все графические "навороты" загружаются в первом кадре, т. е. чем он больше, тем дольше будет грузиться сам прелоадер!
А нужен ли вообще прелоадер? Ответить на этот вопрос поможет сам Flash!
В режиме Test Movie в меню Debug выберите или установите свою скорость загрузки файла (учтите, что реальная скорость загрузки у пользователя будет гораздо ниже указанной):
В меню View выбираем пункт Show Streaming:
Тестируем наш ролик на различных скоростях загрузки:
Успехов!
PS. Обратите внимание: реальный размер ролика 2470 байт, а Flash "говорит", что 2468 байт! Я не знаю почему. Кто знает?
Снег во Flash
,
В этом уроке предлагается разобраться с ActionScript, а заодно научиться делать "настоящий" снег:
Итак, шаг 1: В вашем любимом графическом пакете создайте картинку 480 х 60 px. Это наш фон. (Я поставил максимальное сжатие и самое плохое качество). Если у вас там всякий лес цветной разный нарисован - подберите степень сжатия, чтобы фон не смотрелся убого. Но учтите, что чем сложнее фон - тем больше размер баннера.
Шаг 2: Теперь надо браться непосредственно за Flash. Создайте новый файл. Цвет фона значения не имеет. Измените параметр Modify | Movie... | Frame Rate с 12 до 50 и установите размер 480 х 60 px. Добавьте еще 2 слоя. Назовите слои соответственно "Snow", "Text" и "Back". В кадр 50 для каждого слоя вставьте фрейм:
Шаг 3: Вызываем пункт меню Insert | New Symbol... В разделе Name называем символ: "Back" , параметру Behavior назначаем Button. Импортируем наш фон: File | Import... В панели Info Устанавливаем размер 480 х 60:
Помещаем символ Back на слой Back и центрируем:
Шаг 4: Создание символа "Снежинка". Создаем новый символ: Insert | New Symbol... с именем Snow и типом "Movie Clip". Не забудьте: заливка должна быть белой, фон - прозрачный. Можно воспользоваться векторным редактором Flash или скопировать нарисованный символ, например, из программы Corel Draw (Я так и сделал. Вот ).
Размер снежинки 70 х 70 px. Нажмите Ctrl+Shift+G, чтобы разгруппировать изображение. Поместите Movie Clip Snow на слой Snow и в панели Instance присвойте имя Snow:
Установите позицию символа -35:
Шаг 5: Создание надписи. Создайте новый символ с именем Text, типом "Movie Clip" и поместите в него текст. Преобразуйте текст в растровое изображение (Ctr+b). Установите прозрачность 30%:
Поместите Move Clip на слой Text и в резделе Instance присвойте имя Text. У вас должно получиться примерно так:
Мы сделали всю подготовительную работу. Приступим к кодированию. Для символа Snow кликом правой клавиши мыши вызываем Object Actions.
Включаем режим Expert Mode:
Теперь старательно списываем этот код:
onClipEvent (enterFrame)
Событие возникает при смене кадра.
_root.snow._y = (35 + 60 + 35) / 60 * _root._currentframe;
Вычисляем новое положение снежинки по вертикали (35 - половина вертикального размера снежинки, 60 - высота баннера. Можно было написать сразу 130).
_root.snow._rotation = _root.snow._rotation + rotate;
Поворачиваем снежинку в зависимости от переменной rotate.
if (_root._currentframe == 1)
Если текущий кадр первый, выполняется последующий код по установке первоначальных параметров снежинки.
var scale;
var rotate;
Объявляем переменные.
rotate = random(3) - 1;
Переменная rotate принимает случайные значения: -1, 0 и 1.
_root.snow._rotation = random(30);
_root.snow._x = random(480);
Устанавливаем случайный начальный угол поворота снежинки и случайное положение по горизонтали.
_root.Snow._alpha = random(50) + 50;
Устанавливаем прозрачность снежинки в диапазоне 50 - 100%.
scale = random(90) + 10;
_root.Snow._xscale = scale;
_root.Snow._yscale = scale;
Генерируем случайный начальный размер снежинки в диапазоне 10 - 100%.
Итак, со снежинками разобрались. Сделали 2 важных вывода:
1. Все работает. Можно проверить Control | Test Movie
2. Встроенный редактор кода просто ужасен!
Для тех, кто разбираться в кодировании не хочет - вот ). Загрузить его в редактор кода можно следующим образом:
Осталось сделать обработчик для надписи. Откройте TimeLine для символа Text, дважды щелкнув по его пиктограмме:
Втавьте ключевой кадр в позицию 35. (Insert Keyframe). Выделите надпись и увеличьте значение Alpha в 100%:
Установите указатель на 1-й кадр и в панеле Frame установите значение Tweening в Shape:
Для первого и последнего кадров в панели Frame Actions напишите единственную строчку кода:
stop();
Перейдите к Scene 1, для символа Back в Frame Actions напишите следующий ):
on (rollOver, dragOver) {_root.Text.gotoAndPlay(2);}
on (rollOut, dragOut) {_root.text.gotoAndPlay(1);}
Вот и все:
Успехов!
Рисуем "работающие" часы
(Macromedia Flash 5.0).
,
Flash позволяет работать с датой/временем. За это отвечает объект
Date (object)
Рассмотрим некоторые возможности объекта, позволяющие создать часы, отображающие системное время.
Такие часы можно, например, разместить на странице сайта или встроить в поздравительную открытку.
Итак, создадим новый файл размером 100 х 50 px. На Scene1 в первом кадре поместим динамическую текстовую надпись и присвоим ей имя, например TimeField:
Для удобства размещения/выравнивания присвойте значение 00:00:00, все равно в процессе работы ролика надпись изменится. Если вы используете "экзотический" шрифт, укажите Flash, что начертание цифр и разделителя надо храниить в самом ролике:
На этом процесс "рисования" заканчивается. Приступим к кодированию.
Для первого кадра в панели ActionScript (не забудьте установить режим ExpertMode) пишем следующий код:
Time = new Date();
H = Time.GetHours();
M = Time.GetMinutes();
S = Time.GetSeconds();
if (Length(H) < 2) {H = "0" + H};
if (Length(M) < 2) {M = "0" + M};
if (Length(S) < 2) {S = "0" + S};
TimeField = H + ":" + M + ":" + S;
В первой строке создаем экземпляр объекта Date и присваиваем ему текущее системное время.
В строках 2 - 4 переменным H, M и S присваеваем значения часов, минут и секунд соответственно.
В строках 5 - 7 добавляем текстовый "0" к началу переменной в случае, если длина переменной меньше 2.
И, наконец, в последней строке для надписи TimeField присваиваем "собранное" значение времени.
Во втором ключевом кадре ролика пишем код:
GotoAndPlay(1);
Если вы правильно повторили все шаги, то часы должны "заработать". Здесь лежит .
Мы разобрались с "электронными" часами. Попробуем сделать часы "со стрелками":
Создаем новый файл размером 100 х 100 px. Вставляем новый слой и в свойствах называем слои соотвественно Arrows и Grid. Разумно, чтобы стрелки были расположены над циферблатом:
На слое Grid рисуем сам циферблат. Здесь . Далее создаем три новых символа с часовой, минутной и секундной стрелками. (Учтите, что поворачиваться "стрелки" будут относительно центра, помеченного "крестиком"). Назовем их соответсвенно HArr, MArr и SArr:
Помещаем символы на слой Arrows и в разделе Instance присвоим им имена HA, MA и SA:
Для первого кадра слоя Arrows в панели ActionScript (не забудьте установить режим ExpertMode) пишем следующий код:
Time = new Date();
H = Time.GetHours();
M = Time.GetMinutes();
S = Time.GetSeconds();
HA._rotation = 30 * (H - 12) + M / 2;
MA._rotation = 6 * M + S / 10;
SA._rotation = 6 * S;
Первые четыре строчки вам уже понятны по первому примеру. В строках 5 - 7 вычисляем угол поворота для соответствующих стрелок в зависимости от времени.
Во втором ключевом кадре ролика на слое Arrows пишем код:
GotoAndPlay(1);
Вот и все! Посмотрите исходный этого примера. Обратите внимание на размеры swf-файлов!
Далее все зависит от вашей фантазии. Для примера я сделал такой ролик:
Определение наличия Flash-plugin'а средствами HTML
,
В этом маленьком уроке рассказывается как определить наличие установленного плагина (примочки) Flash в браузере пользователя.
По статистике, около 90% пользователей в наши дни пользуются Internet Explorer (5-й или 6-й версией). В этих браузерах Flash, как правило, уже установлен (если же нет, то, при наличии Интернет-соединения, установить его - дело пары минут). Тем не менее, если вам нужно на 100% быть уверенным в том, что у пользователя всё будет работать "правильно", даже если у него не установлена примочка Flash, нужно определять наличие примочки, и, в зависимости от этого, показывать Flash страничку, или контент, не сожержащий Flash.
Здесь приведён самый простой способ проверки наличия Flash. Для этого способа потребуется лишь одна строчка в HTML и очень простой Flash-мультик.
Вот строчка, которую нужно будет вставить в HTML файл в раздел <head>:
<META HTTP-EQUIV="Refresh" CONTENT="seconds_until_refresh; URL=non_flash_url">
Эта строчка обращается по адресу non_flash_url через seconds_until_refresh после загрузки строчки. Например строчка
<META HTTP-EQUIV="Refresh" CONTENT="5; URL=non_flash.html">
обращается к файлу non_flash.html через 5 секунд.
Создаём Flash мультик с минимальными размерами (во Flash 5 было ограничение - 20x20, во Flash MX можно делать мультики хоть 1x1) с единственным кадром, содержащим единственное действие:
GetURL("flash_page.html");
flash_page.html - страничка, содержащая Flash-контент.
Можете скачать пример такого файла:
Из этого файла создаём .swf файл, который помещаем в наш HTML файл (в тот где была строчка <META ...>). Что в итоге происходит? Открывается файл, содержащий строчку <META ...> и маленький Flash мультик. Если в браузере установлена Flash-примочка соответствующей версии, то срабатывает действие в .swf файле и браузер переходит на страничку flash_page.html. Если же Flash примочка не обнаружена, то через 5 секунд браузер перейдёт по адресу, указаному в <META ...> (в нашем случае - non_flash.html). Недостаток этого метода состоит только в незначительной задержке в несколько секунд, кот. нужны для загрузки странички. Размер .swf файла получается очень маленьким (порядка 50-100 байт), так что это не является помехой.
Удачи!
Определение скорости компьютера
,
Для производительных роликов часто оказывается полезным определить скорость "железа", на котором они будут проиграны. (И, может быть, выбрать соответствующее качество (quality) воспроизведения). Ниже приводится простой способ определения производительности компьютера, который можно использовать во время прелоадинга (загрузки ролика) или непосредственно перед началом проигрывания ролика.
Вот наш рабочий пример:
Метод очень прост: мы берём кусочек анимации (длиной 1-3 секунды), совпдающей (или превосходящей) по сложности анимацию, которая используется в ролике. Запоминается значение таймера в начале анимации и в конце, а затем вычисляется длительность проигрыша кусочка. Скажем, установленная скорость ролика равна 30 кадров в секунду, а длина тестового фрагмента составляет 60 кадров. (Данные значения используются в нашем примере). В таком случае, длительность проигрыша должна составлять 2 секунды. Можно прибавить некоторое время (в нашем случае добавлено 0.5 сек) немного поэкспериментировав и определив минимальную скорость, которая требуется для проигрыша ролика. Функция getTimer(), которая используется для получения значения таймера возвращает результат в миллисекундах, что даёт нам большую чувствительность для наших тестов.
В приведенном примере тест на скорость считается пройденным, если 60 кадров анимации проиграются меньше чем за 2500 миллисекунд.
Можно придумать различные вариации этого способа. Только будьте осторожны с анимацией, используемой при определении скорости. Она должна требовать столько же (или даже больше) ресурсов, сколько использует ваш основной ролик. Подсказка: используйте большие по площади символы и различные эффекты цветности/прозрачности. Это хорошо нагружает видеосистему.
Вот исходник примера, использованного в уроке: (24 k)
Удачи!
Держите весь код в одном месте
Везде, где это возможно, весь код должен размещаться в одном месте. Это облегчает его нахождение и отладку. Одна из главных сложностей в отладке клипов Macromedia Flash — это поиск кода. Если большая часть кода размещена в одном кадре, эта проблема устраняется. Обычно лучшее место для размещения кода — это первый кадр.
Когда в первом кадре расположен большой код, разделите его на части комментариями, чтобы повысить читабельность, например:
/*** Раздел функций для кнопок ***/
/*** Константы и переменные ***/
Одно исключение при размещении всего кода в первом кадре возникает в случае предварительной загрузки клипов. В приложении с предзагрузкой клипов размещение всего кода в первом кадре может быть невозможным. Но все равно нужно стремиться к централизации кода.
В клипах с прелоадером начинайте написание кода со второго кадра. Используйте два слоя для кода — один слой для функций, а другой слой для действий, связанных с различными состояниями приложения.
Помните, что функции и объекты, созданные программными методами ActionScript, существуют на протяжении всего клипа. Вместе с этим продолжает действовать механизм создания и уничтожения мувиклипов, базирующийся на состояниях временной диаграммы. Временная диаграмма должна отражать эту взаимосвязь.
Рисунок 2: Пример временной диаграммы ("таймлайна") с предзагрузчиком.
Формат временной диаграммы (таймлайна)
Избегайте использования названий слоев, принятых по умолчанию (Layer 1, Layer 2, и т.п.), так как это может привести к путанице. Слои таймлайна должны называться интуитивно понятным образом. Слои также должны быть сгруппированы вместе путем использования папок там, где это имеет смысл. Например, следует располагать все слои с кодом ActionScript на самом верху стека слоев, чтобы в таймлайне можно было легко найти весь код.
Блокирование неиспользуемых в данный момент слоев — хорошая практика. Это предупреждает случайные изменения в документе.
Инициализация
Инициализация приложения используется для задания его начального состояния. Функция инициализации вызывается в приложении в первую очередь и только один раз — программой. Все остальные вызовы этой функции должны управляться событиями.
// кадр 1
this.init();
function init() {
if (this.inited != undefined)
return;
this.inited = true;
// здесь идет код инициализации...
}
Используйте файлы #include .as
Любой определенный вами объект или библиотека созданных вами функций должны определяться во внешнем ActionScript файле и использоваться в качестве файла включаемого (include) файла. Например, если приложение использует объекты с именами "Foo" и "Bar", каждый из этих объектов должен содержаться в отдельном включаемом ActionScript-файле. Имя включаемого файла должно соответствовать имени объекта, например:
Foo.as
Bar.as
Библиотеки многократно используемых функций должны также определяться во включаемых файлах ActionScript. В этом случае имя включаемого файла должно состоять из букв нижнего и верхнего регистра (начинаясь с буквы нижнего регистра), например:
stringUtils.as
Такая система использования включаемых файлов делает объектно-ориентированный код ActionScript более легким для идентификации. Но более важно то, что код становится модульным, позволяя разработчикам создавать ActionScript-библиотеки объектов и функций. Только необходимый для приложения код включается из библиотеки внешних файлов.
Кроме того, используя внешние файлы ActionScript, разработчики могут интегрировать файлы кода с системой управления версиями, например, такими, CVS или SourceSafe. Это облегчает отслеживание исходного кода.
Используйте ключевое слово var для локальных переменных
Все локальные переменные должны использовать ключевое слово var. Это предохраняет переменные от глобального доступа и, что более важно, предохраняет переменные от неумышленного переназначения[]. Например, следующий код функции не использует ключевое слово var при объявлении переменной, что приводит к (неумышленной) перезаписи внешней переменной, не относящейся к функции:
counter = 7;
function loopTest()
{
trace(counter);
for(counter = 0; counter < 5; counter++)
{
trace(counter);
}
}
trace(counter);
loopTest();
trace(counter);
Этот код выводит:
7
7
0
1
2
3
4
5
В данном случае переменная counter, находящаяся на основной временной диаграмме, переназначается переменной counter, которая находится внутри функции. Ниже приведен исправленный код, который использует ключевое слово var, для объявления обеих переменных. Использование декларации var в функции устраняет ошибку вышеуказанного кода:
var counter = 7;
function loopTest()
{
trace(counter);
for(var counter = 0; counter < 5; counter++)
{
trace(counter);
}
}
trace(counter);
loopTest();
trace(counter);
Исправленный код выводит следующее:
7
7
0
1
2
3
4
7
Из последней строки видно, что не принадлежащая функции переменная counter сохранила свое значение после вызова функции.
Используйте относительные пути для задания области видимости
Область видимости должна быть задана для каждой переменной. Исключением являются параметры функций и локальные переменные. Область видимости переменных должна задаваться относительно их текущего положения, если это возможно. Использование _root для задания области видимости переменной не рекомендуется, поскольку это ограничивает мобильность кода. Вместо _root используйте ключевое слово _parent или this, например:
this.myVar.blah = 100; // определяйте область видимости для переменных, используя относительную адресацию, как в этой строке
_root.myMovieClip.myVar.blah = 100; // НЕ задавайте область видимости переменных, используя абсолютные ссылки, как в этой строке
Если все же приходится использовать абсолютную адресацию к главному таймлайну, вместо использования _root создайте переменную-ссылку на главный таймлайн. Это позволит изменять всего один параметр, если структура таймлайна изменится. Чтобы создать удобную ссылку на основной таймлайн клипа, добавьте такую строку кода к основному таймлайну:
_global.myAppMain = this; // (замените "myApp" названием вашего приложения)
После вставки этой строки в ваше приложение, используйте _global.myAppMain.someFunction, чтобы ссылаться на функции главного таймлайна. Это позволяет изменять структуру приложения, не нарушая область видимости вызовов функций и переменных в клипе.
Избегайте размещения кода на мувиклипах и кнопках
Не размещайте код на мувиклипах и кнопках, если в этом нет крайней необходимости. Если код все же должен быть размещен на мувиклипе или кнопке, используйте при этом минимальное количество кода. С этой точки зрения лучше всего вызывать функции, как в следующем примере:
myButton.onMouseDown = function() {
_parent.doMouseDown(this);
}
Использование вызова функции переносит всю функциональность на основной таймлайн мувиклипа.
Кадры как состояния приложения
Разработчики часто пишут построчный код (программу) прямо на отдельных кадрах, чтобы определять состояния приложения. Такая практика нежелательна.
Правильная организация кода базируется на описании состояний приложения в ключевых кадрах. Поместите в функцию любое действие, необходимое для конкретного состояния, а затем вызывайте эту функцию как единственное действие в соответствующем ключевом кадре.
Продолжая организацию приложения, создайте в клипе два слоя с кодом. В первом кадре первого слоя, существующего по всей длине клипа, располагается самая большая часть кода. Второй слой содержит действия, необходимые ключевым кадрам для изменения состояний приложения. Единственный код в каждом ключевом кадре второго слоя должен быть вызовом функции для конкретного состояния (вызываемая функция должна быть описана в первом кадре первого слоя). Для создания некоторых состояний (например, для вызовов диалоговых окон) допускается использование мувиклипов, присоединенных с помощью действия attachMovie во время выполнения приложения.
Комментирование кода
Комментируйте код всегда. Для разработчика комментарии являются хорошей возможностью рассказать, для чего написан код и что он должен делать. Комментарии должны подтверждать каждое решение — в любом месте, в котором вы производили выбор и принимали решение о способе кодирования, нужно вставлять комментарий с обоснованием сделанного выбора.
Когда вы пишете "обходной" код для решения специфических, нестандартных задач вашего приложения, добавьте комментарий, из которого другие разработчики поймут, в чем заключалась сложность, и как вы ее обошли. Это облегчает понимание специфических проблем теми разработчиками, которые еще могут с ними столкнуться. Это просто облегчает им жизнь.
Вот пример простого комментария для переменной:
var clicks = 0; // переменная для подсчета нажатий кнопки
Блочные комментарии полезны для больших кусков текста:
/*
Инициализирует переменную clicks, хранящую количество нажатий кнопки.
*/
Ниже приведены некоторые общие методы для указания особо важных комментариев (в скобках предложены русскоязычные аналоги):
// :TODO: topic (// :СДЕЛАТЬ: тема)
Указывает, что код нужно доделать или сделать что-то еще.
// :BUG: [bugid] topic (// :ОШИБКА: [номер ошибки] тема)
Показывает известную ошибку ("глюк", "баг"). Комментарий также должен объяснять, в чем состоит проблема, и содержать "bug ID" (номер "бага"), если необходимо.
// :KLUDGE: (// :ВОЗМОЖЕН ДРУГОЙ ВАРИАНТ:)
Показывает, что соответствующий код не является элегантным или лучшим решением. Этот комментарий оповещает других, что в будущем код следует усовершенствовать.
// :TRICKY: (// :РИСКОВАНО:)
Уведомляет разработчиков, что код со многим взаимосвязан (его изменение повлечет изменения в других местах). Это совет разработчику: "подумай, прежде чем что-то изменять".
Пример
/*
:TODO: msw 654321: проблемы с отображением больших объемов данных из БД. Наверное, следует разбивать данные на более мелкие порции для каждого запроса.
*/
Наследование объектов
Задание свойства "__proto__" для создания наследования практиковалось в Flash Player 5. Эта практика не поддерживается в Flash Player 6, и ее использование не рекомендуется. Свойство __proto__ должно рассматриваться как свойство только для чтения (read-only). Правильный способ создания наследования — это создание цепочки прототипов. Чтобы создать цепочку прототипов, установите свойство "prototype" функции конструктора подкласса (subclass) в экземпляр надкласса (superclass), используя следующий синтаксис:
ChildClass.prototype = new ParentClass();
Пример этой практики:
function Shape()
{
}
function Rectangle()
{
}
Rectangle.prototype = new Shape();
Следующая практика НЕ рекомендуется:
Rectangle.prototype.__proto__ = Shape.prototype;
Если разработчики беспокоятся, что такая форма наследования приведет к тому, что весь конструктор будет признан необязательным, следующий код поможет предотвратить это:
_global.SuperClassConstructor = function() {
if (this._name!=undefined) {
// код конструктора размещается здесь
}
}
В вышеприведенном примере код конструктора не будет выполнен, потому что еще не определен экземпляр. Заметьте, что этот код работает только в классах, основанных на классе MovieClip.
Область видимости
Flash Player 6 поддерживает концепцию "цепочки областей видимости" (как определено в стандарте ECMA-262). Таким образом, устранены значительные недостатки "прямой области видимости" в Flash Player 5.
Цепочка областей видимости — это список ActionScript-объектов. Flash Player ищет идентификатор, начиная с последнего элемента в цепочке областей видимости, и продолжает подниматься по цепочке, пока не найдет его.
Цепочка областей видимости для типичного сценария ActionScript:
Объект Global;
Объект MovieClip;
Локальные переменные.
Конструкция with временно добавляет объект в конец цепочки областей видимости. Когда действие with прекращается, объект удаляется из цепочки областей видимости.
При определении функции текущая цепочка областей видимости копируется и хранится в объекте функции. При вызове функции происходит переключение текущей цепочки областей видимости на цепочку областей видимости объекта функции, а в конец цепочки добавляется новый объект Local Variables.
В Flash 5 область видимости функции всегда была следующей:
Объект Global;
мувиклип, содержащий функцию;
Локальные переменные.
Список областей видимости никогда не содержал более трех пунктов, кроме случая с использованием with. Это было отклонением от стандарта ECMA-262, и область видимости метода всегда находилась в мувиклипе, содержащем метод, а не в месте определения этого метода.
В Macromedia Flash Player 6 при определении метода мувиклипа вне самого мувиклипа цепочка областей видимости метода будет содержать внешний объект, а не объект мувиклипа, для которого определяется метод. В таком случае в теле определяемого метода необходимо использовать ключевое слово this, чтобы используемые в этом методе идентификаторы ссылались на объект мувиклипа, а не на внешний объект.
Имейте в виду, что поддерживается обратная совместимость с Flash Player 5. Для среды разработки Flash 5 применимы те же правила использования области видимости, что и для Flash Player 5.
Предосторожности использования оперативной памяти
Текст. Каждый отдельный текстовый объект использует 10 КБ памяти. Это относится к динамическим текстовым полям, полям для ввода текста и статическим текстовым полям, использующим шрифты устройств ("device fonts"), например, "_sans".
Мувиклип. Каждый мувиклип использует около 1 КБ памяти. Это число может стремительно возрастать при увеличении количества используемых мувиклипов. Имейте в виду, что графические символы (graphic) не обладают такими высокими требованиями к памяти, как мувиклипы.
Объекты функций. Каждый объект функции создает два объекта ActionScript, вместе занимающие 700 байтов. Создание объекта функции для каждого экземпляра объекта — дорогое удовольствие с точки зрения расхода памяти. Рекомендуется всегда использовать прототипы. Прототипы создаются только один раз и помогают избежать неоправданного расходования памяти.
Предварительная загрузка
Главная проблема создания компонентов, хорошо согласовывающихся с процессом предварительной загрузки — это минимизация количества объектов, загружающихся перед первым кадром. Символы в первом кадре загружаются прежде, чем в проигрывателе сможет отобразиться какая-либо графика. Это означает, что даже компонент прелоадера не появится, пока не будут загружены все символы с пометкой "Export in First Frame" (экспортировать в первом кадре). Поэтому любой код ActionScript, обрабатывающий действия пользователя, должен всегда помещаться в кадре, следующем после кадра с прелоадером.
Принципы присвоения имен
Во-первых, схема присвоения имен должна быть последовательной, а имена должны быть удобными для чтения и понимания. Это означает, что имена должны быть понятными словами или фразами. Первичная функция или назначение любого объекта должны быть очевидными из его имени. Так как типы переменных в ActionScript контролируются динамически, то имя должно также содержать суффикс, определяющий тип объекта, на который ссылается имя. Самый естественный случай имен — это фразы типа "существительное-глагол" или "прилагательное-существительное". Например:
Имя клипа — "my_movie.swf";
Переменная для добавления к URL — "course_list_output" (вывод списка курсов);
Компонент или объект — "ProductInformation" (информация о продукте)
Переменная или свойство — "userName" (имя пользователя)
Имена функций и переменных должны начинаться со строчной буквы (a, b, c, ..., x, y, z). Имена объектов и конструкторов объектов должны начинаться с заглавной буквы (A, B, C, ..., X, Y, Z). Использование смешанных регистров символов рекомендуется в случае именования переменных. Другие форматы именования приемлемы, если они используются последовательно во всем проекте. Имя переменной может содержать только буквы, числа и символы подчеркивания. Не начинайте имя переменной с числа или символа подчеркивания. Неправильными именами переменных будут следующие:
_count = 5; // начинается с символа подчеркивания
5count = 0; // начинается с числа
foo/bar = true; // содержит символ "слэш"
foo bar = false; // содержит пробел
Кроме того, в качестве имен переменных нельзя использовать ключевые слова ActionScript. Также избегайте использования в качестве имен переменных слов из популярных конструкций программирования, даже если Macromedia Flash Player к настоящему времени не поддерживает эти конструкции в качестве ключевых слов. Это дает больше уверенности в том, что будущие версии проигрывателя не вступят в конфликт с вашим приложением. Например, не нужно делать так:
var = "foo";
MovieClip = "myMovieClip";
switch = "on";
case = false;
abstract = "bar";
extends = true;
implements = 5;
Так как ActionScript совместим с ECMAScript, авторы приложений могут ознакомиться со списком зарезервированных слов, приведенных в . Пока Flash MX не поддерживает константы, разработчики должны применять следующий принцип: имена переменных набирать символами нижнего регистра, а имена переменных-констант — только символами верхнего регистра. Например:
course_list_output = "foo"; // переменная
courseListOutput = "foo"; // переменная
BASEURL = http://www.foo.com; // константа
MAXCOUNTLIMIT = 10; // константа
MyObject = function{}; // функция конструктора
f = new MyObject(); // объект
Редактор кода ActionScript в среде разработки Flash MX имеет встроенную функцию "завершения кода". Эта функция помогает вам писать код, предоставляя в виде выпадающего списка возможные варианты завершения кода. Чтобы вы могли пользоваться этим преимуществом, имена ваших переменных должны соответствовать определенному формату. В этом встроенном формате суффикс имени переменной является строкой, указывающей на тип переменной. Ниже приведена таблица поддерживаемых суффиксов:
Таблица 3: Суффиксы для активации функции завершения кода
Тип объекта | Суффикс | Пример |
String | _str | myString_str |
Array | _array | myArray_array |
MovieClip | _mc | myMovieClip_mc |
TextField | _txt | myTextField_txt |
Date | _date | myDate_date |
Sound | _sound | mySound_sound |
XML | _xml | myXML_xml |
Color | _color | myColor_color |
Button[] | _btn | myButton_btn |
TextFormat | _fmt | myTextFormat_fmt |
XMLSocket | _xmlsocket | myXmlSocket_xmlsocket |
FListBox | _lb | myFListBox_lb |
FScrollBar | _sb | myFScrollBar_sb |
FComboBox | _cb | myFComboBox_cb |
FScrollPane | _sp | myFScrollPane_sp |
FMessageBox[] | _mb | myFMessageBox_mb |
FDraggablePane | _dp | myFDraggablePane_dp |
FTicker | tick_ (префикс) | tick_myFTickerMain |
FTree | _tree | myFTree_tree |
FTreeNode | _tn | myFTreeNode_tn |
FIconButton | _ib | myFIconButton_ib |
FProgressBar | _pr | myFProgressBar_pr |
Вы увидите эту функцию в действии, если наберете в панели Actions один из примеров и символ точки. Например, введите myString_str. — появится выпадающий список свойств и методов для объекта String. Не забывайте о точке:
Рисунок 1: Пример действия помощника завершения кода.
Наконец, имена всех .swf-файлов должны быть набраны в нижнем регистре, а слова в именах должны быть разделены символом подчеркивания (например, "lower_case.swf"). Обсуждение соглашений об именовании включаемых файлов ActionScript см. в разделе "".
Помните, что вышеуказанные рекомендации являются общими принципами. Важнее всего, выбрав определенную схему именования, использовать ее последовательно во всем приложении или проекте.
_Root против _global
Важно понимать разницу между _global и _root. Ссылка _root уникальна только в рамках каждого загруженного .swf-клипа. Ссылка _global применима ко всем клипам в пределах проигрывателя. В общем случае для ссылок лучше использовать _global , а не _root.
Создание объектов
При создании объекта включайте в его прототип функции и свойства, распространяемые на все экземпляры объекта. Это гарантирует, что в оперативной памяти будет находиться только одна копия каждой функции. Сделайте своим правилом не определять функции внутри конструктора — это создает для каждого экземпляра объекта отдельную копию этой же функции и приводит к излишнему расходованию оперативной памяти.
Пример лучшей практики создания объекта:
MyObject = function()
{
}
MyObject.prototype.name = "";
MyObject.prototype.setName = function(name)
{
this.name = name;
}
MyObject.prototype.getName = function()
{
return this.name;
}
Следующий пример демонстрирует неправильный метод создания объекта:
MyObject = function()
{
this.name = "";
this.setName = function(name)
{
this.name = name;
}
this.getName = function()
{
return this.name;
}
}
В первом примере каждый экземпляр объекта MyObject указывает на одни те же функции и свойства, определенные в прототипе объекта. При этом в оперативной памяти находится только одна копия getName(), независимо от количества созданных объектов MyObject.
Во втором примере каждый созданный экземпляр MyObject создает копию каждого свойства и функции. Эти дополнительные свойства и функции занимают дополнительную память, и в большинстве случаев не предоставляют при этом никаких преимуществ.
Стандарты Actionscript
Приложения Macromedia Flash в основном строились без учета каких-либо стандартов и основополагающих принципов. Такая гибкость способствует решению задач множеством способов, и это хорошо, но приложение становится непроходимым лесом для всех кроме автора— такой код сложен для понимания. Даже автор, спустя некоторое время, будет с трудом читать написанный им же код. Если разработчик не может понять код в приложении, то код будет трудно отлаживать, вносить в него изменения или использовать его многократно.
Типы данных и их размеры в файлах
Таблица 2: Основные объекты ActionScript
Тип объекта | Размер, байтов |
Короткая строка (7 символов) | 55 |
Число | 22 |
Объект | 340 |
Пустой мувиклип | 800 |
Объект функция | 700 |
Текстовое поле | 9 500 |
Таблица 3: Простые .swf-файлы
Тип простого .swf-файла | Размер, байтов |
Пустой .swf-файл | 250 000 (большая часть памяти уходит на встроенные объекты ActionScript) |
Пустой .swf-файл с определенным компонентом | 750 000 (большая часть отводится самому .swf-файлу и объекту функции компонента) |
Таблица 4: Объекты компонентов (по одному экземпляру)
Объект компонента | Размер, байтов |
PushButton | 60 000 |
CheckBox | 55 000 |
Пустой ListBox | 490 000 |
Этот документ не является завершенным
Этот документ не является завершенным набором лучших методов создания кода. Macromedia продолжает расширение документа, основываясь на информации от людей, создающих и продвигающих критически важные по своему значению приложения для Flash Player. Этот документ живой, он управляется сообществом разработчиков, как это всегда было с ActionScript и Macromedia Flash Player с самого начала их существования.
оригинал:
перевод:
рецензент: fix
Примечания:
[] Начиная с этой строки, идут суффиксы, любезно подсказанные .
[] Эти суффиксы активизируются при установленном Flash UI Component Set 2, который можно скачать с сайта Macromedia.
[] Английское слово "overwriting" переведено как "переназначение", что соответствует терминологии, принятой в статьи "Объектно-ориентированное программирование в Flash 5". Весьма полезная статья.
Чего нет в демонстрационной версии программы?
Много чего, например:
Автоматической привязки компонентов и связей к линиям сетки, что значительно упрощает рисование; Изменяемой размерности линий сетки; Наличия в меню реализованных пунктов Select, Copy, Paste; Сохранения и восстановления нарисованной схемы узла на диске.
Будем считать это заданием на будущее.
Всего хорошего, Евгений.
Демонстрация метода.
Загрузить демонстрационную версию программы можно отсюда (80 кб).
Выберем в качестве объектов композиции модели различных микросхем, а затем для демонстрации метода объединим их в некоторый узел. Отметим, что выбор данной области для демонстрации метода не имеет большого значения, просто это направление нам ближе.
В левой части загруженного приложения находится окно Tree с набором микросхем. Выберите несколько любых микросхем (далее объектов), щелкнув по каждой из них мышью. Расположите объекты на рабочем столе, так как Вы считаете нужным. Обратите внимание — объекты можно свободно перемещать, так как работает функция drag-and-drop.
Работает так же контекстное меню, причем работает оно избирательно. Если Вы щелкнете правой мышью на пустом месте области проектирования, то увидите множество пунктов системного меню. Если щелкнете над объектом или связью (о них чуть позже), то к системному меню добавятся новые подпункты. Выбрав подпункт «Delete Component», можно удалить объект с рабочего стола.
Чтобы объединить пару объектов связью, достаточно щелкнуть левой кнопкой мыши по любой из контактных площадок объекта, затем, не отпуская кнопки, переместить мышь на другой объект и отпустить кнопку мыши над нужной контактной площадкой. Будет создана линия связи между двумя микросхемами. Аналогичным образом, можно связать любое число объектов любым количеством связей. Программа не позволяет проводить повторные связи и связи между контактами одной и той же микросхемы.
Если разрешение экрана Вашего монитора велико и работать трудно, включите нужное увеличение, и работать станет значительно удобнее. Сделать это можно либо из пункта View Flash Player, либо из контекстного меню.
Отметим, что любая линия связи может иметь какое угодно число составных частей (звеньев). Чтобы изменить форму линии, достаточно щелкнуть по ней левой кнопкой мыши, затем, не отпуская кнопки, переместить мышь в любое место рабочего стола и отпустить. Обратите внимание, что цвет редактируемой линии изменяется. Выбрав подпункт «Delete Line» в контекстном меню, можно удалить ненужную линию связи.
Объект, объединенный в схему, может быть перенесен в любую точку стола проектирования, линии связи последуют за ним, причем, изменяться будет только последнее (первое) звено cвязи. Таким образом сохраняется единое целое конструкции.
Поместив на экран некоторое число компонентов, и связав их можно получить приблизительно такую картину. Если приложить усилие и выровнять компоненты и связи, то получим читаемую схему узла. Итак, мы имеем возможность связать объекты. Но что это дает?
Каждый объект (в данном случае модель микросхемы) имеет свою функциональность, которая реализована в виде класса с определенным набором свойств, методов, обработчиков событий. Связывая объекты программа конструирует модель композиции. В данном случае мы получим модель узла, собранного из моделей микросхем, в другом случае - это может быть SQL запрос, в третьем - еще что-то. Это зависит от выбранной области знания и требует создания соответствующего программного модуля проектирования.
Примечание. Статья описывает лишь метод объединения объектов и никак не затрагивает вопросы проектирования узлов на микросхемах.
Как устроены объекты.
Объекты, между которыми проводятся связи, так же наследники класса MovieClip. Создаются они динамически из одноименных классов при выборе элемента внутри компонента Tree. Например: la3 = new la3(nameLa3, numberLayer, numberLa3);
Однако отметим, что в качестве объектов могут использоваться любые визуальные компоненты, имеющие обработчики onPress(), onRelease(), onMouseUp() а не только наследники MovieClip. Но при этом нужно иметь в виду, что работы может значительно прибавиться.
В качестве «горячих областей» (hitArea) применяются также MovieClip. Количество горячих областей внутри объекта никак не ограничивается, однако, координаты их, определяются при создании класса объекта.
Несмотря на то, что каждый объект имеет несколько «горячих» областей, обработчик событий для всех дочерних областей объекта один. Реализовано это, например, для события onPress следующим образом: function _onPress(parametr){ // Переберем все дочерние MovieClip элемента _this var _this = parametr; var obj:Object; for(j in _this){ if((typeof (_this[j]) == "movieclip")) { obj= _this[j]; // Найдем горячую область, по которой щелкнули мышью if (obj.hitTest(_root._xmouse, _root._ymouse, true)) {...}
} ......... } }
где parametr — несущий MovieClip для дочерних областей.
Как устроены связи.
Связи между объектами — это суть наследники класса MovieClip, создаются динамически в процессе рисования и имеют обработчики событий onPress(), onRelease(), а также обработчик контекстного меню itemHandler(_obj, menuItem), где:
_obj — имя выбранной пользователем связи; menuItem — подпункт контекстного меню.
Количество звеньев в связи (в линии) ничем не ограничивается, другими словами, линия может быть как угодно сложной.
Примечание. В определениях «как угодно сложной» или «ничем не ограничивается» есть немного от лукавого. Более точное определение может звучать так: «сложность композиции зависит от мощности Вашего компьютера».
Все связи сохраняются в двух специальных массивах: arrayLines({startNameElement, endNameElement, lineObject ,,,,}) и arrayPoint({nameLine, x,y }); где,
startNameElement — стартовый элемент; endNameElement — финишный элемент; lineObject, nameLine — имя линии; x, y — координаты звена линии.
Первый массив устанавливает соответствие между двумя связываемыми объектами и именем связи (линии). Второй массив содержит все множество координат точек изменений, через которые проходит линия в формате: имя линии — координаты точки.
В данной реализации нет необходимости создавать связи направленными и различать их по типам. Однако нет ограничений для того, чтобы сделать связи направленными и разными по качеству (иногда это требуется). Придать связям направленность и качество можно из контекстного меню, добавив туда дополнительные пункты и дописав к ним обработчики.
Композиции объектов
,
Статья содержит описание графического метода, при помощи которого можно создавать композиции из объектов в различных областях знаний. Метод легко развивается и трансформируется под конкретную функциональность объектов. Язык реализации ActionScript 2.0, для больших проектов С++.
Несколько слов о среде проектирования.
В состав основного модуля программы входит небольшое число функций, перечислим некоторые из них: onLoad, onEnterFrame
, и другие.
Общий объем текста программы без учета классов микросхем содержит около 600 строк.
Описание задачи.
Предлагается метод и его реализация в виде программы, которая позволяет объединять визуальные объекты при помощи мыши в единую композицию, подобно тому, как это делается, например, в конструкторе SQL запросов Microsoft Access.
Цель работы.
Оценить возможности Macromedia Flash, как инструмента для создания моделей микросхем. Сочетание редактора для рисования графических объектов и объектно-ориентированного языка для управления этими объектами – это хорошая предпосылка для выбора Flash в качестве инструмента.
Описание интерфейса программы.
Верхняя часть приложение содержит меню, которое введено по большей части на перспективу развития. Меню создано на основе UI компонента MenuBar.
Иерархически раскрывающийся список содержит перечень микросхем для выбора пользователем. Полный список микросхем находится в XML файле на сервере, и при необходимости может быть подгружен в приложение. Для организации списка использован UI компонент Tree.
Генератор импульсов предназначен для задания входной импульсной последовательности по каждому из каналов. В настоящее время программа содержит четыре входных канала, однако, по мере создания новых моделей требующих большее число каналов, число их в приложении увеличивается. Для каждого канала может быть установлена отдельная импульсная последовательность с требуемой длиной импульса и скваженностью. Генератор выполнен на UI компонентах ComboBox, RadioButton, NumericStepper.
Задержка срабатывания микросхемы выполнена на UI компоненте NumericStepper.
В нижней части приложения находиться панель состояния, в ней отражаются неопределенные или ошибочные состояния моделируемой микросхемы.
Правая часть экрана приложения содержит входные и выходные импульсные последовательности.
Пользоваться приложением достаточно просто: следует выбрать микросхему и задать ей входные импульсные последовательности. Программа отобразит входные и выходные графики и возможно диагностику.
Организация программы.
Все модели микросхем выполнены в виде отдельных классов и содержат только логику работы микросхем. Классы микросхем не содержат кода визуализации входных или выходных последовательностей. Другими словами, содержимое и представление полностью разделены, класс микросхемы не делает ничего, чтобы отобразить какой либо график.
Входной информацией для объекта класса микросхемы служит многомерный массив событий, поступающий от входных каналов. Например, в модели микросхемы RS/D триггера любое событие анализируется с учетом всех четырех входных воздействий R,S,D,C.
Прорисовкой входных и выходных графиков занимаются специальные подпрограммы. Входом для программы прорисовки входных графиков служат параметры импульсных последовательностей, исходящих от генератора, и определенные пользователем. Входом для программы рисования выходного графика служит массив выходных значений объекта микросхемы.
Ниже приведен пример класса модели R-S триггера.
//*************************************** // Логический элемент : R-S триггер // автор : Вересов Евгений // дата создания : 10.11.05 // vers.: 1.0 //*************************************** class tp2 { private var input : Array; // Массив для входа private var output : Array; // Выходной массив private var s : Number // Буфер первого канала private var r : Number // Буфер второго канала private var sost : Number // Состояние триггера
// Конструктор public function tp2(){ this.input = new Array(); this.output = new Array(); sost = 0; s = null; r = null; }
// История точек входа public function setInput(step:Number,value:Number, channel:Number):Void{ this.input.push({x:step,y:value,ch:channel}); }
// формирование выхода public function out():Array { input.sortOn("x"); var i = 0;
for(i=0; i<input.length;i++){ // Сохраним текущее значение if(input[i].ch==1) {s = input[i].y;} if(input[i].ch==2) {r = input[i].y;}
// Если s ==0 r==1 if((s==0) && (r ==1)) {output.push({x : input[i].x, y : 1});sost=1}
// Если s ==1 r==0 if((s==1) && (r ==0)) {output.push({x : input[i].x, y : 0});sost=0}
// Если s ==1 r==1 if((s==1) && (r ==1)) {output.push({x : input[i].x, y : sost});}
// Если s ==0 r==0 if((s==0) && (r ==0)) {output.push({x : input[i].x, y : null});} } return output; } }
Предмет моделирования.
На первом этапе, для моделирования выбраны микросхемы ТТЛ серии SN74/54, у нас это серии микросхем: 155, 555, 1531, 1533. С точки зрения написания модели не имеет существенного значения тип используемой технологии, по которой изготавливается микросхема: ТТЛ, ЭСТЛ или КМОП, хотя конечно, это будут разные модели. Гораздо более важным является степень интеграции микросхемы. Например, написать модель R-S триггера это одно, а модель АЦП, функционирование которого начнется только после предварительной записи в него ряда управляющих слов, это совершенно другое с точки зрения затрат временим и объема кода.
К моменту написания статьи реализованы модели простых микросхем: ЛН1 – логическое НЕ, ЛА3 – логическое 2И-НЕ, ЛЕ4 – логическое 3ИЛИ-НЕ, ТР2 – RS триггер, ТМ2 – RS/D триггер.
Предположение.
Предполагается, что динамические модели микросхем, адекватные прототипам, созданные и размещенные в Internet, окажутся востребованными.
Такая модель выглядит так же, как на экране осциллографа выглядят входные и выходные последовательности реальной микросхемы. Модель позволяет увидеть поведение оригинала при любых входных последовательностях, в том числе, и при таких, при которых состояние микросхемы становиться неопределенным.
На практике при отладке узлов на микросхемах средней степени интеграции необходимы: макет узла, источники питания, генератор импульсов, осциллограф. При разработке прикладной системы на основе микроконтроллера все несколько сложнее, приходиться отлаживать как код программы, так и схемотехнику системы. При проектировании и отладке систем на основе микроконтроллеров используют симуляторы, внутрисхемные эмуляторы, дебаггеры.
Технология моделирования.
Автор использует событийный метод моделирования. Суть его состоит в том, что обработке подлежат лишь события. Под событием понимается любое изменение входного воздействия или времени задержки срабатывания микросхемы, например, изменение потенциала или фронта импульса. Однако подчеркну, что речь идет о логическом, а не электрическом моделировании, – у этих двух направлений совершенно разные точки приложения усилий.
Событийное моделирование хорошо тем, что позволяет использовать минимум ресурсов процессора пользователя и канала доставки приложения.
Требования, предъявляемые к приложению.
В настоящее время модели микросхем включены в состав приложения ControlPanel.
Приложение соответствует следующим требованиям:
Модели микросхем, по возможности точно отражают поведение оригиналов.
Выходные сигналы генерируются быстро, без видимой задержки.
Пользователь может задавать любые входные последовательности, в том числе и такие, при которых состояние микросхемы становится неопределенным.
Объем загрузочного модуля приложения не превышает 100-150 кб. В противном случае будет использована оверлейная структура организации программы.
Рисование с помощью ActionScript во Flash MX
В этом уроке мы научимся рисовать различные графические примитивы - линии, кривые и заливки - средствами ActionScript. Предполагается, что вы уже немого знакомы с этим языком и вам не нужно объяснять его основы. Если вы новичок в ActionScript, посмотрите другие статьи, в частности
Для рисования примитивов нам потребуются следующии функции объекта MovieClip:
beginFill ([rgb[, alpha]]) beginGradientFill (fillType, colors, alphas, ratios, matrix) clear() curveTo (controlX, controlY, anchorX, anchorY) endFill() lineStyle ([thickness[, rgb[, alpha]]]) lineTo (x, y) moveTo (x, y)
Начнем с функций moveTo() и lineTo(). Они используются для рисования линий. moveTo() устанавливает позицию "карандаша" (курсора) в позицию x, y. lineTo() проводит линию от позиции, установленной moveTo(), до позиции указанной параметрами x, y в самой функции lineTo().
Но, прежде чем рисовать линии этими функциями, нужно установить свойства линии функцией lineStyle(). У неё три необязательных параметра: thickness - указывает толщину линии; rgb - цвет (а-ля 0x56FFCC); alpha - значение прозрачности. Если параметр не указан, его значение считается равным нулю.
Вот пример кода, который рисует синий квадрат в текущем объекте MovieClip:
lineStyle(1, 0x0000FF);
moveTo(100, 100);
lineTo(200, 100);
lineTo(200, 200);
lineTo(100, 200);
lineTo(100, 100);
Координатная решетка любого объекта типа MovieClip начинается с верхнего левого угла и растет вправо вниз, как видно на рисунке выше.
Для закраски нарисованных фигур используются функции beginFill() и endFill(). Функцию beginGradientFill() для создания градиентной закраски мы рассмотрим позже.
beginFill() включает режим закраски. После её вызова, все нарисованные контуры будут закрашиваться, образую замкнутые фигуры. beginFill() имеет два необязательных параметра: rgb указывает цвет закраски, alpha - прозрачность.
endFill() отключает режим закраски.
Рекомендуется для рисовательной деятельности создавать пустой объект при помощи функции createEmptyMovieClip(). Этой функции передаются два параметра: имя экземпляра клипа, и целое значение, указывающее глубину клипа на экране, относительно других клипов.
Вот пример c использованием функций beginFill() и endFill():
_root.createEmptyMovieClip("myClip", 1);
myClip.lineStyle(2,0x234567);
myClip.beginFill(0x7878FF);
myClip.moveTo(70,20);
myClip.lineTo(20,100);
myClip.lineTo(120,100);
myClip.lineTo(70,20);
myClip.endFill();
myClip.lineStyle(4, 0x0078DD);
myClip.moveTo(140,20);
myClip.lineTo(190,20);
myClip.lineTo(190,70);
myClip.lineTo(140,70);
myClip.lineTo(140,20);
myClip.beginFill(0x00FF00, 30);
myClip.lineStyle(1, 0xDC2323);
myClip.moveTo(230, 20);
myClip.lineTo(350, 100);
myClip.lineTo(350, 20);
myClip.lineTo(230, 100);
myClip.lineTo(230, 20);
Вот как выглядит результат работы этого скрипта:
Рассмотрим функцию, которая рисует кривые: curveTo(controlX, controlY, anchorX, anchorY). Функция имеет четыре обязательных параметра. При отсутствии хотя бы одного из них она не срабатывает. Началом кривой считается текущая позиция курсора ("карандаша"), которая устанавливается при помощи moveTo(), или же позицией, в которой закончили черчение функции lineTo() или curveTo(). Конец кривой указывается параметрами anchorX и anchorY. Параметры controlX и controlY указывают точку, к которой направлены начало и конец линии. Для наглядности на рисунке ниже обозначены все точки.
Вот пример кода, и рисунка, который получается в результате его исполнения:
lineStyle(1);
beginFill(0xFF9921, 20);
moveTo(70,20);
curveTo(120,20,120,70);
curveTo(120,120,70,120);
curveTo(20,120,20,70);
curveTo(20,20,70,20);
endFill();
moveTo(140,120);
curveTo(140,20,160,20);
curveTo(180,20,180,120);
Наконец, рассмотрим самую сложную функцию beginGradientFill (fillType, colors, alphas, ratios, matrix), которая служит для градиентной закраски.
Параметр fillType указывает тип закраски может быть равен одной из следующих строк: "linear" - линейная, "radial" - радиальная. Не забудьте, что это строки, поэтому параметры нужно указывать в кавычках.
Следующие четыре параметра представляют из себя массивы, каждый из которых мы сейчас рассмотри подробнее.
colors - массив, содержащий цвета градиента. alphas содержит alphа-канал (прозрачность) каждого цвета.
ratios содержит значения распределения цветов. Возможные значения: 0-255. Это значение указывает место в процентном соотношении, где значение цвета достигает максимума.
matrix является матрицей преобразования, которая может описываться двумя наборами значений:
a, b, c, d, e, f, g, h, i, которые представляют из себя матрицу типа
a | b | c |
d | e | f |
g | h | i |
Для обращения к свойствам объекта можно использовать инструкцию with(). Вот пример, в котором мы создаём классическую "хромовую" закраску, повёрнутую на 45 градусов.
_root.createEmptyMovieClip( "myClip", 1 );
with ( _root.myClip )
{
colors = [ 0x0066FD, 0xFFFFFF, 0xFFFFFF, 0x996600, 0xFFCC00, 0xFFFFFF];
alphas = [ 100, 100, 100, 100, 100, 100 ];
ratios = [ 0, 100, 120, 125, 165, 255];
matrix = { matrixType:"box", x:20, y:20, w:130, h:100, r:(45/180)*Math.PI };
beginGradientFill( "linear", colors, alphas, ratios, matrix );
moveto(20,20);
lineto(150,20);
lineto(150,120);
lineto(20,120);
lineto(20,20);
endFill();
}
Вот и всё! На самом деле, после небольшого количества практики, всё становится понятно и легко.
Как обычно, можно скачать все примеры к уроку: (6 k)
Удачи!
Использование методов SetVariable и GetVariable для передачи данных между Flash и CBuider
Демонстрации методов SetVariable и GetVariable приведена в проекте, который находится в файле .
Методы объявлены в SockwaveFlashObjects_OCX.h. следующим образом:
void __fastcall SetVariable(BSTR name/*[in]*/, BSTR
value/*[in]*/);
BSTR __fastcall GetVariable(BSTR name/*[in]*/);
Параметр name определяет полное имя переменной, значение которой устанавливается методом SetVariable или запрашивается методом GetVariable. Для метода SetVariable параметр value содержит устанавливаемое значение. Возврат значения переменной в методе GetVariable производится через имя метода.
Обратите внимание, что все параметры и возвращаемое значение имеет тип BSTR.
Итак, пример использования SetVariable и GetVariable
Во Flash создаем ролик, (см. рис. 9) в котором располагаем статический текст и динамический тексты.
Рис. 9. Flash ролик для демонстрации SetVariable и GetVariable
В динамическом тексте меняем его имя на CBuilderText и имя переменной на BcbText (см. рис. 10)
Рис. 10. Свойства динамического текста
Сохраняем Flash ролик под именем BcbToFlash.fla (и BcbToFlash.swf) и приступаем к созданию проекта на CBuilder (см. рис. 11).
Этот проект будет передавать во Flash ролик текст, который будет отображаться в поле динамического текста (имя этого компонента CBuilderText), меняя переменную под именем BcbText. Изменение будет происходить при нажатии на кнопку "Передать" (вызов метода SetVariable).
С помощью ComboBox1 будем менять цвет бордюра вокруг текста. Изменение будет происходить при любой модификации значения в ComboBox1. (опять же метод SetVariable).
Рис. 11. Форма для демонстрации методов SetVariable и GetVariable
И, наконец, демонстрация метода GetVariable с помощью кнопки "Запросить цвет бордюра из Flash ролика" и метки с именем Label3. При нажатии на кнопку в Label3 отобразится значение кода цвета бордюра.
Обратите внимание, что задавать цвет надо в 16-ричном виде, а возвращается он в десятичном. И, естественно, надо не забывать, что все параметры передаются и возвращаются в переменных типа BSTR. Для преобразования можно использовать функцию StringToOleStr и не забывать указывать L перед текстовыми константами.
Текст модуля для демонстрации методов SetVariable и GetVariable
//------------------------------------
#include < vcl.h>
#pragma hdrstop
#include "Unit1.h"
//-----------------------------------
#pragma package(smart_init)
#pragma link "ShockwaveFlashObjects_OCX"
#pragma resource "*.dfm"
TForm1 *Form1;
//-----------------------------------
__fastcall TForm1::
TForm1(TComponent* Owner)
: TForm(Owner)
{
ShockwaveFlash1->Movie =
ExtractFilePath(Application->ExeName) + "BcbToFlash.swf";
Label3->Caption = ShockwaveFlash1->
GetVariable (L"CBuilderText.borderColor");
}
//-------------------------------------
void __fastcall TForm1::
Button1Click(TObject *Sender)
{
ShockwaveFlash1->SetVariable
(L"BcbText", StringToOleStr(Edit1->Text));
}
//--------------------------------------
void __fastcall TForm1::
ComboBox1Change(TObject *Sender)
{
ShockwaveFlash1->SetVariable
(L"CBuilderText.borderColor", StringToOleStr(ComboBox1->Text));
}
//---------------------------------------
void __fastcall TForm1::
Button2Click(TObject *Sender)
{
Label3->Caption = ShockwaveFlash1->
GetVariable (L"CBuilderText.borderColor");
}
//--------------------------------------
Команда fsCommand и событие onFSCommand
Flash ролик может инициировать событие CBuilder, а наоборот –CBuilder во Flash, к сожалению, нет. Команда скрипта fsCommand, написанная во Flash, вызывает событие onFSCommand для объекта типа TSockwaveFlash в CBuilder и передаёт два параметра:
BSTR command – наименование команды;
BSTR args – параметры.
Значение этих параметров устанавливается командой fsCommand во Flash и, в нашем случае, могут иметь произвольные значения, которые можно использовать для обмена данными.
Приведём простой пример (см. ).
Запустим macromedia Flash и создадим ролик следующим образом.
Поместим в единственный фрейм сцены кнопку "Oval bottons - blue" из общей библиотеки (см. рис. 7).
Рис. 7. Создание кнопки.
Теперь напишем обработчик события Release для этой кнопки в котором разместим команду fscommand ("Click"). В данном примере передача второй параметр в команде fscommand не используется.
Это показано на рис. 8.
Рис. 8. Обработчик события нажатия кнопки.
Выбор текста "Click" в качестве первого параметра данном случае произволен.
Сохраним ролик под именем botton.fla в том же каталоге, в котором будем размещать создаваемый на CBuilder проект. Нажмем Alt+Ctrl+Enter, чтобы получить botton.swf.
Создадим новый проект на CBuilder. На форму поместим компонент Flash под именем ShockwaveFlash1. Сделаем программную загрузку файла botton.swf и обработку события onFSCommand как показано ниже в тексте модуля.
#include < vcl.h>
#pragma hdrstop
#include "Unit1.h"
//------------------------------------
#pragma package(smart_init)
#pragma link "ShockwaveFlashObjects_OCX"
#pragma resource "*.dfm"
TForm1 *Form1;
//-----------------------------------
__fastcall TForm1::TForm1
(TComponent* Owner)
: TForm(Owner)
{
}
//-----------------------------------
void __fastcall TForm1::Shockwave
Flash1FSCommand(TObject *Sender,
BSTR command, BSTR args)
{
AnsiString x(command); //
преобразование BSTR AnsiString
if (x == "Click")
Form1->Color = Form1->Color==
clWhite?clBtnFace:clWhite;
}
//------------------------------------
void __fastcall TForm1::
FormCreate(TObject *Sender)
{
ShockwaveFlash1->Movie =
ExtractFilePath(Application->ExeName) + "button.swf";
}
//------------------------------------
Обратите внимание, что перед использованием параметр command типа BSTR преобразуются в тип AnsiString (переменная x). Если значение переменной x равно "Click", то форма меняет свой цвет.
Параметр arg здесь не используется, но его можно применить, чтобы передать в CBuilder какую-либо информацию. Для нормальной работы не забудьте преобразовать его в AnsiString , так, как мы сделали это с переменной command.
Проигрывание Flash ролика
Создаём на CBuilder новый проект с единственной формой Form1. Из палитры компонентов ActiveX помещаем на форму компоненту ShackwaveFlash. Заносим с помощью инспектора объектов или программно в свойство ShockwaveFlash1->Movie полный путь и имя файла Flash ролика (расширение файла swf). В примерах Flash ролик помещён в тот же каталог что и exe-файл, поэтому в них свойство удобно менять программно, размещая код в обработчике события создания формы:
void __fastcall TForm1::FormCreate(TObject *Sender)
{
ShockwaveFlash1->Movie = ExtractFilePath
(Application->ExeName) + "ball.swf";
}
Установите свойства ShockwaveFlash1->Loop и ShockwaveFlash1->Playing в true. Нажмем F9, чтобы провести промежуточную проверку приложения. На форме должен двигаться и деформироваться овал. Если вместо этого на форме просто белый квадрат, то скорее всего неправильно установлено свойство ShockwaveFlash1->Movie (файл ball.swf находится в ).
Отметим, что свойства, методы и поля класса TShockwaveFlash можно просмотреть в файле ShockwaveFlashObjects_OCX.h. Рекомендуем сделать это. Информацию о методах можно найти на сайте компании Macromedia, в описании и в Help пакета Flash.
Теперь модифицируем наше приложение так, чтобы продемонстрировать возможности управления ходом выполнения Flash ролика. Вид главной формы представлен на рис. 5. Кнопки Stop, Play, Back, Forward, Rewind вызывают одноименные методы ShockwaveFlash1:
Stop – останавливает выполнение ролика;
Play – инициирует выполнение ролика с текущего фрейма;
Back - переход на предыдущий фрейм;
Forward - переход на следующий фрейм;
Rewind - переход на следующий фрейм;
При нажатии кнопок Back, Forward, Rewind, если ролик проигрывается то, перед выполнением соответствующего метода производится остановка методом Stop.
Рис. 6. Вид формы
Кнопка "Перейти" совместно с CSpinEdit1 демонстрирует использование метода ShockwaveFlash1->GotoFrame – переход на произвольно заданный номер фрейма.
Кнопка "Загрузить новый Flash ролик" вызывает диалоговое окно и загружает новый swf файл. (См. поставляемый с примером square.swf)..
Отметим, что в программе используются:
свойство ShockwaveFlash1-> TotalFrames для отображения общего количества фреймом во Flash ролике;
метод ShockwaveFlash1->IsPlaying. Возвращаемое им значение позволяет определить проигрывается ли в текущий момент ролик.
метод ShockwaveFlash1->CurrentFrame для отображения номера текущего фрейма при остановках.
Исходный код программы находится в архиве .
Текст основного модуля из архива
#include < vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------
#pragma package(smart_init)
#pragma link "ShockwaveFlashObjects_OCX"
#pragma link "CSPIN"
#pragma resource "*.dfm"
TForm1 *Form1;
//-------------------------------
__fastcall TForm1::TForm1
(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------
void TForm1::ShowCurFrame(void) //
показать номер текущего фрейма
{
Label2->Caption = IntToStr
(ShockwaveFlash1->CurrentFrame()); // номер текущего фрейма
Label2->Visible = true;
}
//--------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
ShockwaveFlash1->Movie =
ExtractFilePath(Application->ExeName) + "ball.swf";
Label4->Caption = IntToStr
(ShockwaveFlash1->TotalFrames); // Общее число фреймов
}
//--------------------------------
void __fastcall TForm1::
Button2Click(TObject *Sender)
{
ShockwaveFlash1->Stop();
ShowCurFrame();
}
//--------------------------------
void __fastcall TForm1::
Button3Click(TObject *Sender)
{
ShockwaveFlash1->Play();
Label2->Visible = false;
}
//--------------------------------
void __fastcall TForm1::
Button4Click(TObject *Sender)
{
if (ShockwaveFlash1->IsPlaying())
ShockwaveFlash1->Stop();
// если проигрывается, то остановим
ShockwaveFlash1->Back();
// на предыдущий фрейм
ShowCurFrame();
}
//---------------------------------
void __fastcall TForm1::
Button5Click(TObject *Sender)
{
if (ShockwaveFlash1->IsPlaying())
ShockwaveFlash1->Stop();
// если проигрывается, то остановим
ShockwaveFlash1->Forward();
// на следующий фрейм
ShowCurFrame();
}
//--------------------------------
void __fastcall TForm1::
Button6Click(TObject *Sender)
{
if (ShockwaveFlash1->IsPlaying())
ShockwaveFlash1->Stop(); //
если проигрывается, то остановим
ShockwaveFlash1->Rewind(); //
на 1-й фрейм
ShowCurFrame();
}
//--------------------------------
void __fastcall TForm1::
Button7Click(TObject *Sender)
{
ShockwaveFlash1->GotoFrame
(StrToInt(CSpinEdit1->Text)); // на введенный фрейм
ShowCurFrame();
}
//---------------------------------
void __fastcall TForm1::
Button8Click(TObject *Sender)
{
if (OpenDialog1->Execute())
{
if (ShockwaveFlash1->IsPlaying())
ShockwaveFlash1->Stop(); //
если проигрывается, то остановим
ShockwaveFlash1->Movie =
OpenDialog1->FileName;
Label4->Caption = IntToStr
(ShockwaveFlash1->TotalFrames); // Общее число фреймов
ShockwaveFlash1->Play();
Label2->Visible = false;
}
}
//-------------------------------
Установка компоненты
Чтобы иметь возможность работать с Flash роликом, необходимо импортировать компонент ActiveX для Flash. Естественно это возможно, если в операционной системе есть библиотека Flash.ocx или SWFlash.ocx. Эта библиотека устанавливается автоматически при установке пакета Flash или проигрывателя Flash. Последний распространяется компанией Macromedia бесплатно (http://www.macromedia.com/go/getflashplayer).
Итак, установим компоненту. Запустим CBuilder. Откроем меню Component>Import ActiveX Control появиться диалоговое окно (рис. 1).
Рис 1. Диалоговое окно Import ActiveX
Поле Palette page можно не менять, если вы не хотите поместить компонент на другую страницу палитры компонентов. Найдите и выберете в списке Shockwave, откроется кнопка Install…, нажмите её, появится окно (рис. 2)
Рис. 2 Выбор пакеджа в который будет помещаться компонент.
Рекомендуем поле File name не менять. Нажатие кнопки OK приведет к появлению окна (рис. 3)
Рис. 3. Запрос на переустановку пакеджа.
После подтверждения получаем информационное сообщение (рис. 4)
Рис. 4. Информационное сообщение
В результате всех этих манипуляций в палитре компонентов в разделе ActiveX появятся новая компонента
Рис. 5. Фрагмент линейки компонент.
Подготовительный этап завершён.
Вступление
Цель данной статьи продемонстрировать программистам, работающим на CBuilder или на Delphi, возможность интерактивного взаимодействия CBuilder (Delphi) и Flash. Хотя статья рассчитана в основном на программистов, работающих под CBuilder, она также будет полезна программирующим на Delphi.
От редакции CITForum.ru: Для любителей Delphi Олег Варибрус впоследствии написал аналогичную статью .
в данной статье приведены для
Все примеры в данной статье приведены для CBuilder, однако без существенных изменений всё вышесказанное можно отнести и к Delphi.
Возможности работы с Flash роликом через CBuilder отнюдь не ограничиваются теми инструментами, которые рассматривались в статье. В частности, существуют ряд методов, позволяющих работать с отдельными "мувиками", а не со всем роликом в целом. Это может дать уникальные возможности по программному управлению отдельными частями Flash ролика в ходе его выполнения.
Использование методов SetVariable и GetVariable для передачи данных между Flash и Delphi
Демонстрации методов SetVariable и GetVariable приведены в проекте, который находится в файле .
Методы объявлены в ShockwaveFlashObjects_TLB.pas следующим образом:
procedure SetVariable(const name: WideString; const value: WideString); safecall; function GetVariable(const name: WideString): WideString; safecall;
Параметр name определяет полное имя переменной, значение которой устанавливается методом SetVariable или запрашивается методом GetVariable. Для метода SetVariable параметр value содержит устанавливаемое значение. Возврат значения переменной в методе GetVariable производится через имя метода.
Итак, пример использования SetVariable и GetVariable
Во Flash создаем ролик (см. ), в котором располагаем статический и динамический тексты.
В динамическом тексте меняем его имя на DelphiText и имя переменной на DelphiVarText (см. рис. 10)
Рис. 10. Свойства динамического текста
Сохраняем Flash-ролик под именем DelphiToFlash.fla (и DelphiToFlash.swf) и приступаем к созданию проекта на Delphi (см. рис. 11).
Этот проект будет передавать во Flash-ролик текст, который будет отображаться в поле динамического текста (имя этого компонента DelphiText), меняя переменную под именем DelphiVarText. Изменение будет происходить при нажатии на кнопку "Передать" (вызов метода SetVariable).
С помощью ComboBox1 будем менять цвет бордюра вокруг текста. Изменение будет происходить при любой модификации значения в ComboBox1 (опять же метод SetVariable).
Рис. 11. Форма для демонстрации методов SetVariable и GetVariable
И, наконец, демонстрация метода GetVariable с помощью кнопки "Запросить цвет бордюра из Flash-ролика" и метки с именем Label3. При нажатии на кнопку, в Label3 отобразится значение кода цвета бордюра.
Обратите внимание, что задавать цвет надо в 16-тиричном виде, а возвращается он в десятичном.
Команда fsCommand и событие onFSCommand
Flash-ролик может инициировать событие Delphi, а наоборот - из Delphi во Flash, к сожалению, нет. Команда скрипта fsCommand, написанная во Flash, вызывает событие onFSCommand для объекта типа TSockwaveFlash в Delphi и передаёт два параметра:
BSTR command - наименование команды; BSTR args - параметры.
Значения этих параметров устанавливаются командой fsCommand во Flash и, в нашем случае, эти параметры могут иметь произвольные значения, которые можно использовать для обмена данными.
Приведём простой пример (см. ).
Запустим Macromedia Flash MX и создадим ролик следующим образом.
Поместим в единственный фрейм сцены кнопку "Oval buttons - blue" из общей библиотеки (см. рис. 7).
Рис. 7.Создание кнопки.
Теперь напишем обработчик события Release для этой кнопки, в котором разместим команду fscommand ("Click"). В данном примере передача второго параметра в команде fscommand не используется.
Это показано на .
Выбор текста "Click" в качестве первого параметра в данном случае произволен.
Сохраним ролик под именем botton.fla в том же каталоге, в котором будем размещать создаваемый на Delphi проект. Нажмем Alt+Ctrl+Enter, чтобы получить botton.swf.
Создадим новый проект на Delphi. На форму поместим компонент Flash под именем ShockwaveFlash1. Сделаем программную загрузку файла botton.swf и обработку события onFSCommand, как показано ниже в тексте модуля.
unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, OleCtrls, ShockwaveFlashObjects_TLB;
type TForm1 = class(TForm) ShockwaveFlash1: TShockwaveFlash; procedure ShockwaveFlash1FSCommand(ASender: TObject; const command, args: WideString); procedure FormCreate(Sender: TObject); private { Private declarations } public { Public declarations } end;
var Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.ShockwaveFlash1FSCommand(ASender: TObject; const command, args: WideString); begin if command = 'Click' then if Form1.Color=clWhite then Form1.Color := clBtnFace else Form1.Color := clWhite; end;
procedure TForm1.FormCreate(Sender: TObject); begin ShockwaveFlash1.Movie := ExtractFilePath(Application.ExeName) + 'button.swf'; end;
end.
Если значение переменной x равно "Click", то форма меняет свой цвет.
Параметр arg здесь не используется, но его можно применить, чтобы передать в Delphi какую-либо информацию.
Проигрывание Flash-ролика
Создаём на Delphi новый проект с единственной формой Form1. Из палитры компонентов ActiveX помещаем на форму компоненту ShackwaveFlash. Заносим с помощью инспектора объектов или программно в свойство ShockwaveFlash1.Movie полный путь и имя файла Flash-ролика (расширение файла swf). В примерах Flash-ролик помещён в тот же каталог, что и exe-файл, поэтому в них свойство удобно менять программно, размещая код в обработчике события создания формы:
procedure TForm1.FormCreate(Sender: TObject); begin ShockwaveFlash1.Movie := ExtractFilePath(Application.ExeName) + 'ball.swf'; end;
Установите свойства ShockwaveFlash1.Loop и ShockwaveFlash1.Playing в true. Нажмем F9, чтобы провести промежуточную проверку приложения. На форме должен двигаться и деформироваться овал. Если вместо этого на форме просто белый квадрат, то, скорее всего, неправильно установлено свойство ShockwaveFlash1.Movie (файл ball.swf находится в ).
Отметим, что свойства, методы и поля класса TShockwaveFlash можно просмотреть в файле ShockwaveFlashObjects_TLB.pas (обычно он находится в "c:\Program Files\Borland\Delphi7\Imports\"). Рекомендуем сделать это. Информацию о методах можно найти на сайте компании Macromedia, в описании и в Help пакета Flash.
Теперь модифицируем наше приложение так, чтобы продемонстрировать возможности управления ходом выполнения Flash-ролика. Вид главной формы представлен на рис. 6. Кнопки Stop, Play, Back, Forward, Rewind вызывают одноименные методы ShockwaveFlash1:
Stop - останавливает выполнение ролика; Play - инициирует выполнение ролика с текущего фрейма; Back - переход на предыдущий фрейм; Forward - переход на следующий фрейм; Rewind - переход на следующий фрейм;
При нажатии кнопок Back, Forward, Rewind во время воспроизведения ролика, перед выполнением соответствующего метода производится остановка методом Stop.
Рис. 6. Вид формы
Кнопка "Перейти" совместно с CSpinEdit демонстрирует использование метода ShockwaveFlash1.GotoFrame - переход на произвольно заданный номер фрейма.
Кнопка "Загрузить новый Flash-ролик" вызывает диалоговое окно и загружает новый swf-файл. (См. предоставляемый с примером файл square.swf).
Отметим, что в программе используются:
свойство ShockwaveFlash1.TotalFrames для отображения общего количества фреймом во Flash-ролике; метод ShockwaveFlash1.IsPlaying. Возвращаемое им значение позволяет определить, проигрывается ли в текущий момент ролик. метод ShockwaveFlash1.CurrentFrame для отображения номера текущего фрейма при остановках.
Исходный код программы находится в архиве .
Текст модуля для демонстрации методов SetVariable и GetVariable
unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, OleCtrls, ShockwaveFlashObjects_TLB, ExtCtrls, StdCtrls;
type TForm1 = class(TForm) Label1: TLabel; Label2: TLabel; Label3: TLabel; Button1: TButton; Edit1: TEdit; ComboBox1: TComboBox; Button2: TButton; Panel1: TPanel; ShockwaveFlash1: TShockwaveFlash; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); procedure ComboBox1Change(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } end;
var Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject); begin ShockwaveFlash1.Movie := ExtractFilePath(Application.ExeName) + 'DelphiToFlash.swf'; Label3.Caption := ShockwaveFlash1.GetVariable ('DelphiText.borderColor'); end;
procedure TForm1.Button1Click(Sender: TObject); begin ShockwaveFlash1.SetVariable ('DelphiVarText', StringToOleStr(Edit1.Text)); end;
procedure TForm1.ComboBox1Change(Sender: TObject); begin ShockwaveFlash1.SetVariable ('DelphiText.borderColor', StringToOleStr(ComboBox1.Text)); end;
procedure TForm1.Button2Click(Sender: TObject); begin Label3.Caption := ShockwaveFlash1.GetVariable ('DelphiText.borderColor'); end;
end.
Текст основного модуля из архива
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Spin, OleCtrls, ShockwaveFlashObjects_TLB; type TForm1 = class(TForm) Label1: TLabel; Label2: TLabel; Label3: TLabel; Label4: TLabel; Label5: TLabel; ShockwaveFlash1: TShockwaveFlash; Button2: TButton; Button3: TButton; Button4: TButton; Button5: TButton; Button6: TButton; Button7: TButton; SpinEdit1: TSpinEdit; OpenDialog1: TOpenDialog; Button8: TButton; procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); procedure Button4Click(Sender: TObject); procedure Button5Click(Sender: TObject); procedure Button6Click(Sender: TObject); procedure Button7Click(Sender: TObject); procedure Button8Click(Sender: TObject); procedure FormCreate(Sender: TObject); private { Private declarations } procedure ShowCurFrame(); // показать номер текущего фрейма public { Public declarations } end;
var Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.ShowCurFrame(); // показать номер текущего фрейма begin Label2.Caption := IntToStr(ShockwaveFlash1.CurrentFrame()); // номер текущего фрейма Label2.Visible := true; end;
procedure TForm1.Button2Click(Sender: TObject); begin ShockwaveFlash1.Stop(); ShowCurFrame(); end;
procedure TForm1.Button3Click(Sender: TObject); begin ShockwaveFlash1.Play(); Label2.Visible := false; end;
procedure TForm1.Button4Click(Sender: TObject); begin if ShockwaveFlash1.IsPlaying() then ShockwaveFlash1.Stop(); // если проигрывается, то остановим ShockwaveFlash1.Back(); // на предыдущий фрейм ShowCurFrame(); end;
procedure TForm1.Button5Click(Sender: TObject); begin if ShockwaveFlash1.IsPlaying() then ShockwaveFlash1.Stop(); // если проигрывается, то остановим ShockwaveFlash1.Forward(); // на следующий фрейм ShowCurFrame(); end;
procedure TForm1.Button6Click(Sender: TObject); begin if ShockwaveFlash1.IsPlaying() then ShockwaveFlash1.Stop(); // если проигрывается, то остановим ShockwaveFlash1.Rewind(); // на 1-й фрейм ShowCurFrame(); end;
procedure TForm1.Button7Click(Sender: TObject); begin ShockwaveFlash1.GotoFrame(StrToInt(SpinEdit1.Text)); // на введенный фрейм ShowCurFrame(); end;
procedure TForm1.Button8Click(Sender: TObject); begin if OpenDialog1.Execute() then begin if (ShockwaveFlash1.IsPlaying()) then ShockwaveFlash1.Stop(); // если проигрывается, то остановим ShockwaveFlash1.Movie := OpenDialog1.FileName; Label4.Caption := IntToStr(ShockwaveFlash1.TotalFrames); // Общее число фреймов ShockwaveFlash1.Play(); Label2.Visible := false; end
end;
procedure TForm1.FormCreate(Sender: TObject); begin ShockwaveFlash1.Movie := ExtractFilePath(Application.ExeName) + 'ball.swf'; Label4.Caption := IntToStr(ShockwaveFlash1.TotalFrames); // Общее число фреймов end; end.
Установка компоненты
Чтобы иметь возможность работать с Flash-роликом, необходимо импортировать компонент ActiveX для Flash. Естественно, это возможно, если в операционной системе есть библиотека Flash.ocx или SWFlash.ocx. Эта библиотека устанавливается автоматически при установке пакета Flash или проигрывателя Flash. Последний распространяется компанией Macromedia .
Итак, установим компоненту. Запустим Delphi. Откроем меню Component→Import ActiveX Control, появится диалоговое окно (рис. 1).
Рис 1.Диалоговое окно Import ActiveX
Поле Palette page можно не менять, если вы не хотите поместить компонент на другую страницу палитры компонентов. Найдите и выберите в списке Shockwave, откроется кнопка Install…, нажмите её, появится окно (рис. 2)
Рис. 2. Выбор пакеджа, в который будет помещаться компонент.
Рекомендуем поле File name не менять. Нажатие кнопки OK приведет к появлению окна (рис. 3)
Рис. 3. Запрос на переустановку пакеджа.
После подтверждения получаем информационное сообщение (рис. 4)
Рис. 4. Информационное сообщение
В результате всех этих манипуляций в палитре компонентов в разделе ActiveX появится новая компонента
Рис. 5. Линейка компонентов с новым компонентом в ActiveX
Подготовительный этап завершён.
Вступление
Прошло около двух лет с момента опубликования моей статьи "Flash и CBuilder". За это время я получил несколько писем с просьбой предоставить примеры на Delphi. Чтобы удовлетворить эти просьбы и по согласованию с редакцией сайта, я решил выставить данную "зеркальную" статью.
роликом через Delphi отнюдь не
Возможности работы с Flash- роликом через Delphi отнюдь не ограничиваются теми инструментами, которые рассматривались в статье. В частности, существует ряд методов, позволяющих работать с отдельными "мувиками", а не со всем роликом в целом. Это может дать уникальные возможности по программному управлению отдельными частями Flash-ролика в ходе его выполнения.