Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Web-дизайн 1 часть / Литература / ActionScript 2.0. Программирование во Flash MX 2004.pdf
Скачиваний:
354
Добавлен:
26.03.2015
Размер:
8.81 Mб
Скачать

//При возникновении сбоя создаем текстовое поле и выводим в него об этом

//сообщение

listener.onLoadError = function():Void { clip.createTextField("error", 0, 50, 50, 0, 0); clip-error.autoSize = clip.error.border=true; clip.error.text = "Анимация не может быть загружена";

};

//По завершении загрузки первого кадра нужно сделать клип с анимацией

//невидимым, а также остановить его дальнейшую прокрутку listener.onLoadInit = function{):Void {

clip._visible = false; clip.stop();

}

//При загрузке очередной порции данных меняем длину шкалы прелоадера,

//а также обновляем значения в полях рrос и time

listener.onLoadProgress = function(clip:MovieClip, l_b:Number, t_b:Number): Void {

var percent:Number = l_b/t_b;

preloader.proc.text = Math.floor(percent*1000)/10; preloader.polosa._xscale = percent*100;

preloader.time.text = Math.round((1-percent)*(getTimerО-timer) / percent / 6000) /10; };

//При завершении загрузки удаляем предзагрузчик и ненужные более объекты.

//Затем делаем клип clip видимым и начинаем его прокрутку listener.onLoadComplete = function():Void {

preloader.swapDepths(1000), preloader.removeMovieClip(); delete loader, delete listener, delete timer; clip._visible=true, clip.play();

};

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

Делая вывод, можно сказать, что внешние предзагрузчики гораздо лучше внутренних. Кстати, среди встроенных компонентов Flash MX 2004 имеются простейший внешний предзагрузчик и шкала загрузки — Loader и ProgressBar. Особенности их применения мы обсудим в главе, посвященной компонентам.

Заканчивая разговор о создании предзагрузчиков, упомянем еще о двух инструментах, предназначенных для реализации прелоадеров. Это глобальные свойства _framesloaded (количество загруженных кадров) и _totalframes (полное число кадров в фильме). Соответственно, чтобы определить, какая часть фильма уже подгрузилась, нужно поделить величину _framesloaded на значение

_totalframes.

На практике прелоадеры при помощи свойств _framesloaded и _totalframes создаются исключительно редко. Это связано с тем, что обновляться такой предзагрузчик будет лишь по полному завершению загрузки кадра. Естественно, что это может быть приемлемо лишь в том редком случае, когда в фильме очень много кадров и информация по ним распределена достаточно равномерно. Скорее, данные свойства имеют историческое значение (во Flash 5 они применялись довольно активно, так как тогда метод getBytesLoaded() возвращал вес загруженных кадров, а не число реально подкачанных байтов). Правда, _totalframes иногда применяется в коде, управляющем навигацией по временной шкале — о таком ее использовании мы поговорим в разделе 10,14.

10.7.6. Кэширование swf-фильмов

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

метод называется кэшированием, и его поддерживают все современные браузеры. Кэшируются все элементы, встроенные в страницу, в том числе и swf-фильмы. Более того, кэшированию подвергаются даже фильмы, закачанные автономным плейером или плейером среды тестирования Flash, а также фильмы, загруженные посредством функции loadMovie(). В этом можно убедиться двумя способами. Во-первых, можно обратиться к директории, я которой хранятся кэшированные файлы (в русифицированной Windows их принято называть временными файлами Интернета — Temporary Internet Files). В Windows 2000 путь к этой директории имеет приблизительно следую-

щий вид: C:\Documenls and Settings\user\Local Settings\Temporary Internet Files. Во-вторых, можно сравнить время, которое требуется на то, чтобы была проведена первая и последующие загрузки фильма. Повторный импорт фильма потребует несопоставимо меньше времени.

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

Однако у кэширования есть и негативная сторона, связанная с отладкой. Например, представьте, что вы создаете предзагрузчик. Чтобы его тестировать, вы закачиваете некоторый swf-файл на сервер. Запустив фильм в первый раз, вы обнаруживаете ошибки и исправляете их. Однако проверить, корректно ли стал работать предзагрузчик, у вас не получится, так как реальная загрузка осуществляться не будет. Плейер просто возьмет копию фильма из папки Temporary Internet Files. Как же в такой ситуации провести отладку? Можно, конечно, менять имя фильма на сервере, но этот способ неэффективен. Более технично использовать один из следующих подходов;

удалять копию фильма из папки Temporary Internet Files. Подход хороший, если загружается немного фильмов;

воспользоваться тем, что URL может содержать придаток сданными (метод GET), причем один URL, но с разными данными воспринимается как разные ссылки. Следовательно, присоединяя к адресующему фильм URL случайное число, можно заставить плейер осуществлять загрузку из сети даже тогда, когда в кэше имеется копия фильма. Важное условие успешности описанного подхода следующее: ссылка на swf-файл должна быть абсолютной, а не относительной. Например:

this.createEmptyMovieClip("clip", 0); clip.loadMovie("http://www.mysite.ru/film.swf?"+Math.random());

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

Бороться с кэшированием фильмов, встроенных в HTML-страницу, также несложно. Для этого можно к URL, адресующему фильм, присоединять случайное число (посредством JavaScript). Также можно использовать серверный скрипт, который будет исполнять роль посредника. Наиболее же простой способ избежать кэширования заключается в создании следующего заголовка:

<НЕАD>

<МЕТА HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE"> </HEAD>

10.7.7. Изменение глубины основной временной диаграммы

Мы уже не раз отмечали, что не существует особых различий между основной временной диаграммой и клипами. Следовательно, должно иметься прямое сходство между виртуальными слоями клипов и уровнями. Так, главная временная диаграмма обладает, как и любой клип, глубиной. Ее значение можно прочитать, используя метод getDepth(), и переопределить при помощи метода swapDepths():

trace(_root.getDepth());

// Выводит: -16384

_root.swapDepths(1000);

// Пробуем изменить глубину _root

trace(_root.getDepth());

// Выводит:

1000 (глубина была успешно изменена)

trace(_root);

//

Выводит:

_level0 (изменение глубины не

 

//

повлекло

изменения уровня)

Проанализировав приведенный код, можно сделать два важных вывода:

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

Уровень, занимаемый фильмом, и глубина его основной временной диаграммы прямо никак не связаны.

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

trace(_root.getDepth());

Затем опубликуем новый фильм на Рабочий Стол, назвав 1 .swf.

Далее создадим еще один документ и на его первом кадре наберем:

loadMovieNum("1.swf", 1);

Чтобы при тестировании данного фильма файл 1.swf попал в его область видимости, сохраняем соответствующий ему fla-файл на Рабочем Столе. Нажимаем <Ctrl> + <Enter>. В панели Output при этом появляется -16383. Пробуем заменить уровень, на который подгружается 1.swf, на 100-й. При этом в Output выводится число -16284.

Итак, оказывается, что уровень и глубина взаимозависимы. Более того, можно даже вывести однозначную формулу, связывающую глубину основной временной диаграммы с соответствующим ей уровнем: depths=-16384+level. Но почему тогда при изменении глубины не модифицируется уровень, по которому адресуется фильм (см. пример выше)?

А ответить на этот вопрос очень просто, предположив, что реально никаких уровней не существует. Имеются глубины, на которых действительно располагаются фильмы. Эти глубины полностью аналогичны виртуальным слоям обычных клипов. Их можно прочитать и даже изменить. Уровни же — это лишь удобная форма для именования проигрываемых в плейере фильмов и задания параметров для функций и методов семейства loadMovie (действительно, если бы отсчет велся от - 16384, работать с ними было бы гораздо сложнее). Итак _lеvel0 — это имя загруженного первым фильма, а не указатель на глубину, на которой он находится. Фильм с таким именем может располагаться и на миллионной глубине, отображаясь выше всех остальных фильмов.

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

but.onRelease=function():Void { _root.swapDepths(1000);

}

Тут же расположим код, подгружающий второй фильм в первый:

loadMovieNum("2.swf", 1);

Сохраняем фильмы n одной директории как 1.swf и 2.swf. Далее запускаем проигрывание файла 1.swf. При этом в плейере содержимое второго фильма отобразится выше содержимого первого. После нажатия кнопки but объекты первого фильма окажутся выше объектов второго.

Таким образом, используя метод swapDepths(), можно менять порядок отображения фильмов в плейере точно так же, как и вложенных клипов. А это означает, что клипы являются по своей сути как бы маленькими swf-фильмами (точнее, что нет принципиальных отличий между объектами, которые мы называем клипами, и структурами, стоящими за термином «фильм»). В качестве дополнительного доказательства такого утверждения можно привести тот факт, что при помощи loadMovie() любой swf-файл может быть подгружен в клип.

Кстати, можно обменять два фильма глубинами, используя их имена. Для этого нужно использовать второй вариант синтаксиса метода swapDepths():

_level0.awapDepths(_level1);

Функции и методы семейства IoadMovie() не учитывают глубин фильмов. Поэтому запись loadMovieNum(«1.swf»,1) не всегда означает, что фильм будет помещен на глубину -16383. Если в плейере уже имелся фильм с именем _level1, то новый фильм просто заместит его. А располагаться он при этом может на любой глубине.

10.7.8. Доступ из одного фильма к объектам другого

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

_level1.mov.start Drag(); // Клип mov фильма level1 становится протаскиваемым

Аналогичным образом можно прочитать значение переменной или даже вызвать функцию кода другого фильма.

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

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

Так как уровни — это просто имена подгруженных в плейер фильмов, то создать переменную на незаполненном уровне невозможно. Например:

_level1.prop = "Привет"; trace(_level1.prop); // Выводит: undefined

Все, что мы говорили выше о доступе одного из проигрываемых в плейере фильмов к элементам другого, по умолчанию справедливо лишь в том случае, если оба фильма были получены с одного домена или же соответствующий фильму, к которому происходит обращение, swf-файл хранится локально. Если же фильмы были закачаны с разных доменов, то начинают работать ограничения, связанные с политикой сетевой безопасности Flash MX 2004.

Соседние файлы в папке Литература