voliuf.narod.ru

главная

друзья

помощь сайту

Macromedia Flash MX и программирование на ActionScript

Бесплатные учебники по темам

Партнерская программа

1.Знакомство с ActionScript

2.Применение обработчиков событий

3.Адресация

4.Объекты и их использование

5.Применение функций

6.Создание и модификация объектов

7.Работа с динамическими данными

8.Манипулирование данными

9.Использование условной логики

10.Автоматизация скриптов с помощью циклов

11.Организация ввода и вывода данных во Flash

12.Применение XML во Flash

13.Проверка и форматирование данных

14.Динамическое управление фильмами-символами

15.Привязка динамики к времени и кадрам

16.Звук и ActionScript

17.Загрузка внешних материалов

 


Macromedia Flash MX и программирование на ActionScript 
14.Динамическое управление фильмами-символами
  
 
Внимание! Для работы с этим уроком необходимы учебные файлы, которые Вы можете загрузить  здесь.

Приложение для рисования – один из проектов, которые мы создадим в этом уроке в ходе изучения различных способов динамического управления клипами.


   

Создание экземпляров клипов динамически

Для динамического создания экземпляра фильма-символа предназначены три метода объекта MovieClip:

 
  • duplicateMovieClip(): C помощью этого метода можно создать дубликат (новый экземпляр) существующего на сцене экземпляра фильма-символа.
  • attachMovie(): Этот метод создает на сцене новый экземпляр фильма-символа, имеющегося в библиотеке.
  • createEmptyMovieClip(): Этот метод создает пустой экземпляр фильма-символа – то есть не содержащий ни данных, ни графических материалов.
 

Каждый из этих методов мы с вами применим в ходе выполнения упражнений этого урока.

 

duplicateMovieClip()

Мы уже познакомили вас с этим методом в Уроке 10 – Автоматизация скриптов с помощью циклов, однако сделали это бегло, не вдаваясь в детали. Теперь, наконец, вы узнаете все об этом мощном методе!

 

Метод duplicateMovieClip() служит для Flash указанием создать дубликат имеющегося на сцене экземпляра фильма-символа, дав ему новое имя. Если указанный экземпляр клипа на сцене не присутствует (находится в одном из предыдущих или последующих кадров), то Flash не сможет дублировать его. Другое ограничение состоит в том, что дубликат может быть создан только на том же самом монтажном столе, где находится оригинал. Для динамического создания экземпляра клипа на любом монтажном столе следует применять метод attachMovie() – мы еще поговорим о нем в этом уроке.

 

Создаваемый дубликат наследует все физические свойства, которые имел оригинал на момент дублирования.

 

Дубликат фильма-символа наследует следующие свойства оригинала:

 
  • Позиция
  • Масштаб
  • Прозрачность
  • Угол поворота
  • Цвет
  • Обработчики событий, присоединенные к экземпляру клипа
 

Дубликат фильма-символа не наследует:

 
  • Переменные, массивы, объекты
  • Имя
  • "Видимость"
  • Номер текущего кадра
 

 


 

 

 

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

 

Синтаксис дублирования экземпляра фильма-символа таков:

 
myClip.duplicateMovieClip(имя, глубина, объект);
        

Эта строка ActionScript начинается с указания имени (с адресацией) фильма-символа, который следует дублировать, после чего следует вызов метода duplicateMovieClip() объекта MovieClip. В результате создается новый экземпляр, именем которого будет значение параметра имя, на глубине глубина. Параметр объект – не обязательный. Пример:

 
name = "ball2";
depth = 100;
ball.duplicateMovieClip(name, depth);
        

Эти три строки создают дубликат экземпляра клипа ball; экземпляр-дубликат получает имя ball2 и располагается на глубине 100.

 

Примечание Говоря здесь о глубине (depth), мы подразумеваем порядок наложения экземпляров клипов на монтажном столе. Во Flash, если два экземпляра клипов перекрываются, верхним будет тот, который имеет большее значение глубины. Каждый экземпляр фильма-символа имеет уникальное значение глубины, определяющее его положение по отношению к другим объектам на сцене. При дублировании новому экземпляру клипа присваивается значение глубины – любое положительное число. Чем больше это число, тем выше "над сценой" будет расположен экземпляр. Вы, возможно, даже не подозревали, что все экземпляры фильмов-символов, которые вы помещаете на монтажный стол в процессе разработки проекта, тоже автоматически получают глубину, при этом значения глубин начинаются с отрицательного числа -16384. Это означает, что динамически созданный экземпляр, помещенный на глубину 1, перекроет все, что было помещено на сцену вручную.

 

Каждый монтажный стол в фильме имеет диапазон глубин от -16384 до 1048575, причем все отсчеты глубин ведутся относительно главного монтажного стола фильма. Иными словами, некий "экземпляр 1" может содержать дочерние экземпляры, расположенные на его монтажном столе на глубинах от -16384 до 1048575. Но если на основном монтажном столе "экземпляр 1" находится под "экземпляром 2", то всякий, даже самый верхний дочерний экземпляр "экземпляра 1" окажется ниже самого нижнего из дочерних экземпляров "экземпляра 2".

 

 


 

 

 

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

 

Итак, каждый монтажный стол имеет 1064960 уровней глубины (от -16384 до 1048575). При этом глубины разных монтажных столов никоим образом не пересекаются между собой.

 

Третий параметр метода duplicateMovieClip(), параметр объект, необязателен, но отнюдь не бесполезен. Свойства объекта, указанного в качестве этого параметра, станут элементами данных нового дубликата клипа. Если параметр опущен, он игнорируется. Расширим немного предыдущий пример:

 
myObject = new Object();
myObject.ballColor = "red";
name = "ball2";
depth = 100;
ball.duplicateMovieClip(name, depth, myObject);
        

Новый экземпляр-дубликат ball2 будет содержать все свойства объекта myObject. В данном случае в новом экземпляре будет создана переменная ballColor со значением "red".

 

Совет Если нужно скопировать переменные из оригинального экземпляра в дубликат, следует использовать в качестве третьего параметра имя оригинального экземпляра. Например:

 
ball.duplicateMovieClip(name, depth, ball);
        

attachMovie()

C помощью метода attachMovie() можно взять фильм-символ из библиотеки и динамически "присоединить" (attach) экземпляр его к любому монтажному столу из имеющихся в данный момент в сцене фильма – при этом, естественно, все содержимое этого экземпляра добавится к содержимому фильма, к которому он присоединяется. Присоединенный клип становится дочерним по отношению к монтажному столу, к которому он присоединен. Он наследует все графические трансформации, выполняемые над родителем (изменения размеров, прозрачности, повороты и т.п.), при этом сохраняя самостоятельность в отношении данных, видимости, текущего кадра и т.п. (подробнее об отношениях родитель/потомок см. Урок 3 – Об адресации).

 

 


 

 

 

В чем же состоят отличия этого метода от метода duplicateMovieClip()? Как уже было сказано, attachMovie() присоединяет экземпляр клипа из библиотеки к любому из монтажных столов в фильме. Поскольку присоединяемый клип берется из библиотеки (а библиотека содержит все клипы фильма), клип, к которому присоединяется экземпляр, не обязан находиться на сцене в момент присоединения. С методом duplicateMovieClip() все наоборот: экземпляр клипа, который подлежит дублированию, должен находиться на сцене. Более того, дубликат создается только на том же монтажном столе, что и оригинал. Еще одно различие состоит в следующем. Если дублируемый экземпляр имеет присоединенные к нему обработчики событий (data, enterFrame, mouseDown и т.п.), то дубликат автоматически наследует их. С присоединяемым клипом такого не происходит. Конечно, имеются способы добавить обработчики событий и к присоединяемому клипу, но этот процесс не столь прост, как при дублировании.

 

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

 

 


 

 

 

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

 

Пошаговый процесс связывания фильма-символа выглядит так:

 
  1. Откройте библиотеку.
  2. Щелкните правой кнопкой мыши на интересующем вас клипе.
  3. Выберите в контекстном меню пункт Связи (Linkage).
  4. Установите флажок Экспорт для ActionScript (Export for ActionScript).
  5. Введите имя в поле Название (Identifier) (этот идентификатор будет служить в ActionScript) ссылкой на клип, находящийся в библиотеке).
 

Совет Установить связь можно также при создании фильма-символа, нажав в диалоговом окне Преобразовать в символ (Convert to Symbol) кнопку Расширенный (Advanced).

 

 


 

 

 

Примечание При связывании обратите внимание еще на одну опцию – "Экспорт в первый кадр" (Export in first frame), которая включается по умолчанию. Эта опция определяет, в какой момент будет загружаться связанный (или присоединяемый) фильм-символ при просмотре фильма. Если флажок установлен, то клип будет загружен до кадра 1 основного фильма, и, таким образом, его содержимое будет доступно прежде, чем будет предпринята любая попытка присоединить его (например, уже в кадре 1). При использовании крупных клипов (таких, которые содержат много других фильмов-символов или звукозаписей) Flash может в начале фильма "затормозить". Не стоит беспокоиться: просто происходит загрузка содержимого всех связанных фильмов-символов. Если флажок "Экспорт в первый кадр" не установлен, то фильм-символ не будет загружаться перед первым кадрам. В этом случае вы должны поместить экземпляр такого клипа на сцену до того, как попытаетесь присоединить его. После того, как фильм-символ будет обработан (появится в фильме) в каком-либо кадре, его можно будет присоединять когда и где угодно. Например, если в кадре 25 имеется действие, присоединяющее клип, то экземпляр этого клипа должен появиться в фильме в кадре 24 или раньше – иначе метод attachMovie() не сработает. После кадра 24 присоединять экземпляры этого клипа можно сколько угодно, поскольку он уже загружен в память.

 

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

 
путь.attachMovie(идентификатор, новоеИмя, глубина, объект);
Например:
_root.wall.attachMovie("paint", "paint2", 10);
        

Этот скрипт присоединит фильм-символ из библиотеки, имеющий идентификатор "paint", к экземпляру фильма-символа _root.wall. Новый присоединенный экземпляр получит имя paint2 и будет помещен на глубину 10. Присоединенный клип станет дочерним для того экземпляра, к которому он присоединен, так что путь к нему будет выглядеть как _root.wall.paint2. Обратите внимание на пример синтаксиса (первая строка): здесь тоже имеется опция, позволяющая наполнить создаваемый клип свойствами и переменными объекта. Как и для duplicateMovieClip(), эта опция необязательна и в нашем примере (вторая строка) опущена.

 

Совет Простейший способ динамически назначить события клипа присоединенному (или дублированному) клипу – описать обработчики событий сразу после действия, выполняющего присоединение (дублирование), как в этом примере:

 
_root.attachMovie("box", "dynamicBox", 1);
dynamicBox.onEnterFrame = function(){
  dynamicBox._rotation += 15;
}
        

В этом примере экземпляр фильма-символа box (это его имя в библиотеке) динамически присоединяется к основному монтажному столу. Присоединенный экземпляр получает имя dynamicBox. Строки, следующие за действием присоединения, назначают обработчик события клипа для нового экземпляра.

 

createEmptyMovieClip()

Метод createEmptyMovieClip() позволяет динамически создать (на любом монтажном столе) новый экземпляр пустого фильма-символа. Для чего это может понадобиться? Вот несколько примеров.

 
  • К пустому клипу, созданному с помощью этого метода, можно присоединять экземпляры других клипов – например, для динамического генерирования списков и меню. Если элементы меню присоединены к такому "базовому" клипу, можно перемещать все меню целиком, вместо того, чтобы двигать каждый элемент по отдельности.
  • Создав пустой клип, можно затем загрузить в него звукозапись или картинку.
  • Пустые экземпляры клипов могут служить отличными хранилищами для линий, обычных и градиентных заливок, созданных с помощью изобразительных функций Flash.
 

Синтаксис создания экземпляра пустого фильма-символа следующий:

 
путь.createEmptyMovieClip(имя, глубина);
        

Например:

 
_root.createEmptyMovieClip("box", 1);
        

Здесь первый параметр – имя, которое будет присвоено новому экземпляру пустого клипа; второй параметр – глубина, на которую будет помещен этот экземпляр. Если вы попытаетесь протестировать это действие, то не обнаружите никакого видимого результата – ведь созданный экземпляр совершенно пуст. В этом уроке мы с вами используем метод createEmptyMovieClip() для динамического рисования линий.

 

Применение attachmovie()

Метод attachMovie() создает новый экземпляр фильма-символа из библиотеки. В этом упражнении мы с вами создадим проект, при запуске которого на сцене будет отображаться прокручиваемый список. Элементы этого списка будут создаваться посредством динамического присоединения экземпляров клипа.

 
  1. Откройте файл scrollingList1.fla из папки Lesson14/Assets.

На основном монтажном столе мы видим три слоя: Actions, Window и Background. Слой Background содержит общее графическое оформление проекта; в слой Actions мы поместим большинство скриптов; а в слое Window находится экземпляр фильма-символа под названием display.

 

Внутри монтажного стола display вы найдете четыре слоя: Mask, Fields, Scroll Buttons и Window Graphics. В слое Window Graphics содержатся рамка и фон окна, слой Scroll Buttons содержит экземпляр фильма-символа, в котором находятся кнопки прокрутки окна вверх и вниз (ими мы займемся в следующем упражнении), а в слое Fields находится пустой экземпляр клипа под названием list, к которому мы будем присоединять экземпляры, создавая их при помощи attachMovie(). Эти присоединенные экземпляры станут элементами списка, располагаясь один под другим. Список (экземпляр клипа list), будучи наполнен присоединенными к нему экземплярами, станет довольно-таки длинным. Поэтому мы маскируем list прямоугольником, находящимся в слое Mask, так что видимой будет только часть клипа list, находящаяся "внутри" окна.

 

 


 

 

 
  1. Откройте библиотеку и найдите в ней фильм-символ под названием list info bar. Щелкните на нем правой кнопкой мыши (или Control-щелчок на Macintosh) и выберите в появившемся меню пункт Связи (Linkage). В открывшемся диалоговом окне Свойства связи (Linkage Properties) установите флажок Экспорт для ActionScript (Export for ActionScript) и введите infoBar в поле Название (Identifier).

Теперь этот клип готов к использованию методом attachMovie().

 

Для каждой строки в прокручиваемом списке к экземпляру list будет присоединяться один экземпляр клипа infoBar (16 строк, 16 присоединений). Внутри каждого из присоединенных клипов будет два динамических текстовых поля – moonName и moonNum; в этих полях будут отображаться названия лун Юпитера и соответствующие номера.

 

 


 

 

 
  1. Выделите кадр 1 слоя Actions на основном монтажном столе. Откройте панель Действия и введите следующий скрипт:
list = ["Adrastea", "Amalthea", "Ananke", "Callisto", "Carme", "Elara",
"Europa", "Ganymede", "Himalia", "Io", "Leda", "Lysithea",
"Metis", "Pasiphae", "Sinope", "Thebe"];
   

Цель этого упражнения – создать список, элементами которого будут присоединенные экземпляры фильма-символа. Для этого мы прежде всего создаем массив из названий 16 наиболее известных лун Юпитера. Для каждой луны из этого массива к экземпляру list мы должны присоединить экземпляр клипа из библиотеки.

 

Теперь нужно описать функцию, которая и будет создавать список из экземпляров клипа.

 
  1. По-прежнему при выделенном кадре 1 добавьте к скрипту следующее:
function buildList() {
  spacing = 30;
}
   

В конечном итоге функция buildList() будет содержать все действия, необходимые для присоединения, позиционирования и заполнения информацией элементов списка – экземпляров клипа. Для правильного и равномерного размещения элементов списка по вертикали мы создаем переменную spacing и присваиваем ей значение 30 – эта переменная будет определять дистанцию по вертикали (y) между центрами присоединенных экземпляров клипа.

 
  1. Добавьте в описание функции следующие действия, присоединяющие и позиционирующие элементы списка:
var i = -1;
while (++i < list.length) {
  name = "infoBar" + i;
  y = i * spacing;
  display.list.attachMovie("infoBar", name, i);
  display.list[name]._y = y;
  display.list[name].moonName.text = list[i];
  display.list[name].moonNum.text = i + 1;
}
   

В этой части функции используется цикл while, перебирающий поочередно все элементы массива list. Для каждого элемента массива цикл присоединяет к экземпляру list экземпляр клипа infoBar.

 

Первым действием в теле цикла создается переменная name, значение которой задается выражением, которое присоединяет к строке "infoBar" текущее значение i. Поскольку значение i при каждом проходе цикла увеличивается на единицу, name будет принимать значения "infoBar0", "infoBar1", "infoBar2" и так далее. Далее в теле цикла значение name будет использовано для присвоения имени каждому успешно присоединенному экземпляру клипа infoBar. А пока в цикле создается переменная y, которая будет хранить y-координату присоединяемого в данный момент экземпляра. Значение этой переменной вычисляется умножением текущего значения i на значение spacing. Поскольку значение i при каждой итерации увеличивается, то же будет происходить и со значением y. В результате присоединенные экземпляры будут располагаться друг под другом.

 

Последние четыре действия в теле цикла присоединяют экземпляры, позиционируют их и заполняют информацией динамические поля в каждом присоединенном экземпляре. Первым делом создается (присоединяется) новый экземпляр клипа infoBar, имя и глубина которого содержатся в переменных name и i, соответственно. Далее этот присоединенный экземпляр получает y-координату, равную значению переменной y. Каждый из присоединяемых экземпляров содержит те же элементы, что и оригинал, а значит, в каждом имеется два текстовых поля: moonName и moonNum. Последние два действия в теле цикла заполняют эти поля соответствующей информацией. Во первых, в поле moonName присоединенного экземпляра помещается строковое значение (название луны) – i-й элемент массива list. В текстовое поле moonNum каждого экземпляра помещается числовое значение i плюс 1. Таким образом, в этом текстовом поле для соответствующих экземпляров будут выводиться значения 1, 2, 3 и так далее.

 

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

 

 


 

 

 
  1. В самый конец текущего скрипта в кадре 1 (после описания функции) добавьте вызов функции – действие buildList();.

 


 

 

 

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

 
  1. Командой Управление > Проверить фильм (Control > Test Movie) запустите тест только что созданного проекта.

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

 
  1. Закройте тестовый фильм и сохраните свою работу как scrollingList2.fla.

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

 

Построение кнопок с непрерывной обратной связью

Порой возникает необходимость в том, чтобы некие действия выполнялись непрерывно, пока нажата кнопка. Кнопки, запрограммированные таким образом, называют кнопками с непрерывной обратной связью; прекрасным примером будут кнопки прокрутки (тема данного упражнения).

 

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

 

Если информации в окне при каждом нажатии на соответствующую кнопку будет прокручиваться на одну строку, пользователь быстро устанет. Гораздо удобнее, если прокрутка при нажатой кнопке происходит непрерывно, и прекращается, когда кнопка отпущена. Во Flash это можно реализовать (вскоре мы это продемонстрируем) с помощью событий клипа enterFrame или mouseMove.

 

В этом упражнении мы с вами добавим кнопки прокрутки к списку, построенному нами в предыдущем упражнении.

 
  1. Откройте файл scrollingList2.fla из папки Lesson14/Assets.

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

 

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

 

Примечание В этом упражнении, используя термин "прокрутка", мы будем подразумевать перемещение по экрану вверх и вниз фильма-символа list путем изменения значения его свойства _y.

 
  1. Откройте панель Действия, выделите кадр 1 слоя Actions и добавьте сразу после строки, создающей массив list, следующую строку скрипта:
startingY = display.list._y;
   

Для правильной работы прокрутки мы должны установить максимальное и минимальное положения (Y), списка – задать границы прокрутки списка (вертикального перемещения). В любом приложении, где используется прокрутка, необходимо предотвращать возможность прокрутку за пределы документа. Добавленная нами строка скрипта будет использоваться для установления одной из этих вертикальных границ: прокрутка экземпляра клипа list (содержащий присоединенные экземпляры) должна прекращаться, если его Y-координата достигла стартовой Y-координаты (startingY). C этой целью мы и используем сейчас значение переменной startingY.

 

 


 

 

 
  1. Вставьте в кадр 1, сразу после предыдущей строки, строку bottom=120; – это будет второй ограничитель прокрутки.

Как было сказано на предыдущем шаге, наибольшая возможная Y-координата прокрутки экземпляра клипа list – это его стартовая позиция. Переменная bottom, которую мы определяем на этом шаге, будет содержать значение координаты такое, чтобы самый нижний элемент списка не мог выйти за пределы окна. Каким образом это будет достигаться, вы поймете из следующих шагов.

 
  1. Начнем описание функции, осуществляющей прокрутку экземпляра клипа. Для этого в кадр 1, сразу после описания функции buildList(), вставьте следующие строки:
function scroll (direction) {
  speed = 10;
}
   

Впоследствии мы организуем вызов этой функции в нашем проекте посредством события enterFrame, присоединенного к экземплярам клипов, содержащих кнопки прокрутки. Одна из кнопок будет предназначена для прокрутки вверх, другая – вниз. Параметр direction, передаваемый этой функции, будет содержать строковое значение: "up" или "down". Условный оператор (который мы сейчас добавим), в зависимости от значения этого параметра будет выполнять действия, предназначенные для прокрутки экземпляра list вверх или вниз. Переменная speed – скорость прокрутки. Пока одна из кнопок удерживается в нажатом положении, экземпляр list будет перемещаться (либо вверх, либо вниз). Скорость его перемещения и определяется значением переменной speed. Кстати, число 10 взято вовсе не из каких-то "высших соображений"; если хотите, можете взять другое значение.

 
  1. В описание функции, сразу после строки speed = 10;, добавьте оператор if/else if:
if (direction == "up") {
} else if (direction == "down") {
}
   

Как мы уже сказали, direction передается функции в качестве параметра и может принимать строковые значения "up" либо "down". Данный условный оператор будет определять действия, выполняемые функцией, в зависимости от значения этого параметра. На следующих шагах мы вставим в каждую секцию этого условного оператора свой набор действий, осуществляющий прокрутку в том или ином направлении.

 
  1. В секцию оператора if для значения "up" поместите следующий набор действий:
if (display.list._y – speed + display.list._height > (startingY + bottom)) {
  display.list._y -= speed;
} else {
  display.list._y = (startingY + bottom) – display.list._height;
}
   

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

 

В условии оператора проверяется, где окажется нижняя грань экземпляра list при перемещении его на 10 пикселей вверх. Вычисляется это так: берется текущая Y-координата экземпляра list, из нее вычитается значение speed, затем прибавляется общая высота экземпляра. Полученная координата нижней грани экземпляра сравнивается с одним из ограничителей прокрутки (который получается путем сложения значений bottom и startingY). Если в результате перемещения экземпляра list он не достиг ограничителя, то все в порядке – выполняется действие из первой секции оператора, движение экземпляра продолжается. Если же экземпляр дошел до ограничителя, выполняется секция else, и экземпляр попросту устанавливается в максимальную разрешенную координату по вертикали.

 

 


 

 

 

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

 
speed = 10
startingX = 100
bottom = 120
display.list._height = 400 //высота (размер по вертикали) экземпляра list
display.list._y = -165 //текущая координата экземпляра list по вертикали
   

С этими значениями условное выражение в операторе if будет выглядеть следующим образом:

 
if (-165 – 10 + 400 > (100 + 120))
   

В итоге получим:

 
if (225 > 220)
   

Поскольку 225 больше 220, выполняется следующее действие:

 
display.list._y -= speed;
   

Тем самым экземпляр list переместится на 10 пикселей вверх, и его Y-координата станет равна -175. Теперь, при следующем выполнении условного оператора, мы получим:

 
if (-175 – 10 + 400 > (100 + 120))
   

И, в итоге:

 
if (215 > 220)
   

Утверждение ложно, ведь 215 меньше 220, поэтому выполняется действие из секции else:

 
display.list._y = (startingY + bottom) – display.list._height;
   

Экземпляр list помещается в Y-координату, значение которой вычисляется в правой части этого выражения:

 
(startingY + bottom) – display.list._height
   

Подставляя наши значения, получим:

 
(100 + 120) – 400
   

Это даст

 
220 - 400
   

И в итоге

 
-180
   

Тем самым экземпляр list будет привязан к вертикальной координате -180 – нижняя грань экземпляра будет совмещена к верхнему ограничителю прокрутки – дальнейшая прокрутка экземпляра list невозможна.

 

Теперь давайте настроим обработку прокрутки вниз.

 
  1. В секцию оператора if/else для значения "down" поместите вложенный оператор if/else if:
if (display.list._y + speed < startingY) {
  display.list._y += speed;
} else {
  display.list._y = startingY;
}
   

 


 

 

 

Эта часть условного оператора будет обслуживать прокрутку экземпляра клипа вниз. Похоже на то, что было на предыдущем шаге, только здесь условный оператор следит, чтобы экземпляр list при перемещении вниз на значение speed (display.list._y += speed) не вышел за нижний ограничитель прокрутки (startingY). Если этого не произошло, выполняется действие из первой секции оператора, перемещающее экземпляр клипа вниз. В противном случае (else) нижняя грань экземпляра совмещается с нижним ограничителем прокрутки.

 

Описание функции мы закончили, теперь пора поработать с кнопками прокрутки.

 
  1. Открыв библиотеку, сделайте двойной щелчок на фильме-символе под названием list arrow.

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

 
  1. Открыв панель Действия, выделите кнопку и введите такой скрипт:
on (press) {
  buttonPressed = "yes";
}
on (release, releaseOutside, dragOut) {
  buttonPressed = "";
}
   

Эта кнопка будет попросту присваивать значение переменной buttonPressed – "yes" или "", в зависимости от действий пользователя. Если пользователь нажал эту кнопку, buttonPressed получает значение "yes". Если пользователь отпускает кнопку мыши (неважно, где при этом находится указатель – на кнопке или за ее пределами), переменная buttonPressed получает значение "". На следующем шаге мы используем значение этой переменной.

 
  1. Открыв библиотеку, сделайте двойной щелчок на фильме-символе под названием scroll.

Монтажный стол этого клипа содержит два экземпляра фильма-символа list arrow, который содержит кнопку Arrow, к которой мы на предыдущем шаге присоединили скрипт. Один из экземпляров развернут на 180 градусов. Верхний экземпляр носит имя down, а нижний экземпляр – up.

 

Как вы помните, при нажатии кнопки, имеющейся в каждом из этих двух экземпляров, переменная buttonPressed получает значение "yes". Важно понимать, что каждый из экземпляров представляет собой самостоятельный монтажный стол. Нажатие кнопки, находящейся в одном из экземпляров, изменит значение переменной buttonPressed только на этом монтажном столе; на переменную другого экземпляра это событие никак не повлияет.

 
  1. Открыв панель Действия, выделите экземпляр клипа down и введите такой скрипт:
onClipEvent (enterFrame) {
  if (buttonPressed == "yes") {
    _root.scroll("down");
  }
}
   

Мы используем событие enterFrame: ActionScript будет непрерывно (24 раза в секунду) проверять значение переменной buttonPressed на монтажном столе этого клипа, и если это значение равно "yes", будет вызывать функцию scroll() с главного монтажного стола. Это – основа принципа действия нашей кнопки с непрерывной обратной связью. Булево значение в выражении условного оператора определяется самой кнопкой. Пока переменная buttonPressed имеет значение "yes" (то бишь, пока кнопка внутри данного экземпляра нажата), происходит прокрутка. Параметр "down", передаваемый функции scroll(), дает ей знать, в каком направлении должна происходить прокрутка.

 
  1. Выделите экземпляр клипа up и введите в панели Действия, такой скрипт:
onClipEvent (enterFrame) {
  if (buttonPressed == "yes") {
    _root.scroll("up");
  }
}
   

Скрипт идентичен тому, что был на предыдущем шаге, только функции scroll() передается другое значение параметра – "up".

 
  1. Командой Управление > Проверить фильм (Control > Test Movie) запустите тест фильма.

Давайте пустим в дело кнопки, чтобы проверить наши скрипты. Нажмите и удерживайте кнопку "вниз", чтобы начать прокрутку, потом попробуйте другую кнопку. Как видите, когда экземпляр list достигает верхнего или нижнего предела, прокрутка останавливается.

 
  1. Закройте тестовый фильм и сохраните свою работу под именем scrollingList3.fla.

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

 

Динамическое рисование при помощи ActionScript

Посредством ActionScript можно организовать рисование динамически, в ходе воспроизведения фильма. Такая возможность обеспечивается методами объекта MovieClip, предназначенными для рисования.

 

Методы рисования позволяют:

 
  • Провести линию от текущего "курсора рисования" к указанной точке
  • Переместить "курсор рисования" в другую позицию (не рисуя при этом линию)
  • Определить стиль линии для монтажного стола
  • Заполнить фигуру цветом
  • Заполнить фигуру градиентом
  • Искривить линию между двумя точками
  • Удалить с монтажного стола нарисованные линии и заливки
 

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

 

lineStyle()

Прежде, чем рисовать на монтажном столе какие-либо линии, необходимо установить стиль линий для этого монтажного стола. Это значит, что нужно указать Flash:

 
  • Толщину линии
  • Цвет линии
  • Прозрачность линии
 

Синтаксис таков:

 
путь.lineStyle(толщина, цвет, прозрачность)
        

В качестве значения толщины линии следует указать целое число от 0 до 255 (значению 0 соответствует самая тонкая линия). Цвет линии указывается в виде шестнадцатеричного кода. Прозрачность – число от 0 (полностью прозрачная) до 100 (полностью непрозрачная). Рассмотрим пример:

 
_root.myClip.lineStyle(10, 0x009900, 100);
        

Эта строка скрипта устанавливает стиль линий для myClip: все линии, изображаемые в этом клипе, будут зелеными, непрозрачными, толщиной 10.

 

moveTo()

Каждому экземпляру фильма-символа присуще такое свойство, как позиция курсора рисования – координата, от которой начнется линия в случае применения метода lineTo() (смотри следующий подраздел). Другими словами, это стартовая точка очередной линии. При создании экземпляра курсор рисования устанавливается в позицию с координатами x=0, y=0. Однако курсор рисования можно в любой момент переместить с помощью метода moveTo().

 

Синтаксис применения moveTo() следующий:

 
путь.moveTo(x, y);
        

Все, что нужно – это указать координаты x и y для нового положения курсора рисования. Например:

 
_root.myClip.lineStyle(10,0x009900,100);
_root.myClip.moveTo(100,100);
        

Этот скрипт устанавливает стиль линии, а затем перемещает курсор рисования.

 

 


 

 

 

lineTo()

Метод lineTo() объекта MovieClip рисует на указанном рабочем столе линию (формата lineStyle данного монтажного стола) от текущей позиции курсора рисования до точки, указанной при вызове метода.

 

Синтаксис lineTo() прост:

 
myClip.lineTo(x,y);
        

Параметры x и y, как вы догадываетесь, определяют конечную точку рисуемой линии.

 

Совет После того, как линия нарисована, текущая позиция курсора рисования перемещается в конечную точку линии.

 

Вот пример рисования линии с использованием всех описанных нами методов:

 
_root.createEmptyMovieClip("canvas",1);
_root.canvas.lineStyle(2,0x009900,100);
_root.canvas.moveTo(100,100);
_root.canvas.lineTo(200,150);
        

Этот скрипт нарисует линию между точками (100, 100) и (200, 150).

 

 


 

 

 

Применение методов рисования

В этом упражнении мы с вами, используя методы рисования объекта MovieClip, мы начнем создавать несложное приложение, позволяющее пользователю рисовать.

 
  1. Откройте файл draw1.fla из папки Lesson14/Assets.

Основной монтажный стол состоит из пяти слоев, названных в соответствии с их содержимым. Слой Background содержит общее графическое оформление проекта. В слое Canvas находится экземпляр фильма-символа под названием canvas – это будет рабочая область для рисования. Слой Icon содержит экземпляр фильма-символа в виде жука, расположенный у левого края сцены. Этот экземпляр называется icon, в следующем упражнении мы создадим дубликаты этого экземпляра, предоставив пользователю несколько значков, которые он сможет перетащить на сцену, чтобы рисовать поверх шаблона. В слое Controller находится особый экземпляр клипа – он называется controller и представляет собой так называемый клип-контроллер (в принципе, это просто экземпляр, который будет содержать большую часть скриптов, обеспечивающих работу нашего проекта). И, наконец, в слое Windows находятся два экземпляра – window1 и window2; они расположены в правой части сцены и пригодятся нам в одном из следующих упражнений.

 

 


 

 

 

Основной целью данного упражнения будет создание скрипта, который даст возможность рисовать в предназначенной для этого рабочей области. Мы используем события клипа в сочетании с методом hitTest(), чтобы отслеживать нажатия кнопки мыши в пределах экземпляра canvas. После этого для рисования мы используем событие клипа mouseMove. Каждый раз при наступлении события mouseMove положение мыши будет записываться и будет рисоваться линия от предыдущей координаты мыши к текущей координате.

 
  1. Откройте панель Действия, выделите экземпляр клипа controller на основном монтажном столе и введите следующий скрипт:
onClipEvent (mouseUp) {
  down = false;
}
   

Как мы уже сказали, большую часть действий для обеспечения работоспособности проекта мы будем помещать в экземпляр controller. Данный скрипт создает переменную с именем down, которая будет хранить текущее состояние мыши. С помощью события mouseUp эта переменная будет при отпускании кнопки мыши получать значение false, показывая другим скриптам, что кнопка мыши не нажата.

 
  1. В конец текущего скрипта добавьте обработчик события клипа mouseDown:
onClipEvent (mouseDown) {
  if (_root.canvas.hitTest(_root._xMouse,_root._yMouse)) {
    x = _root._xMouse;
    y = _root._yMouse;
    _root.holder.moveTo(x,y);
    down = true;
  }
}
   

При нажатии кнопки мыши (mouseDown) условный оператор проверяет, находился ли курсор мыши в момент нажатия над экземпляром клипа canvas. Если это так, то выполняется несколько действий. Во-первых, координаты мыши по x и y записываются в качестве значений переменных x и y соответственно. Затем эти значения используются в методе moveTo() для перемещения курсора рисования клипа holder в текущие координаты мыши. Клип holder – это пустой экземпляр, который будет создаваться динамически (мы запрограммируем это на следующем шаге). Этот-то экземпляр и будет содержать все нарисованные линии. Последнее действие этого скрипта присваивает переменной down значение true, означающее, что кнопка мыши нажата.

 
  1. В конец текущего скрипта добавьте обработчик события клипа onLoad:
onClipEvent (load) {
  currentColor = "7F6696";
  _root.createEmptyMovieClip("holder",100);
}
   

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

 

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

 
  1. В конец текущего скрипта, после обработчика события onLoad, добавьте описание функции draw():
function draw() {
  _root.holder.lineStyle(0, parseInt(currentColor,16) ,100);
  x = _root._xmouse;
  y = _root._ymouse;
  _root.holder.lineTo(x, y);
}
   

Понятно, что эта функция будет вызываться обработчиком события mouseMove, который мы еще не описали. Функция при вызове первым делом устанавливает стиль линий. Как видите, линии будут самыми тонкими (толщина 0), на 100% непрозрачными, цвет же линий зависит от текущего значения переменной currentColor. Три последние строки функции обеспечивают рисование линии. Линия проводится методом lineTo() от текущего положения курсора рисования (установленного посредством moveTo() в нашем обработчике события mouseDown) до текущего положения курсора мыши (значения x и y в этом скрипте).

 
  1. В конец текущего скрипта добавьте обработчик события клипа mouseMove:
onClipEvent (mouseMove) {
  updateAfterEvent();
  if (down && _root.canvas.hitTest(_root._xMouse, _root._yMouse)) {
    draw();
  }
}
   

Событие mouseMove наступает всякий раз при перемещении мыши. Функция updateAfterEvent() – встроенная функция Flash, обновляющая сцену сразу после события (не дожидаясь следующего кадра). Оператор if проверяет, чему равна переменная down и находится ли мышь над областью рисования (canvas). Если и то, и другое – true, вызывается функция draw(). Таким образом, повторяющийся вызов этой функции создает эмуляцию рисования, пока мышь находится над canvas и ее кнопка нажата. Оператор if предотвращает вызов функции draw(), когда кнопка мыши отпущена или мышь выведена за пределы экземпляра canvas.

 

 


 

 

 
  1. Командой Управление > Проверить фильм (Control > Test Movie) запустите тест фильма. Начните рисовать.

Когда вы, наведя мышь на область рисования, нажмете кнопку, переменной down будет присвоено значение true – и это значит, что при всяком перемещении мыши будет рисоваться линия. Если мышь покидает пределы клипа canvas, рисование прекращается.

 
  1. Закройте тестовый фильм и сохраните свою работу под именем draw2.fla.

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

 

Создание закрашенных фигур динамически

Хотя для этого раздела упражнение не предусмотрено, рисование закрашенных фигур обсудить необходимо.

 

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

 

Чтобы создать заливку, прежде всего следует дать Flash знать, где будет находиться фигура, которую следует закрасить. Делается это при помощи следующего метода:

 
путь.beginFill(color, alpha)
   

Путь указывает на монтажный стол, на котором будут располагаться линии. Параметр color – шестнадцатеричный код цвета. Второй параметр – alpha – означает степень прозрачности заливки: число от 0 до 100. Чтобы сообщить Flash о том, что рисование фигуры завершено, следует применить следующий метод:

 
путь.endFill()
   

Вот пример применения этих методов:

 
_root.createEmptyMovieClip("box",1);
with (_root.box) {
  lineStyle(0,0x000000,100);
  beginFill(0x990000,100);
  moveTo(0,0);
  lineTo(100,0);
  lineTo(100,100);
  lineTo(0,100);
  lineTo(0,0);
  box.endFill();
}
   

Данный скрипт делает следующее:

 
  1. Создает пустой экземпляр фильма-символа.
  2. Устанавливает стиль линий.
  3. Инициирует заливку.
  4. Рисует фигуру.
  5. Завершает заливку.
 

Важно отметить, что при создании фигуры для заливки ее стартовая точка (указанная в moveTo()) должна совпадать с конечной точкой (указанной в последнем lineTo()).

 

 


 

 

 

Создать градиентную заливку ненамного сложнее, чем сплошную; гораздо труднее понять, как этот метод работает. Прежде всего, конечно, указывается путь к фигуре, которую следует закрасить. В целом синтаксис выглядит следующим образом:

 
путь.beginGradientFill (type, colors, alphas, ratios, matrix)
   

Первый параметр, type, может принимать строковое значение – linear либо radial (линейный или радиальный тип градиента). Параметр colors – массив шестнадцатеричных цветовых кодов, используемых в градиенте. Массив может состоять из двух или более элементов. Третий параметр, alphas, есть массив значений прозрачности, применяемых к соответствующим цветам. Этот массив должен содержать столько же элементов, что и массив colors. Параметр ratios – массив, элементы которого могут иметь значения от 0 до 255. Эти значения определяют распределение оттенков.

 

Параметр matrix метода beginGradientFill() требует особого внимания. Это – объект, содержащий значения, используемые при перемещении, сдвиге и вращении градиента.

 

Существует два способа конфигурирования объекта matrix. Чаще всего он содержит следующие свойства:

 
  • matrixType: Эта переменная имеет значение "box". Для Flash она обозначает тип используемой матрицы.
  • x: X-координата начала (верхнего левого угла) градиента.
  • y: Y-координата начала (верхнего левого угла) градиента.
  • w: Ширина градиента.
  • h: Высота градиента.
  • r: Угол поворота градиента (в радианах).
 

 


 

 

 

Вот пример создания фигуры с градиентной заливкой:

 
_root.createEmptyMovieClip("holder", 1);
with (_root.holder) {
  lineStyle(0, 0x000000, 0);
  rotation = 90 * (Math.PI/180);
  colors = [ 0x6666FF, 0xFF6600 ];
  alphas = [ 100, 100 ];
  ratios = [ 0, 255 ];
  matrix = { matrixType:"box", x:0, y:150, w:200, h:100, r:rotation };
  beginGradientFill( "linear", colors, alphas, ratios, matrix );
  moveTo(0,0);
  lineTo(550,0);
  lineTo(550,300);
  lineTo(0,300);
  lineTo(0,0);
  endFill();
}
   

Приведенный скрипт создает квадрат, который затем закрашивает градиентной заливкой. Образующие квадрат линии имеют значение прозрачности 0, и значит, невидимы.

 

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

 

Z-сортировка экземпляров клипа

Изменение глубины расположения экземпляров фильмов-символов называют z-сортировкой. Почему z? Да потому, что глубину во Flash можно рассматривать, как третье измерение, Z-координату (вдобавок к X и Y). В момент создания экземпляра клипа его глубина устанавливается при помощи duplicateMovieClip() или attachMovie(), а для динамического изменения глубины расположения клипов предназначен метод swapDepths() объекта MovieClip. C помощью этого метода можно "поменять глубинами" любые два фильма-символа либо переместить экземпляр на указанную глубину.

 

Для взаимного обмена глубинами двух экземпляров клипов используется следующий синтаксис:

 
movieClip1.swapDepths(movieClip2);
   

Если, например, movieClip2 располагался поверх movieClip1, то в результате выполнения этого скрипта они поменяются местами, и movieClip1 окажется над movieClip2.

 

Синтаксис перемещения экземпляра клипа (созданного до этого при помощи duplicateMovieClip() или attachMovie()) на нужную глубину следующий:

 
movieClip1.swapDepths(нужнаяГлубина);
   

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

 
  1. Откройте файл draw2.fla из папки Lesson14/Assets.

В таком виде мы с вами оставили файл, с которым работали в предыдущем упражнении. В этом упражнении мы добавим кое-что в скрипт экземпляра клипа controller, а также поработаем с клипами-окнами.

 
  1. Откройте панель Действия, выделите экземпляр клипа под именем window1 и добавьте такой скрипт:
onClipEvent (load) {
  this.gotoAndStop("color");
}
   

 


 

 

 

И window1, и window2 – экземпляры одного и того же клипа, только под разными именами. Этот скрипт будет направлять экземпляр window1 к кадру с меткой color сразу после загрузки фильма. В этом кадре имеется несколько кнопок, которые будут предназначены для выбора цвета линий при рисовании.

 
  1. Выделите экземпляр клипа под именем window2 и добавьте в панель Действия следующий скрипт:
onClipEvent (load) {
  this.gotoAndStop("admin");
}
   

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

 
  1. Двойным щелчком откройте клип window1 и перейдите к кадру с меткой color. К первой слева кнопке (в виде кончика карандаша) добавьте следующий скрипт:
on (release) {
  _parent.controller.currentColor = "7F6696";
}
   

Вы, вероятно, помните, что переменная currentColor (в экземпляре клипа controller) хранит цвет рисуемых линий. Этот скрипт как раз присваивает переменной currentColor новое значение – шестнадцатеричный код цвета.

 
  1. Поочередно (слева направо) выделяя остальные кнопки-карандаши, добавьте к ним скрипты:

Для второй кнопки:

 
on (release) {
  _parent.controller.currentColor = "FAC81C";
}
   

Для третьей кнопки:

 
on (release) {
  _parent.controller.currentColor = "E72638";
}
   

Для четвертой кнопки:

 
on (release) {
  _parent.controller.currentColor = "1091CB";
}
   

Для пятой кнопки:

 
on (release) {
  _parent.controller.currentColor = "1FA900";
}
   

Для шестой кнопки:

 
on (release) {
  _parent.controller.currentColor = "BC0077";
}
   

Скрипты те же самые, что и для первой кнопки, разнятся только значения цвета.

 

Теперь давайте запрограммируем перетаскивание окна.

 
  1. Выделите прямоугольную оранжевую кнопку в верхней части этого окна а присоедините к ней следующий скрипт:
on (press) {
  startDrag (this);
  _root.controller.swap(_name);
}
   

 


 

 

 

Поскольку кнопка находится на монтажном столе клипа, изображающего окно, при нажатии кнопки начинается перетаскивание самого этого (this) окна.

 

Второе действие вызывает функцию (пока не написанную). Функция эта, под названием swap(), будет находиться в клипе controller, ее роль будет заключаться в изменении z-положения окна так, чтобы оно оказалось на самом верху. Функция при вызове смотрит переданное ей значение свойства _name (представляющее имя экземпляра) текущего фильма. Наш проект содержит два экземпляра одного и того же клипа – window1 и window2, поэтому кнопка будет работать следующим образом: если кнопка нажата в экземпляре window1, начинается перетаскивание этого экземпляра, и функции swap() передается значение "window1". Если же кнопка нажата в экземпляре window2, начинается перетаскивание этого экземпляра, и функции swap() передается значение "window2".

 
  1. Добавьте к кнопке еще один скрипт:
on (release) {
  stopDrag ();
}
   

При отпускании кнопки процесс перетаскивания прекращается.

 
  1. Вернитесь на основной монтажный стол. При открытой панели Действия выделите экземпляр клипа controller и добавьте в обработчик события load следующее действие:
topDog = "window1";
   

Для смены глубин размещения экземпляров window1 и window2 мы применим метод swapDepths(). Переменная topDog будет хранить имя того экземпляра, который расположен выше. При генерации фильма выше окажется window1, поэтому мы присваиваем переменной именно такое начальное значение.

 
  1. Также в обработчик события load, добавьте описание функции:
function swap (name) {
  _root[name].swapDepths(_root[topDog]);
  topDog = name;
}
  

Назначение этой функции – поменять глубинами экземпляр клипа с именем, содержащимся в name (значение параметра, передаваемого функции) и экземпляр с именем, содержащимся в переменной topDog. После этого переменная topDog получает новое значение – это будет имя экземпляра, который теперь оказался сверху. На шаге 6 мы видели, что функции в качестве параметра передается свойство _name текущего фильма (это может быть либо window1, либо window2). Предполагая, что в некоторый момент переменная topDog имеет значение "window1", нажатие кнопки перетаскивания в window2 (при этом будет вызвана функция и ей передано значение "window2") приведет к такому выполнению функции:

 
function swap ("window2") {
  _root.window2.swapDepths(_root.window1);
  topDog = "window2";
}
   
  1. Командой Управление > Проверить фильм (Control > Test Movie) запустите тест фильма. Попробуйте перетаскивать окна, менять цвет линий.

Как только вы нажмете кнопку в верхней части окна, он окажется верхним по глубине и начнется процесс перетаскивания.

 

Ну, а при нажатии на кнопки выбора цвета происходит только одно: изменяется значение переменной currentColor в экземпляре клипа controller, в результате чего новые линии будут изображаться новым цветом.

 
  1. Закройте тестовый фильм и сохраните работу под именем draw3.fla.

Итак, мы с вами применили метод swapDepths() для перемещения на передний план нужного окна. Но проект еще не закончен! Мы должны запрограммировать очистку рабочей области рисования, а также возможность перетаскивания на нее картинок-шаблонов.

 

Перетаскивание экземпляров клипа

Зачастую при создании пользовательского интерфейса возникает необходимость реализовать для экземпляров клипов операцию типа "перетащить и оставить" (drag-and-drop). Этим термином обозначают следующий процесс: при нажатии кнопки мыши на экземпляре начинается его перетаскивание, которое прекращается, как только кнопка мыши будет отпущена. В результате может быть выполнен некоторый набор действий (в зависимости от того, в каком месте оставлен экземпляр). Самый простой пример – "мусорная" Корзина на рабочем столе вашего компьютера: если вы, перетаскивая значок файла, отпускаете его над Корзиной, то файл удаляется; если же отпускаете в другом месте – значок просто перемещается на это место.

 

Обычно во Flash операция "перетащить и оставить" реализуется при помощи _droptarget или hitTest(). Значение свойства фильма _droptarget – путь к самому "переднеплановому" экземпляру фильма-символа из тех, над которыми в данный момент находится перетаскиваемый экземпляр клипа. С помощью метода hitTest() можно определить момент, когда экземпляр касается своей границей границы другого экземпляра (подробнее об этом см. Урок 9, Использование логических условий). На практике чаще метод hitTest() используется гораздо чаще, чем свойство _droptarget, как более гибкий и многоцелевой.

 

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

 
  1. Откройте файл draw3.fla из папки Lesson14/Assets.

В таком виде мы с вами оставили этот файл после выполнения предыдущего упражнения. Сейчас мы будем добавлять скрипты к экземплярам клипов controller и icon. Для начала мы создадим функцию, формирующую строку значков под областью рисования. Затем мы запрограммируем возможность перетаскивания этих значков, а также отслеживание случая, если они оставлены на области рисования.

 
  1. Откройте панель Действия, выделите экземпляр клипа controller и добавьте в обработчик события load следующее описание функции:
function buildIconList() {
  spacing = 85;
  iconY = 360;
  iconX = 70;
  var i = -1;
  while (++i < _root.icon._totalFrames) {
    newName = "icon" + i;
    _root.icon.duplicateMovieClip(newName, 10000 + i);
    _root[newName]._x = iconX + i * spacing;
    _root[newName]._y = iconY;
    _root[newName].gotoAndStop(i + 1);
  }
}
   

Ничего для вас нового в этой функции нет. На монтажном столе экземпляра клипа icon содержится некоторое количество кадров, в каждом из которых имеется изображение одного из значков. Данный скрипт создает по одному дубликату клипа icon для каждого из этих кадров. Дубликаты располагаются в одну линию в нижней части экрана; курсор воспроизведения каждого дубликата перемещается на соответствующий кадр. В результате мы получим строку из нескольких значков. Можно уменьшить или увеличить число значков (то бишь, кадров в экземпляре клипа icon) – наш скрипт сам "узнает" об этом, поскольку примененный нами оператор цикла while базируется на значении свойства _totalFrames (общее число кадров в клипе). Переменная spacing определяет расстояние по горизонтали между дубликатами. Переменные iconX и iconY – координаты первого дубликата.

 

 


 

 

 
  1. В конец обработчика события load поместите строку buildIconList();:

Это будет вызов только что созданной нами функции для создания строки значков.

 
  1. Двойным щелчком на экземпляре клипа icon откройте его для редактирования на месте. Выделите невидимую кнопку и добавьте к ней такой скрипт:
on (press) {
  startDrag (this);
}
   

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

 

Важно отметить, что эта невидимая кнопка имеет имя iconButton. Для чего это нужно? Когда значок будет оставлен в области рисования и продублирован, дубликат унаследует и невидимую кнопку, и все присоединенные к ней действия. А это значит, что дубликат в области рисования тоже будет перетаскиваемым, а это нам совершенно не нужно. Мы хотим, чтобы в области рисования осталось стационарное изображение, в качестве шаблона для рисования. Поэтому мы и присвоили кнопке имя – чтобы иметь возможность отключить ее в дубликате, помещенном в область рисования. Функцию, обрабатывающую перетаскивание, мы настроим таким образом, чтобы после создания дубликата кнопка в нем отключалась и не могла более вызвать действие startDrag(). Кнопка должна работать только в тех экземплярах клипа icon, которые находятся под областью рисования.

 

 


 

 

 
  1. Добавьте к невидимой кнопке еще один скрипт:
on (release) {
  stopDrag();
  _root.controller.iconReleased(_name);
}
   

Первое действие в этом скрипте просто прекращает процесс перетаскивания, если кнопка отпущена – экземпляр клипа "оставлен". Второе действие вызывает функцию iconReleased() (еще не написанную) в экземпляре клипа controller. Эта функция будет создавать дубликат клипа-значка, перетащенного в область рисования, а оригинал возвращать на прежнее место (под областью рисования), откуда его можно будет вновь перетащить. Обратите внимание, что функции в качестве параметра передается свойство _name перетащенного экземпляра – ведь функция должна знать, какой из четырех значков был данном случае перетащен в область рисования.

 
  1. Вернитесь на основной монтажный стол и выделите экземпляр клипа icon. В панели Действия добавьте следующий скрипт:
onClipEvent (load) {
  homeX = _x;
  homey = _y;
}
   

Используя событие load, мы создаем в экземпляре, сразу после его загрузки, две переменные – homeX и homeY, в которых хранятся начальные координаты экземпляра. Этот скрипт будут наследовать все дубликаты, и значит, на монтажном столе каждого из них будут храниться начальные координаты по X и Y. Эти значения нужны нам, чтобы возвращать на место значки после перетаскивания их в область рисования.

 

Теперь давайте напишем функцию, которая объединит наши разрозненные скрипты.

 
  1. Выделите клип controller и добавьте в обработчик события load следующую функцию:
function iconReleased (name) {
  if (_root.canvas.hitTest(_root._xmouse, _root._ymouse)) {
    ++v;
    newName = "object" + v;
    _root[name].duplicateMovieClip(newName, v);
    _root[newName].gotoAndStop(_root[name]._currentFrame);
    _root[newName].iconButton.enabled = false;
    _root[newName]._xscale = 250;
    _root[newName]._yscale = 250;
  }
  _root[name]._x = _root[name].homeX;
  _root[name]._y = _root[name].homeY;
}
   

У этой функции один аргумент – name. Как мы упоминали на шаге 5, значением этого параметра будет имя экземпляра (свойство _name) значка, перетащенного в область рисования. Значение параметра играет важнейшую роль в работе функции.

 

Первым делом условный оператор проверяет, где находится мышь в момент вызова функции – ведь функция должна сработать только в том случае, если перетаскиваемый значок оставляется в области рисования. Итак, если мышь находится над областью рисования, с помощью duplicateMovieClip() создается копия перетащенного экземпляра клипа. Имя, которое получит дубликат, получается путем объединения строки "object" и значения переменной v (которая увеличивается на единицу при каждом очередном создании дубликата). Таким образом, текущее значение v всегда равно числу дубликатов значков, перетащенных в область рисования – запомните это, в следующем упражнении оно нам пригодится.

 

Созданный дубликат отсылается к тому же кадру, что и экземпляр-оригинал (значок, перетащенный в область рисования). Следующее действие отключает в дубликате невидимую кнопку iconButton (мы говорили об этом на шаге 4). Вдобавок дубликат масштабируется по вертикали и горизонтали до размера 250 процентов – таким образом, экземпляр клипа в области рисования получится больше, чем соответствующий значок.

 

Примечание Экземпляр-дубликат наследует (в момент дублирования) X и Y координаты оригинала. Поэтому, если дубликат сразу же не переместить, он расположится прямо над оригиналом (в этом случае, если бы не масштабирование, на экране даже не произошло бы никаких видимых изменений).о отправляют перетащенный экземпляр клипа на прежнее место, координаты которого хранятся в переменных homeX и homeY на его монтажном столе. Обратите внимание: эти два действия находятся вне условного оператора, а значит, будут выполнены даже в том случае, если выражение условного оператора дало результат false, и дубликат не был создан. Таким образом, если пользователь попытается оставить значок не в области рисования (над экземпляром клипа canvas), а где-либо в другом месте, дубликат не создается, и значок просто возвращается на свою начальную позицию в нижней части экрана.

 

 


 

 

 
  1. Командой Управление > Проверить фильм (Control > Test Movie) запустите тест. Попробуйте перетаскивать значки в область рисования.

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

 
  1. Закройте тестовый фильм и сохраните работу как draw4.fla.

Мы с вами создали простенькое приложение для рисования. Возможности ActionScript, которые мы здесь изучили, позволят вам самостоятельно создавать гораздо более сложные и функциональные приложения.

 

Удаление динамически созданного содержания

Динамически созданные линии можно легко удалить с любого монтажного стола при помощи метода clear(). Синтаксис прост:

 
путь.clear();
   

Экземпляры клипов, созданные при помощи duplicateMovieClip() или attachMovie() (как значки, которые мы перетаскивали в область рисования), можно удалить при помощи метода объекта MovieClip removeMovieClip().

 

Примечание С помощью этого метода можно удалить только те экземпляры клипов, которые созданы динамически, при помощи ActionScript. Созданные вручную, то есть перетащенные из библиотеки на сцену в процессе создания фильма, так удалить нельзя.

 

Удаление экземпляров клипов может пригодиться для динамического удаления содержимого со сцены, для реинициализации приложений и освобождения системных ресурсов, при программировании различных функциональных возможностей в приложениях. Синтаксис метода прост:

 
someMovieClip.removeMovieClip();
   

В этом упражнении мы с вами создадим функцию, которая будет удалять из области рисования все динамически нарисованные линии, а также экземпляры клипа icon, перетащенные в область рисования.

 
  1. Откройте файл draw4.fla из папки Lesson14/Assets.

В таком виде мы оставили файл после выполнения предыдущего упражнения. В этом упражнении мы добавим в controller функцию, очищающую область рисования. Запускаться функция будет скриптом, который мы присоединим к кнопке Clear, находящейся в экземпляре клипа window2.

 
  1. Откройте панель Действия, выделите экземпляр клипа controller и добавьте в обработчик события load следующую функцию:
function clearContent () {
  _root.holder.clear();
  i = 0;
  while (++i <= v) {
    name = "object" + i;
    _root[name].removeMovieClip();
  }
  v = 0;
}
   

Первое действие в этой функции удаляет все динамически нарисованные линии из экземпляра клипа holder. Далее следует несложный цикл while, удаляющий все перетащенные на сцену экземпляры клипа icon. Значение переменной v равно общему числу перетащенных экземпляров icon, ведь v увеличивается на единицу всякий раз, когда в области рисования создается дубликат icon – мы с вами запрограммировали это в функции buildIconList(), в предыдущем упражнении. Теперь мы используем значение v для определения количества итераций цикла, удаляющего дубликаты. После того, как цикл завершен (все экземпляры icon из области рисования удалены), переменной v присваивается значение 0, так что когда в область рисования будет перетащен новый экземпляр icon, нумерация дубликатов вновь начнется с нуля.

 

 


 

 

 
  1. Двойным щелчком на экземпляре window2 откройте его для редактирования на месте. Перейдите к кадру с меткой admin.

В этом кадре имеется две кнопки – Clear и Print. Нам нужно присоединить к кнопке Clear скрипт, вызывающий функцию clearContent() из экземпляра клипа controller. Заодно уж давайте добавим скрипт к кнопке Print.

 
  1. Выделите кнопку Print и присоедините к ней такой скрипт:
on (release) {
  printAsBitmap ("_root", "bmovie");
}
   

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

 

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

 
  1. Выделите кнопку Clear и введите такой скрипт:
on (release) {
  _parent.controller.clearContent();
}
   

Если эту кнопку нажать и отпустить, будет выполнена функция clearContent(), присоединенная к экземпляру controller.

 
  1. Командой Управление > Проверить фильм (Control > Test Movie) запустите тест фильма. Изобразите что-нибудь в области рисования, затем нажмите кнопку Clear.

При нажатии кнопки Clear будет выполнена функция очистки, цикл while в ней удалит все созданные в области рисования экземпляры клипов.

 
  1. Закройте тестовый фильм и сохраните свою работу как draw5.fla.

На этом закончено упражнение и весь урок. Как видите, процесс динамического удаления материалов куда проще процесса создания. Ну, теперь вы умеете делать и то, и другое, а это обеспечит вашим проектам колоссальные возможности взаимодействия с пользователем. Ну, разве не великолепен этот ActionScript?!

 
источник: http://www.INTUIT.ru 


 

13 центов(0,13$) за клик, выплаты через WebMoney каждый вторник +10% с рефералов

Мы выкупаем 100% трафа! $12 за 1000 хостов (РФ), и до $4 за 1000 хостов (зарубежный траф) + 10% с дохода Ваших рефералов!
 Выплаты через
WebMoney

~80-100$ за1000 хостов 2.5$ за 1 смс.
реф. процент - 10 %Выплаты происходят раз в неделю, в четверг на
WebMoney
 
 

 

____________________________

Посмотреть порно видео в онлайне »

_______________________________

 

   
   
Сайт управляется системой uCoz