[ предыдущая страница ] [ следующая страница ] [ содержание ]

6.2. Свойства экземпляров

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

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

Давайте вначале посмотрим, какие свойства экземпляров доступны сценарию ActionScript. Имена всех свойств, чтобы их было сразу видно, начинаются с символа _ (подчеркивание).

6.2.1. Базовые свойства

Во-первых, это координаты объекта в рабочей области. Горизонтальная позиция записывается в свойство _x, а вертикальная - в свойство _y. Что касается размеров объекта, то здесь нам доступны как его абсолютная высота и ширина (свойства _width и _height), так и процентная величина по отношению к оригинальным размерам (свойства _xscale и _yscale).

Текущие координаты указателя мыши записываются в свойства _xmouse и _ymouse. Эти два свойства сильно облегчают жизнь, если нужно отслеживать координаты указателя мыши. В предыдущих версиях языка ActionScript для этого приходилось "прикреплять" к указателю мыши невидимый мувик с помощью оператора startDrag, о котором речь пойдет ниже.

Свойства _name и _target содержат соответственно имя экземпляра мувика и полный путь к нему. Значение свойства _name можно изменить, а вот свойство _target изменению не поддается, что вполне логично. Номер текущего кадра можно узнать из свойства _currentframe. Его значение также невозможно изменить из сценария.

Прозрачность экземпляра мувика можно установить с помощью свойства _alpha. Не забудьте, что с помощью методов объекта Color setTransform и setRGB - также можно устанавливать как прозрачность экземпляра флэш-символа, так и его цвет.

Общее количество кадров мувика (или всего основного ролика) можно узнать из свойства _totalframes, а количество кадров, уже загруженных на данный момент, - из свойства _framesloaded. Это значение особенно актуально при загрузке ролика через Интернет. К этим двум свойствам мы еще вернемся в главе 7, когда речь пойдет о создании предзагрузчиков. Значения свойств _totalframes и _framesloaded изменить нельзя.

Свойство _visible управляет видимостью экземпляра. Если оно имеет значение false, мувик не отображается на экране.

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

6.2.2. Управление качеством воспроизведения

Качеством воспроизведения видеоряда управляет свойство _quality. Оно может принимать четыре значения: Low (Низкое), Medium (Среднее), High (Высокое) и Best (Наилучшее). В режиме Best (Наилучшее) кривые сглаживаются по наилучшему алгоритму (с сеткой 4x4), а также сглаживается вся растровая графика. То же самое происходит в режиме High (Высокое), однако здесь растровая графика сглаживается только в статических объектах. В режиме Medium (Среднее) сглаживание кривых происходит с использованием упрощенного алгоритма (сетка 2x2), а растровая графика вообще не сглаживается. В режиме Low (Низкое) не происходит даже сглаживания кривых. Как видите, повышение качества обеспечивается сглаживанием кривых линий. Чем больше кривых сглаживается, тем больше ресурсов компьютера требуется для прорисовки каждого отдельного кадра. При качестве Best (Наилучшее) многие компьютеры, не успевая прорисовать все кадры сколько-нибудь сложного ролика, начнут просто пропускать кадры. От таких пропусков качество видеоряда ролика страдает заметно сильнее, чем от отсутствия сглаживания некоторых кривых.

Поэтому свойство _quality следует устанавливать в зависимости от сложности ролика. Если ролик содержит много объектов и много анимации, если он имеет повышенную частоту кадров или содержит много текстовой информации, лучше предусмотреть переключение качества воспроизведения в режим Medium (Среднее) или даже Low (Низкое). Правда, текст в режиме Medium (Среднее) и, тем более, Low (Низкое) воспринимается крайне плохо, а при небольшом размере шрифта может стать и вообще нечитаемым.

Помимо свойства _quality, для определения и установки качества воспроизведения иногда используют также устаревшее свойство _highquality. Оно может принимать значения 0, 1 или 2, причем значение 2 соответствует наилучшему качеству.

Для настройки воспроизведения звука можно регулировать размер звукового буфера с помощью свойства _soundbuftime. При потоковом воспроизведении звука некоторая часть записи предварительно загружается в буфер (чтобы при небольших сбоях в канале связи звук не прерывался). По умолчанию размер звукового буфера равен 5 секундам записи. Значение свойства _soundbuftime должно быть целым числом.

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

Интересно также свойство _droptarget. Оно недоступно для изменения и всегда содержит имя экземпляра объекта, над которым находится текущий объект при перетаскивании. Чтобы это свойство имело смысл, к указанному объекту вначале должен быть применен оператор (или метод) startDrag. Об этом мы поговорим в главе 7.

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

6.2.3. Пример программного изменения свойств

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

Теперь щелкните на мувике правой кнопкой мыши и выберите в контекстном меню пункт Actions (Действия), чтобы открыть окно сценария объекта. Введите туда такой код:

onClipEvent (keyDown) {
   if (key.isDown(key.RIGHT)) {
      _x += 5;
   }
   if (key.isDown(key.LEFT)) {
      _x -= 5;
   }
   if (key.isDown(key.UP)) {
      _y -= 5;
   }
   if {key.isDown(key.DOWN)) {
      _y += 5;
   }
}

Этот сценарий отслеживает событие нажатия клавиши. Когда такое событие происходит, сценарий проверяет, какая именно клавиша нажата. Если нажата клавиша ВПРАВО, свойство _x увеличивается на 5 и, соответственно, весь мувик сдвигается на 5 пикселов вправо. Если нажата клавиша ВВЕРХ, то свойство _y уменьшается на 5 и так далее. Таким образом, мы перемещаем объект по экрану с помощью свойств _x и _y.

Для иллюстрации свойств _xmouse и _ymouse можно добавить в ролик еще одну особенность: пусть при перемещении мыши объект тоже немного перемещается в сторону перемещения указателя мыши. Это можно сделать, добавив в сценарий объекта еще один оператор onClipEvent, на сей раз связав его с событием mouseMove (Движение мыши). Чтобы понять, куда перемещается указатель мыши, нам придется каждый раз сохранять старые значения в специально созданных переменных (назовем их oldx и oldy) и затем сравнивать с ними новые координаты указателя мыши. В зависимости от результата этого сравнения можно увеличивать или уменьшать координаты нашего мувика (свойства _x и _y). Вот какой код можно, например, добавить:

onClipEvent (mouseMove) {
   if (_xmouse>oldx) {
      _x++;
      oldx = _xmouse;
   }
   if (_xmouse<oldx) {
      _x--;
      oldx = _xmouse;
   }
   if (_ymouse>oldy) {
      _y++;
      oldy = _ymouse;
   }
   if (_ymouse<oldy) {
      _y--;
      oldy = _ymouse;
   }
}

Для полной корректности сценария здесь не хватает одной детали. Дело в том, что первоначальные значения переменных oldx и oldy равны 0, однако указатель мыши может изначально находиться совсем в другом месте. Так что, если внимательно приглядеться, самое первое движение мыши в нашем ролике может вызвать сдвиг мувика совсем не в ту сторону, в какую требуется. И хотя эта мелочь почти незаметна, давайте попробуем ее исправить. Для этого проинициализируем значения наших переменных в сценарии первого (и единственного) кадра основного ролика:

rect.oldx = _xmouse;
rect.oldy = _ymouse;

Обратите внимание на то, что переменные oldx и oldy расположены внутри экземпляра мувика rect, поэтому обращение к ним из основного ролика требует указания имени этого объекта.

6.2.4. Программная анимация

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

Для первоначального размещения машинок применим метод Math.random. Он возвращает псевдослучайное число в диапазоне от 0 до 1. Нам нужно число от -70 до -30 (изменим только горизонтальные координаты объектов, поскольку по вертикали они уже расположены правильно). Умножим полученное случайное число на 40 и вычтем из результата 70. Аналогично получим случайное значение горизонтальной координаты для экземпляров, перемещающихся справа налево. Кстати, этим экземплярам мы еще не дали имя. Назовем их rac1, rac2 и rac3. Теперь создадим новый слой (можно назвать его Actions) и поместим в его первый кадр такой код:

car1._x = Math.random()*40-70;
car2._x = Math.random()*40-70;
car3._х = Math.random()*40-70;
rac1._x = Math.random()*40+560;
rac2._x = Math.random()*40+560;
rac3._x = Math.random()*40+560;

Итак, первоначальное расположение объектов на сцене готово. Теперь нужно осуществить собственно движение. Для этого нужно всего лишь увеличивать или уменьшать свойство каждого из экземпляров, а когда он "проедет" весь экран, возвращать его на исходную позицию. Поместим во второй кадр слоя Actions такой код:

car1._x++;
car2._x++;
car3._х++;
rac1._x--;
rac2._х--;
rac3._x--;
if (car1._x>580) {
   car1._x = Math.random()*40-70;
}
if (car2._x>580) {
   car2._х = Math.random()*40-70;
}
if (car3._х>580) {
   car3._х = Math.random()*40-70;
}
if (rac1._x<-10) {
   rac1._x = Math.random()*40+560;
}
if (rac2._x<-10) {
   rac2._x = Math.random()*40+560;
}
if (rac3._x<-10) {
   rac3._x = Math.random()*40+560;
}

Чтобы обеспечить цикличность выполнения этого кода, поместим в третий кадр слоя Actions оператор

gotoAndPlay (2);

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

Управление анимацией с клавиатуры

Попробуем несколько усложнить задачу. Пусть нажатие на цифровые клавиши от 1 до 6 приостанавливает на 2 секунды соответствующую машину, клавиши, находящиеся сразу под цифрами от 1 до 6 (то есть, клавиши Q - Y), увеличивают скорость движения каждого объекта, а клавиши следующего ряда (A - H) уменьшают.

Сначала давайте справимся с приостановкой нашей программной анимации. Введем для каждого из объектов вспомогательную переменную. Пусть ее значение равно нулю, если анимация идет обычным образом, а если произошла приостановка, то присвоим этой переменной значение getTimer() в момент приостановки. Теперь осталось вставить оператор if для проверки состояния вспомогательной переменной. Если она равна нулю, можно изменять значение _x, а если нет, то нужно ее сравнивать с текущим значением getTimer(). Если эта разница достигла 2000 миллисекунд, можно обнулить вспомогательную переменную, и в следующий раз анимация будет продолжена. Кроме того, нужно вставить проверку: не нажата ли соответствующая клавиша. Если это так, надо присвоить вспомогательной переменной текущее значение getTimer().

Пусть переменная s1 играет роль вспомогательной для экземпляра car1. Тогда в первом кадре мы на всякий случай присвоим ей начальное значение 0, а во втором напишем следующий код:

if (s1==0) car1._x++;
else if (getTimer()-s1>2000) s1 = 0;

и далее

if (key.isDown(ord(1)) {
   s1 = getTimer();
}

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

Осталось добавить ускорение и замедление движения. Это совсем простая задача. Вместо увеличения и уменьшения свойства _x на единицу внесем в код изменение на некоторую переменную величину, например, a1 для первого мувика (пусть вначале значение этой переменной равно 1). Проверим, как выше, методом key.isDown нажатие нужной клавиши и, соответственно, увеличим или уменьшим значение переменной a1:

if (key.isDown(ord("Q"))) {
   a1++;
   if (a1>20) a1--;
}

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

В принципе, две строки

a1++;
if (a1>20) a1--;

можно заменить одной:

if (a1<20) a1++;

но при небольшом размере сценария это не столь уж существенно. Добавим подобные конструкции и для остальных объектов.

Посмотрим, что у нас получилось в целом. Вот сценарий первого кадра:

car1._x = Math.random()*40-70;
car2._x = Math.random()*40-70;
car3._x = Math.random()*40-70;
rac1._x = Math.random()*40+560;
rac2._x = Math.random()*40+560;
rac3._x = Math.random()*40+560;
s1 = 0;
s2 = 0;
s3 = 0;
s4 = 0;
s5 = 0;
s6 = 0;
a1 = 1;
a2 = 1;
a3 = 1;
a4 = 1;
a5 = 1;
a6 = 1;

А вот какой код получился во втором кадре:

if (s1==0) car1._x += a1;
else if (getTimer()-s1>2000) s1 = 0;
if (s2==0) car2._x += a2;
else if (getTimer()-s1>2000) s2 = 0;
if (s3==0) car3._x += a3;
else if (getTimer()-s3>2000) s3 = 0;
if (s4==0) rac1._x -= a4;
else if (getTimer()-s4>2000) s4 = 0;
if (s5==0) rac2._x -= a5;
else if (getTimer()-s5>2000) s5 = 0;
if (car1._x>580) {
   car1._x = Math.random()*40-70;
}
if (car2._x>580) {
   car2._x = Math.random()*40-70;
}
if (car3._x>580) {
   car3._x = Math.random()*40-70;
}
if (rac1._x<-10) {
   rac1._x = Math.random()*40+560;
}
if (rac2._x<-10) {
   rac2._x = Math.random()*40+560;
}
if (rac3._x<-10) {
   rac3._x = Math.random()*40+560;
}
if (key.isDown(ord(1))) {
   s1 = getTimer();
}
if (key.isDown(ord(2))) {
   s2 = getTimer();
}
if (key.isDown(ord(3))) {
   s3 = getTimer();
}
if (key.isDown(ord(4))) {
   s4 = getTimer();
}
if (key.isDown(ord(5))) {
   s5 = getTimer();
}
if (key.isDown(ord(6))) {
   s6 = getTimer();
}
if (key.isDown(ord("Q"))) {
   a1++;
   if (al>20) a1--;
}
if (key.isDown(ord("W"))) {
   a2++;
   if (a2>20) a2--;
}
if (key.isDown(ord("E"))) {
   a3++;
   if (a3>20) a3--;
}
if (key.isDown(ord("R"))) {
   a4++;
   if (a4>20) a4--;
}
if (key.isDown(ord("T"))) {
   a5++;
   if (a5>20) a5--;
}
if (key.isDown(ord("Y"))) {
   a6++;
   if (a6>20) a6--;
}
if (key.isDown(ord("A"))) {
   a1--;
   if (al<0) a1++;
}
if (key.isDown(ord("S"))) {
   a2--;
   if (a2<0) a2++;
}
if (key.isDown(ord("D"))) {
   a3--;
   if (a3<0) a3++;
}
if (key.isDown(ord("F"))) {
   a4--;
   if (a4<0) a4++;
}
if (key.isDown(ord("G"))) {
   a5--;
   if (a5<0) a5++;
}
if (key.isDown(ord("H"))) {
   a6--;
   if (a6<0) a6++;
}

В третьем кадре расположена одна-единственная строка

gotoAndPlay (2);

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

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

[ предыдущая страница ] [ следующая страница ] [ содержание ]
Hosted by uCoz