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

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

Регистрация классов

Одна из наиболее ценных новинок ActionScript, появившихся во Flash MX – это возможность создания подклассов фильмов-символов. Вы можете создать собственный класс (этому вы научились в данном уроке), запрограммировать его функциональные возможности – используя обработчики событий клипа, свои методы и прочее; а потом ассоциировать с этим классом один или несколько фильмов-символов из библиотеки – тогда каждый экземпляр этого символа автоматически унаследует возможности вашего класса. Хотя на словах это может звучать немного запутанно, на самом деле ничего сложного тут нет. Давайте рассмотрим пример. Для начала предположим, что у нас в библиотеке имеется пара символов, которым присвоены имена связи (Linkage identifier) clipOne и clipTwo.

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

Итак, давайте создадим новый класс:

_global.CustomClass = function(){
}

Мы создали новый класс под именем CustomClass. Далее мы укажем, что этот класс должен наследовать возможности класса MovieClip – для этого сразу после описания класса мы поместим такую строку:

CustomClass.prototype = new MovieClip();

Теперь придадим нашему классу дополнительные возможности, добавив их в объект-прототип:

CustomClass.prototype.onRollOver = function(){
  this._alpha = 50;
}
CustomClass.prototype.onRollOut = function(){
  this._alpha = 100;
}
CustomClass.prototype.onEnterFrame = function(){
  this._rotation += 10;
}

Наш класс получил, посредством трех методов – обработчиков событий, три функции интерактивного взаимодействия. Теперь нужно, чтобы экземпляры фильма-символа clipOne могли наследовать эти возможности. Для этого нам следует воспользоваться методом Object.registerClass():

Object.registerClass("clipOne", CustomClass);

Теперь все экземпляры фильма-символа clipOne будут реагировать на rollOver, rollOut и enterFrame так, как предписывает CustomClass. Технически они более не считаются экземплярами класса объектов MovieClip – вместо этого они стали экземплярами класса объектов CustomClass.

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

Если вдруг необходимость в наследовании экземплярами clipOne функциональности класса CustomClass отпадет, можно применить следующий синтаксис:

Object.registerClass("clipOne", null);

Регистрация фильма-символа как класса и ее отмена не имеет эффекта для существующих экземпляров данного фильма-символа, она действует только для новых экземпляров, помещаемых в фильм – прямо на монтажный стол в процессе разработки либо динамически, посредством duplicateMovieClip() или attachMovie(). Существующие экземпляры сохраняют текущую функциональность. Чтобы вы лучше поняли этот принцип, давайте рассмотрим пример. Допустим, в кадре 1 вашего фильма вы описали CustomClass. В этот же кадр вы поместили экземпляр фильма-символа clipOne и назвали его myInstance. В кадр 2 вы поместили действие, регистрирующее clipOne как CustomClass:

Object.registerClass("clipOne", CustomClass);

Теперь, хотя мы зарегистрировали clipOne как CustomClass, экземпляр этого фильма-символа myInstance (помещенный в кадр 1) не унаследует функциональность CustomClass, поскольку этот экземпляр появился в фильме (в кадре 1) до того, как был вызван метод registerClass() (в кадре 2). Только те экземпляры, которые будут помещены в фильм с этого момента – вручную или динамически – будут наследовать возможности CustomClass.

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

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

Однако это не означает, что несколько фильмов нельзя связать с одним классом – это как раз можно. Просто вызываете опять метод registerClass() – столько раз, сколько нужно:

Object.registerClass("clipTwo", CustomClass);
Object.registerClass("myClip", CustomClass);
Object.registerClass("anotherClip", CustomClass);

В результате этих действий экземпляры фильмов-символов clipTwo, myClip и anotherClip будут наследовать возможности CustomClass.

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

myMovieClip._proto_ = CustomClass.prototype;

В этом случае экземпляр myMovieClip унаследует возможности CustomClass. Такое изменение свойства _proto_ отражается на экземпляре немедленно.

Итак, в следующем упражнении мы создадим собственный класс, настроим его функциональные возможности, а затем, с помощью метода registerClass(), назначим фильм-символ из библиотеки объектом нашего класса.

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

С этим проектом мы работали в предыдущих упражнениях, его элементы вам знакомы. Однако здесь мы несколько изменили структуру проекта. Теперь проект содержит две сцены, идентичные во всем, кроме одного: сцена 1 содержит кнопку, при нажатии которой происходит переход к сцене 2, а во второй сцене, наоборот, имеется кнопка для перехода в сцену 1. Кроме того, в кадр 1 сцены 1 добавлено действие stop(), чтобы пользователь мог переключаться между сценами с помощью кнопок.

Кнопки справа от экземпляра bigHead теперь заменены четырьмя экземплярами фильма-символа Icons. В среде разработки эти экземпляры выглядят одинаково (изображения рта), однако на самом деле фильм-символ Icons содержит все изображения, которые мы использовали ранее для кнопок (глаза, нос, очки). К тому времени, как мы закончим программировать этот проект и проиграем его, эти четыре экземпляра будут выглядеть так же, как те кнопки в предыдущих упражнениях.

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

Четыре экземпляра имеют следующие имена (сверху вниз): mouth, nose, eyes и glasses. Запомните эти имена: в построении проекта они будут важны. Скрипты в этом упражнении мы будем помещать в основном на монтажный стол фильма-символа Icons. Прежде, чем заняться этим, давайте откроем библиотеку и посмотрим, что представляет собою этот фильм-символ.

  1. Командой Окно > Библиотека (Window > Library) откройте панель Библиотека. Найдите фильм-символ под названием Icons. Щелкните на нем правой кнопкой (или Control - щелчок на Mac) и выберите в появившемся меню команду Связи (Linkage).

В открывшемся диалоговом окне Свойства связи (Linkage Properties) вы видите, что фильм символ имеет идентификатор (имя) "icons". Для него установлена опция "Экспорт в первый кадр" ("Export in first frame") – это означает, что данный клип (а иногда и скрипт, который он содержит) будет загружен прежде, чем что-либо другое в этом фильме, включая даже первый кадр – запомните это, данный момент будет очень важен.

Примечание Подробнее о настройках связи смотри в Уроке 14 – Динамическое управление фильмами-символами.

  1. Нажав кнопку Отмена (Cancel), закройте диалоговое окно Свойства связи. Закройте панель Библиотека. Двойным щелчком на одном из находящихся на сцене экземпляров фильма-символа Icons откройте его для редактирования на месте.

Монтажный стол этого клипа содержит четыре слоя, в каждом из которых – 40 кадров. В слое Labels имеется четыре ключевых кадра с метками: mouth, nose, eyes и glasses. Каждая из них обозначает иное графическое изображение (в слое Graphics ), соответствующее названию метки. Слой Hit State содержит маленький прозрачный квадрат, расположенный под изображениями. Этот квадратик, как мы вскоре увидим, найдет важное применение. В кадре 1 слоя Actions будут содержаться все скрипты, которые мы создадим в этом упражнении.

  1. Открыв панель Действия, выделите кадр 1 и введите следующий скрипт:
_global.Custom1 = function(){
}
Custom1.prototype = new MovieClip();

Первые две строки создают новый класс под названием Custom1. Как видите, описание класса предельно простое. Следующая строка устанавливает наследование, в результате которого класс Custom1 получит все функциональные возможности класса MovieClip. Теперь мы опишем особые возможности, присущие классу Custom1.

  1. В конец этого скрипта добавьте следующий:
Custom1.prototype.scale = function(amount){
  this._xscale = amount;
  this._yscale = amount;
}

Этот блок кода описывает для класса Custom1 новый метод под названием scale(). Метод будет управлять масштабированием экземпляра, основываясь на значении amount, передаваемом методу при вызове. Скоро мы им воспользуемся.

Примечание В этом скрипте (и в последующих) this в итоге станет ссылкой на тот экземпляр, который унаследует возможности класса. Так, если экземпляр с именем myClip станет наследником Custom1, действие myClip.scale(50) ; установит масштаб в 50 процентов для этого экземпляра.

  1. В конец скрипта добавьте следующие строки:
Custom1.prototype.onLoad = function(){
  this.gotoAndStop(this._name);
}

В этой части скрипта мы создаем метод - обработчик события onLoad – он описывает, что должно происходить при загрузке экземпляров данного класса. Действие gotoAndStop() будет перемещать каждый экземпляр к метке, соответствующей его имени. Четыре экземпляра фильма-символа Icons унаследуют эту способность класса. Имена этих экземпляров – mouth, nose, eyes и glasses – такие же, как имена четырех меток на монтажном столе данного фильма-символа. Таким образом, при загрузке (onLoad) экземпляр перейдет к метке, соответствующей его имени ( this._name ). В результате после начала фильма четыре экземпляра будут выглядеть так же, как прежние четыре кнопки.


  1. В конец скрипта добавьте следующие строки:
Custom1.prototype.onPress = function(){
  thisX = this._x;
  thisY = this._y;
  startDrag(this, true);
  this.scale(70);
}

В этой части скрипта использован метод-обработчик события onPress, он устанавливает, что должно происходить с экземплярами данного класса при нажатии на них кнопки мыши. Первые две строки фиксируют текущие координаты экземпляра по x и y и помещают значения в переменные с именами thisX и thisY. Следующее действие делает экземпляр перетаскиваемым. В последней строке используется метод scale(), созданный нами на предыдущем шаге – в данном случае он уменьшает экземпляр до 70 процентов от нормального размера.

  1. В конец скрипта добавьте следующие строки:
Custom1.prototype.onRelease = function(){
  stopDrag();
  if (this.hitTest("_root.bigHead")){
    this._x = thisX;
    this._y = thisY;
    _root.bigHead[this._name] = true;
    this.scale(100);
    this.enabled = false;
  }else{
    this._x = thisX;
    this._y = thisY;
    this.scale(100);
  }
}

В этой части скрипта применен метод-обработчик события onRelease, описывающий, что должно происходить с экземплярами данного класса при отпускании нажатой кнопки мыши. Первым делом прекращается перетаскивание экземпляра. Затем вступает в действие оператор if, выполняющий один из двух наборов инструкций в зависимости от того, где оказался экземпляр в результате перетаскивания. Для проверки условия использован метод hitTest() – с его помощью выясняется, оказался ли экземпляр после перетаскивания на экземпляре bigHead. Если это так, то выполняется первый набор действий. Два первых действия перемещают экземпляр в координаты со значениями thisX и thisY – то есть в изначальное положение. В следующем действии свойству экземпляра bigHead, имеющему такое же название, как имя текущего экземпляра, присваивается значение true. Например, если нажатый и отпущенный экземпляр имеет имя nose, то данная строка расшифруется так:

_root.bigHead.nose = true;

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

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

Секция else выполняется, если экземпляр в результате перетаскивания не попал на bigHead. В этом случае выполняется всего три действия. Экземпляр попросту возвращается в начальное положение и принимает нормальный размер. После этого его можно снова нажимать и перетаскивать, и тогда снова оператор if предпримет соответствующие действия.

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

  1. Поместите в конец скрипта следующую строку:
Object.registerClass("icons", Custom1);

Мы регистрируем фильм-символ Icons (его идентификатор связи – "icons") как класс Custom1 ; теперь экземпляры фильма будут наследовать все свойства и методы этого класса.

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

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

 

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

Вот задание:

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

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