Опубликован: 04.11.2006 | Уровень: специалист | Доступ: платный
Урок 14:

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

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

Зачастую при создании пользовательского интерфейса возникает необходимость реализовать для экземпляров клипов операцию типа "перетащить и оставить" ( 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, которые мы здесь изучили, позволят вам самостоятельно создавать гораздо более сложные и функциональные приложения.

Салтанат Бектегенова
Салтанат Бектегенова

Дострочное пересдача экзамена

 

Евгений Стародубцев
Евгений Стародубцев

Вот задание:

7. Открыв панель Действия (Actions) и установив ее в Экспертный режим(Expert Mode), выделите кадр 1 слоя Actions и введите следующий скрипт:

Евгения Дегтяренко
Евгения Дегтяренко
Украина, Запорожье
Анна Елисеева
Анна Елисеева
Россия, Великий Новгород, Ногородский государственный университет имени Ярослава Мудрого, 2003