Книга: Macromedia Flash Professional 8. Графика и анимация

Управление клипами

Управление клипами

А теперь рассмотрим средства, предоставляемые Flash для управления клипами, находящимися на рабочем листе.

Создание новых клипов

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

Дублирование существующего клипа

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

duplicateMovieClip(<Дублируемый клип>, "<Имя создаваемого клипа>", <Порядок перекрытия нового клипа>);

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

Однако при создании нового клипа способом дублирования нужно учесть четыре момента. Во-первых, содержимое переменных, объявленных в сценариях дублируемого клипа, а также его свойств не копируется в новый клип. Во-вторых, если дублируемый клип содержит анимацию, то в новом клипе она в любом случае начнет воспроизводиться с самого начала. В-третьих, созданный таким образом клип вкладывается в тот клип, в котором находится продублированный клип. В четвертых, созданные с помощью действия duplicateMovieClip клипы в порядке перекрытия всегда находятся "выше" созданных вручную.

Приведем пример сценария, использующего действие duplicateMovieClip и находящегося в клипе car:

duplicateMovieClip(wheel2, "wheels", 3);

(Мы только что приделали к нашему автомобилю пятое, запасное, колесо!)

Вместо действия duplicateMovieClip можно использовать одноименный метод объекта MovieClip. Вот формат его вызова:

<Дублируемый клип>.duplicateMovieClip ("<Имя создаваемого клипа>", <Порядок перекрытия нового клипа>);

Создание нового клипа на основе образца.

Сценарные образцы

Чтобы создать совершенно новый клип, основанный на библиотечном образце-клипе, используется метод attachMovie объекта movieClip. Формат его вызова следующий:

<Клип>.attachMovie("<Имя сценарного образца>",

"<Имя создаваемого клипа>", <Порядок перекрытия нового клипа>);

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

Дело в том, что для успешного использования в методе attachMovie образец-клип нужно превратить в так называемый сценарный — доступный для вызова из сценария. Сейчас мы выясним, как это делается.

Первым делом нужно вывести на экран панель Library. Далее найдем в списке этой панели нужный образец и выберем в контекстном или дополнительном меню пункт Linkage, после чего на экране появится давно знакомое нам диалоговое окно Linkage Properties (см. рис. 8.21).

Чтобы превратить образец в сценарный, нужно включить флажок Export for ActionScript и ввести идентификатор создаваемого образца в поле ввода Identifier. Все почти так же, как и в случае разделяемых образцов.

Далее нам нужно решить, куда будут помещены массивы данных этого сценарного образца. По умолчанию все они помещаются в первый кадр фильма и, соответственно, загружаются перед тем, как фильм начнет воспроизводиться. Если таких образцов слишком много или если они очень велики, пауза перед выводом первого кадра фильма может затянуться. Но мы можем заставить Flash поместить массив данных образца в тот кадр фильма, в котором они впервые встречаются. Для этого достаточно отключить флажок Export in first frame.

Однако здесь нас подстерегает другой сюрприз. Если мы не использовали где-либо в фильме сценарный образец, то Flash не поместит его в результирующий файл Shockwave/Flash, справедливо полагая, что он здесь лишний. Что мы там написали в сценариях, его (Flash) не касается. Так вот, для того чтобы Flash все же сохранил сценарный образец в готовом фильме, нам придется все-таки поместить его экземпляр на рабочий лист, задав для него либо очень маленькие размеры, либо максимальную прозрачность.

Вот, собственно, и все. Осталось нажать кнопку ОК окна Linkage Properties. И можно использовать готовый сценарный образец.

Приведенный ниже сценарий добавит в наш автомобиль лишнюю фару, создав ее на основе сценарного образца headlight:

_root.car.attachMovie("headlight", "headlight3", 0);

Создание "пустого" клипа

Flash также позволяет поместить на рабочий лист "пустой" клип. Это выполняется с помощью метода createEmptyMovieClip объекта movieClip. Формат вызова метода такой:

<Клип>.createEmptyMovieClip("<Имя создаваемого клипа>",

<Порядок перекрытия создаваемого клипа>);

Метод createEmptyMovieClip вызывается для того клипа, в который нужно вложить создаваемый "пустой" клип. Оба его параметра нам уже знакомы.

Запишем сценарий с использованием этого метода:

_root.createEmptyMovieClip("tractor", 0);

Этот сценарий поместит на рабочий лист новый "пустой" клип tractor — в компанию к нашему многострадальному автомобилю. Конечно, никакого трактора там пока что нет, но — лиха беда начало…

Удаление клипа

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

removeMovieClip(<Удаляемый клип>);

Например, для того чтобы удалить пятое колесо, подойдет такой сценарий:

removeMovieClip(_root.car.wheels);

Обойдемся без запаски — авось гаишник не остановит.

Для удаления клипа можно также воспользоваться методом removeMovieClip объекта movieClip. Формат его вызова очень прост:

<Удаляемый клип>.removeMovieClip();

Внимание!

С помощью действия или метода removeMovieClip можно удалить только те клипы, которые созданы из сценариев. Клипы, созданные в среде Flash, не могут быть удалены таким образом.

Изменение параметров встроенных клипов

Не стоит думать, что Flash может только создавать, дублировать и удалять вложенные клипы. Сейчас мы рассмотрим свойства и методы объекта movieclip, с помощью которых можно изменять различные параметры встроенных клипов: местоположение, размеры и пр.

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

Вот пример сценария, изменяющего координаты "фар" в нашем клипе car:

_root.car._x = 200;

_root.car.headlightl._y = _root.car.headlight2._y + 20;

Свойства _width и _height содержат соответственно ширину и высоту клипа.

Свойства _xscale и _yscale задают процент изменения размеров клипа соответственно по горизонтали и вертикали. Значения, большие 100, заставляют клип увеличить соответствующий размер, а меньшие 100 — уменьшить. Так, если задать для свойства _xscale значение 50, то клип сожмется по горизонтали вдвое.

Свойство _aipha позволяет получить или задать степень прозрачности клипа. Доступны любые целые значения от 0 (полная прозрачность) до 100 (полная непрозрачность).

Свойство _rotation задает угол поворота клипа в градусах. Например:

onClipEvent(enterFrame) {

++this._rotation;

— this._alpha;

}

Этот сценарий заставляет вложенный клип в процессе воспроизведения фильма плавно поворачиваться и одновременно плавно исчезать. Фактически мы можем создавать настоящую анимацию только средствами ActionScript.

Свойство _visible позволяет сделать клип невидимым. Оно имеет логический тип: значение true делает клип видимым, а значение false — невидимым.

onClipEvent(mouseDown) {

this._visible = ~this._visible;

}

Этот сценарий при каждом щелчке по клипу делает его то видимым, то невидимым.

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

Метод getDepth возвращает порядок перекрытия текущего клипа. Этот метод не принимает параметров.

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

var clip2 = clipl.duplicateMovieClip("clip2",

_root.getNextHighestDepth());

Это выражение создаст новый клип clip2, продублировав уже имеющийся на рабочем листе клип clip1, и поместит его "над" всеми клипами.

Метод getinstanceAtDepth возвращает ссылку на клип, имеющий заданный порядок перекрытия. Значение порядка перекрытия передается в качестве единственного параметра.

Метод swapDepths меняет значения порядка перекрытия двух клипов местами. Формат его вызова таков:

<Клип 1>.swapDepths("<Клип 2>"|<Порядок перекрытия>);

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

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

_root.car.swapDepths("_root.tractor");

_root.car.swapDepths (10);

_root.car.swapDepths(_root.tractor.getDepth());

Получение служебной информации о клипе

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

Свойство _name возвращает имя клипа, заданное с помощью панели Properties, в строковом виде.

Свойство _target возвращает полный путь клипа в строковом виде.

Свойства _xmouse и _ymouse возвращают соответственно горизонтальную и вертикальную координаты курсора мыши относительно точки отсчета клипа. Пользуясь этими свойствами, можно контролировать перемещения мыши. Например:

onClipEvent(enterFrame) {

myCursor._x = _root._xmouse;

myCursor._y = _root._ymouse;

}

Этот сценарий заставляет вложенный клип myCursor перемещаться вслед за курсором мыши. Фактически сам клип будет вести себя как курсор мыши.

Свойство _current frame возвращает номер кадра клипа, на котором в данный момент стоит бегунок (фактически номер воспроизводимого в данный момент кадра).

Свойство _totalframes возвращает общее количество кадров, содержащихся во внутренней анимации клипа.

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

Свойство _framesloaded возвращает количество кадров клипа, данные которых проигрыватель Flash уже загрузил. А методы getBytesLoaded и getBytesTotal помогут узнать соответственно количество загруженных байтов клипа и полный размер клипа в байтах. Используя их, мы можем создавать индикаторы загрузки клипа или фильма.

Реализация drag'n'drop

Термином "drag'n'drop" ("тащи и бросай") обозначают целый набор операций, связанных с перетаскиванием каких-либо объектов операционной системы (файлов, папок, ярлыков), системных или прикладных программ. Так, во Flash с помощью перетаскивания изменяется местоположение фрагментов изображения и бегунка панели Timeline.

Мы также можем реализовать операции "drag'n'drop" в своих фильмах Flash. Сейчас мы выясним, как это сделать.

Первое, что нам понадобится, — это действие startDrag. Оно делает клип доступным для буксировки с помощью мыши. Формат вызова действия такой:

startDrag(<Клип>, [<За центр>, <Х1>, <Y1>, <Х2>, <Y2>]);

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

Второй параметр (за центр) имеет логический тип. Он позволяет указать точку, к которой будет автоматически "приклеиваться" курсор мыши при перетаскивании. Это может быть точка, в которой пользователь щелкнул мышью (значение false), или центр клипа (значение true).

Остальные четыре параметра позволяют описать прямоугольную область, внутри которой можно будет перетаскивать клип и за пределы которой он не сможет выйти. Через параметры X1 и Y1 задаются горизонтальная и вертикальная координаты левого верхнего угла этой области, а за координаты правого нижнего угла "отвечают" параметры Х2 и Y2. Все координаты задаются относительно внешнего клипа.

Вот два примера применения действия startDrag:

startDrag(_root.car);

startDrag(_root.car, true, 100, 100, 500, 500);

Первое выражение просто делает клип перетаскиваемым. При этом пользователь сможет "ухватить" его мышью и перетащить на новое место. Второе же выражение, кроме этого, задает дополнительные параметры перетаскиваемого клипа.

Вместо действия startDrag можно использовать одноименный метод объекта movieClip:

<Kлип>.startDrag([<За центр>, [<Х1>, <Y1>, <Х2>, <Y2>]]);

После вызова действия или метода startDrag клип останется перетаскиваемым на сколь угодно долгое время. Чтобы завершить операцию "drag'n'drop", например, если пользователь отпустит кнопку мыши, нужно вызвать действие или метод stopDrag. Вот так (действие):

stopDrag();

или так (метод):

_root.car.stopDrag();

На заметку

Для завершения операции "drag'n'drop" также можно вызвать еще раз действие или метод startDrag, но уже для другого клипа. Только один клип в данный момент времени может быть перетаскиваемым.

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

Для запуска и завершения операции "drag'n'drop" можно использовать обработчики событий mouseDown и mouseUp клипа — это очевидно. Давайте напишем эти обработчики и привяжем их к клипу, который нужно сделать перетаскиваемым.

onClipEvent(mouseDown) {

this.startDrag(false);

}

onClipEvent(mouseUp) {

this._x = _root._xmouse;

this._y = _root._ymouse;

this.stopDrag();

}

Обработчик события mouseDown запускает операцию перетаскивания клипа. А обработчик события mouseUp завершает эту операцию и одновременно помещает клип в ту точку, в которой пользователь отпустил кнопку мыши. Как видим, здесь нет ничего сложного.

Объект MovieClip предоставляет доступное только для чтения свойство _droptarget, возвращающее ссылку на так называемую "цель" операции "drag'n'drop" — на клип, в который был "брошен" перетаскиваемый клип. Можно проверить результат, возвращаемый этим свойством, и, в зависимости от него, завершить или не завершить операцию перетаскивания.

Здесь имеет место небольшое затруднение. Дело в том, что свойство _droptarget возвращает результат в особом формате, применяемом в старых версиях Flash (это версии 1–4). Это так называемая "запись со слэшем", когда в качестве разделителя между именем экземпляра объекта и названием его свойства или метода используется косая черта (/), а не точка. Для того чтобы преобразовать "запись со слэшем" в знакомую нам "запись с точкой", нужно воспользоваться встроенной во Flash функцией evai.

Давайте перепишем сценарии-обработчики событий mouseDown и mouseUp так, чтобы они не позволяли пользователю "бросить" перетаскиваемый клип в клип по имени forbiddenArea. Сценарии будут выглядеть так:

onClipEvent(mouseDown) {

this.startDrag(false);

oldX = this._x;

oldY = this._y;

}

onClipEvent(mouseUp) {

if (eval(this._droptarget)!= _root.forbiddenArea) {

this._x = _root._xmouse;

this._y = _root._ymouse;

} else {

this._x = oldX;

this._y = oldY;

}

this.stopDrag();

}

Теперь первый обработчик, помимо запуска операции "drag'n'drop", сохраняет изначальные координаты перетаскиваемого клипа в переменных oldX и oldY. Второй же обработчик, обнаружив, что пользователь перетащил клип в "запрещенное место", восстанавливает изначальное положение перетаскиваемого клипа. В обоих случаях операция "drag'n'drop" завершается.

Так же просто можно написать сценарий, который, наоборот, разрешит "бросать" перетаскиваемый элемент только в одно определенное место. Вообще, можно много чего придумать…

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

Очень многие приложения (не только созданные во Flash, но и обычные, работающие в системе Windows) "щеголяют" фигурными курсорами мыши. Давайте выясним, как создать такой курсор средствами Flash.

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

onClipEvent(load) {

this.startDrag(true);

}

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

Казалось бы, все замечательно. Одно плохо: "родной" курсор мыши, рисуемый самой системой Windows, портит всю картину. Его нужно спрятать. Для этого воспользуемся методом hide пока еще не изученного нами объекта Mouse (он будет рассмотрен далее в этой главе). Этот метод скрывает системный курсор мыши.

Перепишем обработчик события load. Он будет выглядеть так:

onClipEvent(load) {

Mouse.hide();

this.startDrag(true);

}

Вот теперь все работает, как надо.

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

this.startDrag(true, 200, 100, 600, 400);

После этого наш фигурный курсор будет "заперт" в указанных границах.

Выявление совпадений и касаний

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

В нашем случае, однако, все намного проще. Разработчики Flash предусмотрели в объекте movieClip особый метод hitTest. С его помощью мы можем проверить, находится ли заданная точка внутри клипа или касаются ли друг друга два отдельных клипа.

Метод hitTest имеет два формата вызова. Первый из этих форматов позволяет выяснить совпадение точки и клипа:

<Клип>.hitTest(<Х>, <Y>, <Проверять контур>);

Понятно, что первые два параметра определяют соответственно горизонтальную и вертикальную координаты нужной нам точки. Третий параметр имеет логический тип и позволяет указать, что считать границами клипа. Если этот параметр имеет значение true, Flash считает границами клипа контур содержащейся в нем графики. В случае значения false Flash "мысленно" вписывает клип в невидимый прямоугольник и считает границами клипа его контур.

Если заданная точка находится внутри клипа, метод hitTest возвращает значение true. В противном случае — значение false. Возвращаемое значение можно использовать в условном выражении или где-либо еще.

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

onClipEvent(enterFrame) {

if (this.hitTest(_root._xmouse, _root._ymouse, true)) {

this._alpha = 50;

} else { this._alpha = 100;

}

}

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

В нашем случае метод hitTest проверяет только "попадание" в сам клип, поскольку его третий параметр имеет значение true. Если же передать значение false, то метод станет проверять попадание в воображаемый прямоугольник, описанный вокруг нашего клипа. Это более грубая проверка совпадения точки и клипа.

Второй формат метода hitTest позволит нам проверить на совпадение два различных клипа, т. е. проверить, накладываются они друг на друга или перекрываются:

<Клип!>.hitTest(<Клип 2>);

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

Нам осталось проверить работу метода. Создадим новый образец-клип со сложной фигурой, поместим его экземпляр на рабочий лист, сделаем его поменьше и назовем cursor. К первому (и единственному) кадру фильма привяжем вот такой небольшой сценарий:

_root.cursor.startDrag(true);

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

Теперь напишем сценарий-обработчик события enter Frame для клипа hit, так чтобы он проверял касание клипов cursor и hit одного другим:

onClipEvent(enterFrame) {

if (this.hitTest(_root.cursor)) {

this._alpha = 50;

} else { this._alpha = 100;

}

}

Оглавление книги


Генерация: 0.033. Запросов К БД/Cache: 0 / 0
поделиться
Вверх Вниз