Архив рубрики «часть 6»
Руководство по actionscript. часть 6, стр. 001
ГЛАВА 28
Загрузка внешних отображаемых элементов
В ActionScript существует три способа добавления внешнего отображаемого элемента в приложение программным путем:
? использование класса flash. display. Loader для загрузки элемента на этапе выполнения;
? применение класса flash. net. Socket совместно с методом экземпляра loadBytes ( ) класса Loader для загрузки элемента на этапе выполнения через открытый сокет TCP/IP;
? использование тега метаданных [Embed] для встраивания элемента, находящегося в локальной файловой системе, на этапе компиляции.
Классы Loader и Socket являются собственными классами API среды выполнения Flash, в то время как для использования тега метаданных [Embed] требуется платформа разработки Flex. Все три подхода поддерживают следующие форматы отображаемых элементов:
? SWF (скомпилированные приложения Flash);
? JPEG, GIF или PNG (растровые изображения).
Кроме того, тег метаданных [Embed] поддерживает отображаемые элементы в формате SVG.
Продолжение:
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,
41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,
77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,
Руководство по actionscript. часть 6, стр. 002
В этой главе будет рассказано, как использовать классы Loader и Socket, а также тег метаданных [ Embed ] для загрузки внешних отображаемых элементов. Подробную информацию о загрузке шрифтов вы сможете найти в гл. 27. Сведения о загрузке содержимого XML можно найти в гл. 18. Кроме того, информацию о загрузке других неотображаемых элементов, например переменных, бинарных данных или звуковых файлов, можно найти в описании классов URLLoader, URLStream и Sound в справочнике по языку ActionScript корпорации Adobe.
Класс Loader заменяет следующие инструменты языка ActionScript 2.0, предназначенные для загрузки элементов: класс MovieClipLoader; глобальные функции loadMovie() и loadMovieNum(); методы экземпляра loadMovie() и loadMovieNum() класса MovieClip.
Использование класса Loader для загрузки отображаемых элементов на этапе выполнения
Класс Loader применяется для загрузки внешних отображаемых элементов на этапе выполнения. Элемент может быть получен либо по протоколу HTTP, либо из локальной файловой системы. Чтобы воспользоваться классом Loader, необходимо выполнить три основных шага.
1. Создать экземпляр класса flash, display. Loader.
2. Создать экземпляр класса flash. net. URLRequest, определяющий местоположение элемента.
3. Передать экземпляр класса URLRequest в метод load ( ) класса Loader.
В следующих разделах мы создадим пример класса Sunse tviewer, в котором подробно рассматриваются описанные шаги. Класс из нашего примера будет загружать единственное растровое изображение sunset. j pg. Освоив базовые положения загрузки элементов, вы узнаете, как отслеживать ход выполнения операции загрузки с помощью класса flash. display. Loaderlnf о. Наконец, мы рассмотрим код, необходимый для обращения к загруженному элементу и его добавления в список отображения.
Операции загрузки подчиняются ограничениям безопасности приложения Flash Player. м$ 4 * Полную информацию можно получить в гл. 19.
В классе SunsetViewer нашего примера мы предполагаем, что SWF-файл приложения SunsetViewer. swf будет размещен на сайте в той же директории, где находится загружаемое изображение sunset. j pg.
Руководство по actionscript. часть 6, стр. 003
Создание экземпляра класса Loader
Как мы уже знаем, первым шагом в загрузке любого отображаемого элемента на этапе выполнения с помощью класса Loader является создание экземпляра класса Loader. Этот экземпляр управляет операцией загрузки и предоставляет доступ к загруженному элементу. Мы создадим наш экземпляр класса Loader в методе-конструкторе класса SunsetViewer и присвоим его переменной экземпляра loader, как показано в листинге 28.1.
Листинг 28.1. Создание экземпляра класса Loader
Package { import flash. display.*;
public class SunsetViewer extends Sprite { private var loader:Loader;
public function SunsetViewer ( ) { loader = new Loader( ); // Создаем экземпляр класса Loader
Определение местоположения элемента
Чтобы загрузить внешний отображаемый элемент с помощью экземпляра класса Loader, мы должны указать местоположение этого элемента с помощью объекта flash. net. URLRequest. Каждый отдельный объект URLRequest описывает местоположение одного внешнего ресурса, находящегося либо в сети, либо в локальной файловой системе. Чтобы создать объект URLRequest, который определяет местоположение элемента, используйте следующий обобщенный код, присваивающий местоположение элемента переменной экземпляра url:
var urlRequest:URLRequest = new URLRequest( ); url Request, url = «ацреситЭпемента»:
Кроме того, местоположение элемента может быть передано в качестве параметра конструктору класса URLRequest, как показано в следующем коде:
var url:URLRequest = new URLRequesti» адреси[ИЭлемента»);
В обоих случаях aupecURLJneMeHTa — это строка, содержащая стандартный адрес URL. Например:
new URLRequest(«http://www. examp1e. com/image. jpg»);
Набор сетевых протоколов, которые допускается использовать в строке anpecURLdne-мента, зависит от операционной системы. Например, протоколы http: / /, https: / / и f tp: / / поддерживаются всеми операционными системами Windows, Macintosh и UNIX, однако обращение к содержимому справки Windows (ms-its:) может поддерживаться только в операционной системе Windows. Из соображений безопасности приложение Flash Player может также блокировать некоторые протоколы. Тем не менее в настоящее время корпорация Adobe не публикует список блокируемых протоколов. Более того, среда выполнения Flash не генерирует никаких сообщений об ошибках безопасности, относящихся конкретно к блокированию протокола. По этой причине при работе с редко используемыми протоколами не забывайте, что операции загрузки с применением таких протоколов могут потерпеть неудачу, не вызвав никаких ошибок.
Руководство по actionscript. часть 6, стр. 004
Помимо определения адреса URL, каждый объект URLRequest может также предоставлять дополнительную информацию для запрашиваемого по HTTP-протоколу ресурса. Чтобы указать заголовок HTTP-запроса, используемый метод, данные для метода POST, строку запроса и тип содержимого MIME, просто установите соответствующие переменные объекта URLRequest, как описано в справочнике по языку ActionScript корпорации Adobe. Например, чтобы определить заголовки HTTP-запроса, установите переменную экземпляра requestHeaders класса URLRequest.
Местоположение элемента может быть указано в виде абсолютного или относительного URL-адреса. Однако стоит отметить, что система приложения Flash Player, отвечающая за разрешение относительных адресов URL, зависит от способа запуска приложения Flash Player.
? Если приложение Flash Player запускается с целью отображения SWF-файла, встроенного в веб-страницу с помощью тега или, все от-
носительные адреса URL разрешаются относительно этой веб-страницы, а не относительно какого-либо SWF-файла. Более того, если веб-страница была открыта локально^ относительные адреса URL разрешаются локально. Если веб-страница была открыта с сайта, относительные адреса URL разрешаются с использованием адреса этого сайта. ? Когда приложение Flash Player запускается как автономное приложение или в результате непосредственного открытия SWF-файла в браузере, поддерживающем формат Flash, все относительные адреса URL разрешаются относительно первого SWF-файла, открытого в приложении Flash Player, — этот файл называется владельцем сцены. Более того, если владелец сцены был открыт локально, относительные адреса URL разрешаются локально; если владелец сцены был открыт с сайта, относительные адреса URL разрешаются с использованием адреса этого сайта.
*^ I Даже если первый SWF-файл, открытый в приложении Flash Player, будет удален со сцены, А щ он останется владельцем сцены и по-прежнему будет оказывать влияние на разрешение ц»У относительных URL-адресов.
Рассмотрим пример с использованием относительных адресов URL, который демонстрирует две описанные системы разрешения. Предположим, что мы встроили приложение SunsetViewer. swf в веб-страницу SunsetViewer. html и сохранили эти два файла в следующих отдельных директориях:
/vi ewer/SunsetVi ewer. html
/vi ewer/assets/SunsetVi ewer. swf
Предположим также, что из приложения SunsetViewer. swf мы хотим загрузить изображение sunset. jpg, которое тоже находится в директории /assets/:
/viewer/assets/sunset. jpg
Если мы считаем, что пользователь будет запускать приложение SunsetViewer. swf, открывая веб-страницу SunsetViewer. html, мы должны сформировать наш относительный URL-адрес относительно данной веб-страницы, как показано в следующей строке кода:
new URLRequest(«assets/sunset. jpg»);
Тем не менее, если мы считаем, что пользователь будет запускать приложение, непосредственно открывая файл SunsetViewer. swf, мы должны сформировать наш относительный URL-адрес относительно SWF-файла, а не веб-страницы, как показано в следующей строке кода:
new URLRequest(«sunset. jpg»);
*»,
^ I При распространении содержимого, воспроизводимого в приложении Flash Player, фор-
*S: А 9 мируйте все относительные адреса URL в соответствии с тем, как ваши пользователи
tlft будут запускать приложение Flash Player.
Руководство по actionscript. часть 6, стр. 005
Даже если один SWF-файл загружает другой SWF-файл, который, в свою очередь, загружает внешние элементы, относительные адреса URL все равно разрешаются
либо относительно владельца сцены (в случае непосредственного запуска), либо относительно веб-страницы, содержащей встроенное приложение Flash Player (в случае открытия страницы).
Предположим, что мы открываем гипотетическое приложение SlideShow. swf непосредственно в приложении Flash Player. Кроме того, предположим, что приложение SlideShow. swf загружает приложение SunsetViewer. swf из предыдущего примера. В данном случае все относительные URL-адреса в приложении SunsetViewer. swf должны быть сформированы относительно файла SlideShow. swf (обратитевнимание: не относительно приложения SunsetViewer. swf!). Подобным образом, если бы приложение SlideShow. swf открывалось через веб-страницу, все относительные адреса URL в приложении SunsetViewer. swf должны были быть сформированы относительно данной страницы.
^ I Вы можете полностью избежать проблем, связанных с различными вариантами разре-м$ 4 „ шения относительных адресов URL, сохранив все HTML-, SWF-файлы и файлы внешних —отображаемых элементов в одной директории.
Вернемся к нашему примеру класса SunsetViewer. Ранее в листинге 28.1 мы создали экземпляр класса Loader. В листинге 28.2 представлен обновленный класс SunsetViewer, в который был добавлен код, создающий запрос для относительного URL-адреса «sunset. jpg». Как было отмечено ранее, для упрощения нашего примера мы предполагаем, что файлы sunset. jpg и SunsetViewer. swf находятся в одной директории — это позволяет избежать любых сложностей, связанных с разрешением относительных адресов URL.
Листинг 28.2. Определение местоположения элемента
package { import flash. display.*:
import flash. net. URLRequest; // Импортируем класс URLRequest
public class SunsetViewer extends Sprite { private var loader:Loader:
public function SunsetViewer ( ) { loader = new Loader( );
// Определяем местоположение элемента в виде «sunset. jpg» var urlRequest:URLRequest = new URLRequest(«sunset. jpg»);
}
}
}
Теперь, когда мы определили местоположение файла sunset. jpg, загрузим его.
Руководство по actionscript. часть 6, стр. 006
Начало загрузки
До настоящего момента мы уже создали объекты Loader и URLRequest. Теперь соединим их, чтобы загрузить элемент. Чтобы начать загрузку, мы передаем наш экземпляр класса URLRequest в метод load ( ) экземпляра класса Loader, как показано в листинге 28.3.
Листинг 28.3. Начало загрузки
package { import flash. display.*; import flash. net. URLRequest;
public class SunsetViewer extends Sprite { private var loader;Loader;
public function SunsetViewer ( ) { loader = new Loader( );
var url;URLRequest = new URLRequest(«sunset. jpg»); // Начинаем загрузку loader. load(url);
} •
Итак, вот основной код, необходимый для загрузки внешнего отображаемого элемента на этапе выполнения:
var loader-.Loader = new Loader( );
var url;URLRequest = new URLRequesti» адресШО-Элемента»);
loader. load(url);
Здесь адресиШЭлемента — это местоположение загружаемого элемента. Кроме того, допустимо и достаточно распространено объединять вторую и третью строки из предыдущего кода в одну, как показано в следующем коде:
var loader;Loader = new Loader( );
1 oader. 1 oad(new URLRequest(«адресиШэлемента»)):
^ 1 Чтобы отменить выполняемую операцию загрузки, используйте метод экземпляра close()
—-3* -
класса Loader.
Руководство по actionscript. часть 6, стр. 007
После начала загрузки элемента мы в конечном итоге захотим обратиться к этому элементу и отобразить его на экране. Эти вопросы рассматриваются в двух следующих разделах.
Обращение к загруженному элементу
Благополучно обратиться к загруженному элементу можно только после того, как среда выполнения Flash проведет его инициализацию. На этапе инициализации среда выполнения Flash создает экземпляр элемента, добавляет его в объект Loader, загрузивший этот элемент, и выполняет любые задачи, необходимые для подготовки элемента к использованию.
Этап процесса инициализации, на котором создается экземпляр, отличается для разных типов элементов.
? Для растровых изображений экземпляр создается в тот момент, когда загрузка внешнего файла полностью завершена. Тогда загруженные пиксельные данные автоматически помещаются в объект BitmapData, который связывается
с новым объектом Bitmap. Загруженное изображение представляется объектом Bitmap.
? Для SWF-файлов экземпляр создается в тот момент, когда получены все элементы и классы для кадра 1 (включая основной класс SWF-файла). Тогда среда выполнения Flash создает экземпляр основного класса SWF-файла и выполняет его конструктор. Загруженный SWF-файл представляется экземпляром основного класса.
^ I Для простоты в дальнейшем материале мы будем называть созданный экземпляр (либо м$ л * объект Bitmap, либо экземпляр основного класса SWF-файла) объектом элемента.
После создания экземпляра загруженного элемента объект элемента автоматически добавляется в объект Loader. Объект элемента является первым и единственным возможным ребенком объекта Loader. Если элементом оказывается SWF-файл, то любой код, находящийся в первом кадре этого файла, выполняется сразу после добавления экземпляра его основного класса в объект Loader.
После того как объект элемента будет добавлен в объект Loader и процесс инициализации будет завершен, среда Flash выполнит диспетчеризацию события Event. INIT. Когда возникает событие Event. INIT, загруженный элемент считается готовым к использованию. Любой код, которому необходим доступ к загруженному элементу, должен выполняться только после возникновения события Event. INIT.
Руководство по actionscript. часть 6, стр. 008
Не пытайтесь обращаться к загружаемому элементу до возникновения события Event. INIT.
Приемники, которые желают получать уведомления о возникновении события Event. INIT, должны быть зарегистрированы в объекте Loaderlnf о объекта элемента, а не в объекте Loader, над которым изначально был вызван метод load ( ). Объект Loaderlnfo— это отдельный объект, который представляет информацию о загруженном элементе. Любой экземпляр класса Loader предоставляет ссылку на объект Loaderlnfo своего загружаемого элемента через переменную экземпляра contentLoaderInf о. Таким образом, чтобы зарегистрировать приемник события для события Event. INIT некоторого элемента, мы используем следующий обобщенный код:
объект1_оас! ег. contentLoader Inf о. addEventLi stener (Event. INIT, приемникСобытияШ1Т);
Здесь объект1_оас! ег — это объект Loader, загружающий элемент, а приемникСобы-тияШП — ссылка на функцию, которая будет обрабатывать событие Event. INIT. После возникновения события Event. INIT благополучно обратиться к загруженному элементу можно через переменную content или метод getChildAt ( ) класса Loader, как показано ниже:
объект1оабег. content объект1оабег. getChi1dAt СО)
Обратите внимание на значение 0 в выражении getChildAt (0). Элемент является единственным ребенком объекта Loader, поэтому он находится на глубине с индексом 0.
Следующий код демонстрирует приемник события Event. INIT, который устанавливает позицию загруженного и проинициализированного элемента. Для демонстрации двух различных способов обращения к загруженному элементу этот код устанавливает горизонтальную позицию с помощью переменной content, а вертикальную позицию — с использованием выражения getChildAt (0).
private function initListener (e:Event):void { объектLoader. content. x = 50; oбъeктLoader. getCh^^(\^t(Q).y = 75;
}
В качестве альтернативы обратиться к загруженному элементу можно через объект Event, передаваемый в функцию-приемник события Event. INIT. Этот объект определяет переменную target, которая ссылается на объект Loaderlnfo элемента. Каждый объект Loaderlnfo ссылается на свой соответствующий элемент через переменную экземпляра content. Таким образом, внутри функции-приемника события Event. INIT ссылка на загруженный элемент может быть получена с помощью выражения o6beKTEvent. target. content. Например, следующий код устанавливает горизонтальной позиции загруженного элемента значение 100:
private function initListener (e;Event):void { e. target. content. x = 100;
}
При обращении к загруженным элементам следует помнить, что, поскольку элемент не добавляется в свой объект Loader до тех пор, пока процесс загрузки данного элемента не будет успешно завершен, вызов метода o6beKTLoader. getChi 1 dAt (0) до начала операции загрузки приведет к ошибке.
Руководство по actionscript. часть 6, стр. 009
Напомним, что элемент растрового изображения не добавляется в свой объект Loader до тех пор, пока не будет полностью загружен внешний файл. Элемент SWF-файла не добавляется в свой объект Loader до тех пор, пока не будут получены все элементы и классы для первого кадра, включая основной класс SWF-файла.
Более того, перед началом загрузки переменная content содержит значение nul 1. Это демонстрирует следующий код:
// Начинаем загрузку
var loader:Loader = new Loader( );
1oader.1oad(new URLRequest(«sunset. j pg»));
// Сразу же пытаемся обратиться к загружаемому элементу. // не дожидаясь завершения загрузки
traced oader. getChi 1 dAt (0)): // RangeError. Ошибка #2006:
// The supplied index is out of bounds. // (Указанный индекс выходит за пределы.)
tracedoader. content); // Выводит: null
Даже если операция загрузки началась, но элемент не был успешно загружен, обращение к переменной content или вызов метода getChildAt (0) приведет к следующей ошибке:
Error: Error #2099: The loading object is not sufficiently loaded to provide this information.
Руководство по actionscript. часть 6, стр. 010
На русском языке она будет выглядеть так: Загружаемый объект не был успешно загружен для предоставления данной информации.
Снова повторим: не пытайтесь обращаться к загружаемому элементу до момента возникновения события Event. INI Т. На самом деле обратное также верно: перед тем как обратиться к родительскому объекту Loader, код в основном классе загруженного SWF-файла должен дождаться возникновения события Event. INIT. В частности, код в конструкторе основного класса загруженного SWF-файла не имеет доступа к родительскому объекту Loader. С другой стороны, код, помещенный в первый кадр временной шкалы загруженного SWF-файла (в среде разработки Flash), может обращаться к родительскому объекту Loader (до возникновения события Event. INIT).
Воспользуемся новыми знаниями по обращению к элементам на примере класса SunsetViewer. В листинге 28.4 показано, как обращаться к загруженному файлу sunset. jpg из функции-приемника события Event. INIT. Эта функция отображает высоту, ширину и угол поворота загруженного изображения с помощью методик обращения к элементу, рассмотренных в данном разделе.
Листинг 28.4. Обращение к загруженному элементу
package { import flash. display.*; import flash. net. URLRequest; import flash. events.*;
public class SunsetViewer extends Sprite { private var loader:Loader;
public function SunsetViewer ( ) { loader = new Loader( );
// Регистрируем приемник для события Event. INIT
1 oader. contentLoaderlnfо. addEventLi stener(Event. INIT, initListener);
var urlRequest:URLRequest = new URLRequest(«sunset. jpg»); 1oader.1oad(urlRequest);
}
// Приемник вызывается при возникновении события Event. INIT private function initListener (e:Event):void {
// Обращаемся к элементу тремя различными способами
trace(1oader. content. wi dth);
trace(1oader. getChi1dAt(0).hei ght);
trace(e. target. content. rotati on);
}
S$4
Чтобы для загруженного элемента использовать методы и переменные класса Bitmap, MovieClip или основного класса SWF-файла, следуйте методикам, описанным далее в разд. «Проверка типов на этапе компиляции для динамически загружаемых элементов».