Опубликован: 04.11.2006 | Доступ: свободный | Студентов: 4621 / 581 | Оценка: 4.46 / 3.96 | Длительность: 39:17:00
Урок 6:

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

Отслеживание свойств

Итак, вы знаете, что объектам (в том числе фильмам-символам) можно придать свойства (переменные). В типичных Flash-приложениях значения этих свойств в любое время могут быть изменены. Как и у объектов реального мира, изменение свойства может привести к тому, что будет затронут не только объект, свойство которого изменено, но также, возможно, и ряд других объектов – произойдет, можно сказать, цепная реакция изменений. Например, предположим, что погода – это объект, и что погодные условия (свойство погоды – погода.условия) изменились с "ясно" на "дождь" (погода.условия = "дождь";). В результате небо потемнеет, у автомобиля включатся фары и заработают "дворники" на лобовом стекле. В распоряжении ActionScript имеется метод watch() для отслеживания различных свойств (переменных, как условия в нашем примере) объекта; если обнаружено изменение значения свойства, то вызывается некая функция, и ваш проект реагирует на изменение. Синтаксис применения этого метода таков:

имяОбъекта.watch("имяСвойства", имяФункции);

Предположим, weather (погода) – имя фильма-символа на основном монтажном столе, condition (условия) – имя переменной в этом фильме-символе, а watchCondition() – имя функции, которая должна быть вызвана при изменении значения condition. Тогда мы запишем так:

_root.weather.watch("condition", watchCondition);

Примечание Объект может инициировать отслеживание внутри себя, используя синтаксис this.watch("имяСвойства", имяФункции);.

Функция watchCondition() могла бы быть описана, например, так:

function watchCondition(id, oldval, newval){
  message.text = id + " было " + oldval + ", а теперь " + newval;
  if (newval == "rainy"){
    sky.gotoAndStop("dark");
    lights.gotoAndStop("on");
    wipers.gotoAndPlay("on");
  }else if (newval == "sunny"){
    sky.gotoAndStop("bright");
    lights.gotoAndStop("off");
    wipers.gotoAndStop("off");
  }
}

Обратите внимание на параметры id, oldval и newval, передаваемые функции. Эти параметры будут автоматически передаваться функции при ее вызове в результате срабатывания метода watch(). Параметр id представляет собой имя (в виде строкового значения) отслеживаемого свойства; oldval – старое значение этого свойства (до изменения), а newval – новое значение, которое привело к срабатыванию метода watch(). В приведенном примере вы видите, как эти параметры используются внутри функции.

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

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

Если необходимость в отслеживании свойства отпала, вы можете отменить его, вызвав метод unwatch():

weather.unwatch("condition");

После выполнения данной строки скрипта при изменении свойства condition функция watchCondition() более не будет вызываться.

Несколько важных моментов, касающихся применения метода watch():

  • Метод watch() работает с большинством объектов ActionScript, имеющих свойства (переменные), включая объекты, созданные пользователем (как мы показали в предыдущем упражнении). Однако нельзя отслеживать предустановленные свойства ActionScript, такие, как _x, _y, _alpha и тому подобные.
  • Для любого свойства можно инициировать только один процесс отслеживания. Установка нового отслеживания для того же свойства отменит предыдущее.
  • Если вы попытаетесь устроить отслеживание по "принципу домино" – когда при изменении отслеживаемого свойства выполняется функция, которая изменяет другое отслеживаемое свойство, в результате чего выполняется функция, изменяющая еще одно отслеживаемое свойство, и так далее – результаты могут оказаться непредсказуемыми.

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

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

Большинство элементов этой сцены мы для вас уже создали и настроили, так что вы можете сосредоточиться на ActionScript. Сцена содержит четыре слоя. Слой Background содержит фоновую заливку и логотип проекта. В слое Head находятся два экземпляра фильма-символа Head. Меньший экземпляр называется smallHead, больший – bigHead (вскоре мы рассмотрим этот фильм-символ поближе). Кроме того, слой Head содержит текстовое поле, расположенное в нижней части сцены, называется оно message. В слой Buttons помещены все используемые в нашем проекте кнопки. Четыре из них, которые мы будем использовать в этом упражнении, расположены справа от экземпляра bigHead. Имена кнопок – mouthButton, noseButton, eyesButton и glassesButton. Две другие кнопки, те, что в левом верхнем углу сцены, мы используем в следующем упражнении. Слой Actions содержит скрипты (к которым мы многое добавим по ходу упражнения).

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

Главное, о чем следует вас предупредить – это то, что монтажный стол этого фильма-символа (сам по себе простенький) содержит экземпляры четырех других фильмов-символов: glassesClip, eyesClip, noseClip и mouthClip. Что они изображают, можно догадаться по названиям – очки, глаза, нос и рот. Мы будем делать эти экземпляры видимыми и невидимыми, отслеживая изменение значений свойств. В нашем фильме два экземпляра фильма-символа Head, и мы запрограммируем их так, чтобы они реагировали на события противоположным образом. Например, если экземпляр noseClip в экземпляре bigHead становится видимым, то noseClip в экземпляре smallHead делается невидимым.

  1. Вернитесь на основной монтажный стол. Откройте панель Действия, выделите экземпляр bigHead и добавьте следующий скрипт:
onClipEvent(load){
  glassesClip._visible = false;
  eyesClip._visible = false;
  noseClip._visible = false;
  mouthClip._visible = false;
  glasses = false;
  eyes = false;
  nose = false;
  mouth = false;
}

Здесь использовано событие load, то есть скрипт будет выполнен, как только экземпляр bigHead появится на сцене – а это произойдет сразу после начала воспроизведения фильма. Кстати, большинство скриптов для этого упражнения мы будем помещать в обработчики события load. А пока давайте рассмотрим эти первые несколько строк.

Четыре первые строки делают невидимыми экземпляры, о которых мы говорили на предыдущем шаге. Таким образом, сразу после загрузки bigHead лишится лица, а smallHead останется без изменений, (то есть, с лицом) – ведь эти действия затрагивают только экземпляры, находящиеся в bigHead.

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

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

  1. В конце (но внутри) обработчика события load добавьте описание функции:
function watchGlasses(id, oldval, newval){
  _root.message.text = "I now have " + id + ".";
  glassesClip._visible = newval;
  _root.smallHead.glassesClip._visible = oldval;
  _root.glassesButton.enabled = false;
}

Вообще-то мы собираемся установить наблюдение за переменной glasses, а эта функция будет выполняться при изменении значения. Обратите внимание на три параметра, передаваемых функции – id, oldval, newval. Значения всех трех параметров используются в функции. Первая строка функции, используя значение id, будет выводить сообщение в текстовом поле message. Поскольку эту функцию будет вызывать "наблюдатель" за значением glasses, id в данном случае будет иметь строковое значение "glasses", а все сообщение будет звучать как "I now have glasses.". В следующей строке используется значение параметра newval. На предыдущем шаге мы дали очкам начальное значение false ; это значит, что функция будет вызвана, когда это значение сменится на true, а значит, и newval будет true – это ведь не что иное, как новое значение свойства или переменной. Итак, во второй строке glassesClip._visible становится true, и glassesClip из bigHead отображается на экране. В следующей строке нашел применение параметр oldval – в соответствии с ним устанавливается видимость glassesClip из экземпляра smallHead. А поскольку oldval имеет значение false (значение glasses до изменения), то glassesClip из smallHead становится невидимым. Последнее действие отключает кнопку glassesButton. Функции этой кнопки мы пока не запрограммировали, но заранее скажем, что именно она будет изменять значение glasses, что и приведет к выполнению данной функции. Как видите, изменив это значение, кнопка отключается, то есть, использовать ее можно будет лишь один раз.

  1. В конце (но по-прежнему внутри) обработчика события load добавьте описания еще трех функций:
function watchEyes(id, oldval, newval){
  _root.message.text = "I now have " + id + ".";
  eyesClip._visible = newval;
  _root.smallHead.eyesClip._visible = oldval;
  _root.eyesButton.enabled = false;
}
function watchNose(id, oldval, newval){
  _root.message.text = "I now have " + id + ".";
  noseClip._visible = newval;
  _root.smallHead.noseClip._visible = oldval;
  _root.noseButton.enabled = false;
}
function watchMouth(id, oldval, newval){
  _root.message.text = "I now have " + id + ".";
  mouthClip._visible = newval;
  _root.smallHead.mouthClip._visible = oldval;
  _root.mouthButton.enabled = false;
}

Эти три функции будут обрабатывать изменение переменных eyes, nose и mouth, соответственно. На шаге мы задали для всех этих переменных начальное значение false ; значит, соответствующие функции будут выполняться при изменении значения на true. Работают эти функции точно так же, как та, которую мы создали на предыдущем шаге. Различия заключаются лишь в именах самих функций, в именах экземпляров, которые становятся видимыми (в bigHead ) и невидимыми ( smallHead ), и именах отключаемых кнопок.

Итак, функции созданы, пора заняться и "наблюдателями".

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

  1. В конце (но внутри) обработчика события load добавьте следующие строки:
this.watch("glasses", watchGlasses);
this.watch("eyes", watchEyes);
this.watch("nose", watchNose);
this.watch("mouth", watchMouth);

Эти четыре строки содержат указания Flash вести отслеживание значений упомянутых свойств, и в случае изменения выполнить соответствующую функцию. Первая строка устанавливает отслеживание свойства (переменной) glasses. При изменении значения этого свойства выполняется функция watchGlasses(). Обратите внимание на использование здесь термина this. Первая строка, в сущности, гласит: "Отслеживать изменение значения свойства glasses в "этом" ( this ) объекте". Если бы переменная glasses находилась в другом экземпляре, мы могли бы попросту использовать адресацию – указать путь к этому экземпляру (и/или функции), к примеру, вот так:

_root.myMovieClip.watch("glasses", _root.myFunction);

Остальные три строки скрипта устанавливают наблюдение за свойствами eyes, nose и mouth, и при их изменении выполняют соответствующие функции.

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

  1. Выделите кнопку mouthButton справа от экземплра bigHead и присоедините к ней такой скрипт:
on(release){
  _root.bigHead.mouth = true;
}

Как только эта кнопка будет нажата и отпущена, значение свойства mouth экземпляра bigHead изменится с false на true, и на это отреагирует "наблюдатель", установленный нами на предыдущем шаге.

  1. К остальным кнопкам присоедините следующие скрипты:
К кнопке noseButton:
on(release){
  _root.bigHead.nose = true;
}
К кнопке eyesButton:
on(release){
  _root.bigHead.eyes = true;
}
К кнопке glassesButton:
on(release){
  _root.bigHead.glasses = true;
}

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

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

Итак, изначально bigHead у нас совершенно "обезличен". Нажатие той или иной кнопки справа изменит значение mouth, nose, eyes либо glasses, что приведет к выполнению одной из наших функций. В сцене произойдут изменения – как мы и запрограммировали.

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

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

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

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

 

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

Вот задание:

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