Февраль 2011

Руководство по actionscript. часть 6, стр. 035

И. В окне Library Path Item Options (Параметры элемента путей библиотек) нажмите кнопку ОК. 12. В окне Properties (Свойства) нажмите кнопку ОК.

В приложении Flash CS3, чтобы включить файл module. swc в пути внешних библиотек, мы просто помещаем его в ту же папку, где находится файл Main. fla (или в любую другую папку из путей к классам файла Main. fla), и удаляем компонент Module с палитры Library (Библиотека) файла Main. fla.

Как только файл module. swc будет включен в пути внешних библиотек приложения Main, swf, компилятор сможет проверять типы для любого обращения к классу Module, происходящего в приложении Main. swf. Однако, в отличие от методик путей библиотек и путей исходных файлов, когда приложение Ma in. swf компилируется с использованием методики путей внешних библиотек, компилятор не копирует байт-код класса Module в приложение Main. swf. Таким образом, общий размер файлов приложения будет минимальным. Тем не менее исключение байт-кода класса Module из приложения Main. swf приводит к новой проблеме: на этапе выполнения любая ссылка на класс Module из приложения Main. swf оказывается неизвестной для среды выполнения Flash. В связи с этим следующий код:

Moduledoader. content).startC )

вызовет такую ошибку на этапе выполнения:

ReferenceError: Error #1065: Variable Module is not defined.

На русском языке она будет выглядеть так: Ошибка обращения: переменная Module не определена.

Чтобы избежать данной ошибки, мы должны заставить среду выполнения Flash импортировать классы приложения Module, swf в домен приложения файла Main. swf на этапе выполнения.

Домен приложения SWF-файла предоставляет доступ к классам этого файла. Домены приложения определяют, как загруженные SWF-файлы совместно используют классы и другие определения. Дополнительную информацию можно найти в разделе Programming ActionScript 3.0 > Flash Player APIs > Client System Environment > ApplicationDomain class документации корпорации Adobe. Кроме того, обратитесь к гл. 31.

Чтобы импортировать классы приложения Module. s wf в домен приложения файла Main. swf, при создании запроса на загрузку приложения Module. swf мы используем объект LoaderContext. Рассмотрим, как выглядит код, добавляемый в основной класс приложения Main. swf:

// Сначала импортируем классы ApplicationDomain и LoaderContext… import flash. system.*;

// …затем в классе используем объект LoaderContext, чтобы импортировать // классы и другие определения файла Module. swf в домен приложения // файла Main. swf

1oader.1oad(new URLRequest(«Module. swf»).

Руководство по actionscript. часть 6, стр. 036

New LoaderContext(false, ApplicationDomain. currentDomain));

В результате выполнения предыдущего кода классы (и другие определения) файла Module. swf становятся непосредственно доступными для кода приложения Main. swf — будто они были определены в приложении Main. swf.

Стоит отметить, что, если файлы Main, swf и Module, swf находятся в разных удаленных регионах или если файл Main, swf находится в локальной области действия и его тип безопасности песочницы отличается от типа безопасности песочницы файла Module. swf, попытка импортировать классы файла Module. swf в домен приложения файла Main, swf завершится неудачно без сообщения об ошибке. В данном случае следующий код:

Moduledoader. content).start( )

вызовет ту же ошибку, которая возникла бы в случае, когда классы приложения Module. swf вообще не импортируются в домен приложения файла Main. swf:

ReferenceError: Error #1065: Variable Module is not defined.

По-русски ошибка выглядит так: Ошибка обращения: переменная Module не определена.

В определенных ситуациях избежать подобного ограничения безопасности можно с помощью импортирующей загрузки, при которой приложение Ma in. s wf использует объект LoaderContext, чтобы импортировать файл Module. swf в свой домен безопасности. Это демонстрирует следующий код:

var loaderContext:LoaderContext = new LoaderContext( ):

1 oaderContext. appli cati onDomai n = Appli cati onDomai n. currentDomai n;

var loader:Loader = new Loader( );

loader. load(new URLRequest(«Module. swf»), loaderContext):

Полную информацию по импортирующей загрузке можно получить в разд. «Импортирующая загрузка» гл. 19.

Руководство по actionscript. часть 6, стр. 037

Для обзора и для справки в листинге 28.9 представлен код для классов Main и Module, рассмотренных в данном разделе. Предполагается, что файл module. swc был создан и включен в пути внешних библиотек приложения Module. swf.

Листинг 28.9. Классы Main и Module

// Класс Main

package { import flash. display.*; import flash. net.*; import flash. events.*; import flash. system.*;

public class Main extends Sprite { private var loader:Loader;

public function Main( ) { loader = new Loader( );

1 oader. contentLoaderInfо. addEventLi stener(Event. INIT.

initListener);

1oader.1oad(new URLRequest(«Module. swf»), new LoaderContext(false,

Appli cati onDomai n. currentDomai n));

}

private function initListener (e:Event):void { traceC’init»);

Module(e. target. content).start( );

}

}

}

// Класс Module

package { import flash. display. Sprite;

public class Module extends Sprite { public function Module( ) { }

public function start ( ):void { trace(«Module. start( ) was invoked…»);

}

}

}

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

Руководство по actionscript. часть 6, стр. 038

Обращение к элементам в многокадровых SWF-файлах

Ранее из подразд. «Обращение к загруженному элементу» разд. «Использование класса Loader для загрузки отображаемых элементов на этапе выполнения» мы узнали, что в тех случаях, когда один SWF-файл загружает другой SWF-файл, все отображаемые элементы и объекты, создаваемые программным путем и размещаемые в первом кадре загружаемого SWF-файла, становятся доступными сразу после возникновения события Event. INIT. Таким образом, код в приемнике события Event. INIT может сразу же выполнять действия над этими элементами и объектами. Тем не менее код в приемнике события Event. INIT не может выполнять действия над элементами и объектами, которые размещаются в последующих кадрах загруженного SWF-файла.

Любой код, желающий обратиться к элементам и объектам, которые размещаются во втором или последующих кадрах загруженного SWF-файла, должен сначала убедиться в существовании этих элементов и объектов. Убедиться, что нужные элементы и объекты существуют в загруженном SWF-файле, можно двумя способами. В SWF-файле, из которого происходит обращение, нужно:

? периодически проверять существование элемента или объекта с помощью объекта

Timer;

? зарегистрировать приемник для пользовательского события, генерируемого загруженным SWF-файлом в тот момент, когда элемент или объект становится доступным.

Рассмотрим каждую из перечисленных методик на примере. Мы снова будем использовать сценарий из предыдущего раздела, в котором приложение Main. swf загружает приложение Module. swf. Предположим, что во втором кадре основной временной шкалы приложения Module. swf размещается сценарий, который создает объект TextField t. Приложение Main. swf загружает приложение Module. swf и желает обратиться к объекту t. Рассмотрим сценарий временной шкалы приложения Module. swf:

stop( );

var t:TextField = new TextField( );

t. text = «hello»;

addChild(t);

В листинге 28.10 показано, как приложение Main. swf загружает приложение Module. swf, а затем периодически проверяет существование объекта TextField перед его использованием.

Руководство по actionscript. часть 6, стр. 039

Листинг 28.10. Периодическая проверка существования загруженного объекта

package { import flash. display.*; import flash. events.*; import flash. net.*; import flash. utils.*;

public class Main extends Sprite { private var loader:Loader;

public function Main( ) { // Загружаем файл Module. swf loader = new Loader( );

1 oader. contentLoaderlnfo. addEventLi stener(Event. INIT.

initListener);

1oader.1oad(new URLRequest(«Module. swf»));

}

private function initListener (e:Event):void { // Загруженный SWF-файл был проинициализирован, // поэтому начинаем периодическую проверку существования // объекта TextField. var timer:Timer = new TimerdOO, 0); timer. addEventListener(TimerEvent. TIMER, timerListener); timer. start( );

}

private function timerListener (e:TimerEvent):void { // Проверяем, был ли создан объект TextField // загруженного SWF-файла if (loader. content. hasOwnPropertyC’t»)) {

// Объект TextField уже существует, поэтому мы можем благополучно

// обратиться к нему

trace(Object(loader. content).t. text);

// Останавливаем таймер е. target. stop( );

}

}

}

}

Теперь снова предположим, что приложение Main, swf загружает приложение Module. swf и желает обратиться к объекту t. На этот раз, однако, основной класс Module приложения Module. swf рассылает пользовательское событие Module. ASSETS_READY, когда объект t становится доступным. Приложение Main. swf регистрирует приемник для события Module. ASSETS_READY и обращается к объекту t, когда возникает данное событие. Рассмотрим код для класса Module, в котором определена константа события:

package { import flash. display. MovieClip;

class Module extends MovieClip { // Определяем константу события

public static const ASSETS_READY:String = «ASSETS_READY»;

Теперь рассмотрим сценарий, размещаемый во втором кадре основной временной шкалы приложения Module. swf, который осуществляет диспетчеризацию события, обозначающего доступность объекта t:

stop( );

var t:TextF1eld = new TextField( );

t. text = «hello»;

addChild(t);

di spatchEvent(new Event(Module. ASSETS_READY));

Наконец, в листинге 28.11 представлен код для основного класса приложения Main. swf. Предполагается, что на этапе компиляции компилятор языка ActionScript не имеет доступа к определениям классов загружаемого SWF-файла. В итоге этот код ссылается на событие Module. ASSETS_READY по его строковому имени «ASSETS_READY»:

1oader. content. addEventListener(«ASSETS_READY», assetsReadyListener);

Подобным образом в данном коде значение переменной loader. content приводится к типу Ob j ect, поэтому проверка типов откладывается до этапа выполнения:

Object(1oader. content).t. text

Полную информацию о проверке типов загружаемых элементов можно найти в разд. «Проверка типов на этапе компиляции для динамически загружаемых элементов».

Руководство по actionscript. часть 6, стр. 040

Листинг 28.11. Обработка события, сообщающего о доступности загруженного объекта

package { import flash. display.*; import flash. events.*; import flash. net.*; import flash. utils.*;

public class Main extends Sprite { private var loader:Loader;

public function Main( ) { // Загружаем файл Module. swf loader = new Loader( );

1oader. contentLoaderlnfo. addEventLi stener(Event. INIT,

initListener);

1oader.1oad(new URLRequest(«Module. swf»));

}

private function initListener (e:Event):void { // Загруженный SWF-файл был проинициализирован, поэтому регистрируем // приемник для события Module. ASSETS_READY. 1oader. content. addEventLi stener(«ASSETS_READY»,

assetsReadyListener);

private function assetsReadyListener (e:Event):void { // Объект TextField уже существует, поэтому мы можем благополучно // обратиться к нему trace(0bject(1oader. content).t. text);

}

}

}

До сих пор при рассмотрении вопросов, касающихся загрузки элементов, мы ограничивались автоматически создаваемым объектом элемента, на который ссылается переменная loader, content. Теперь рассмотрим, как создавать новые дополнительные экземпляры загруженных элементов вручную.

Руководство по actionscript. часть 6, стр. 041

Создание экземпляра элемента, загружаемого на этапе выполнения

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

Создание экземпляра загруженного SWF-файла

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

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

? получить ссылку на класс с помощью метода экземпляра get Definition ( ) класса ApplicationDomain.

Рассмотрим оба подхода на примерах, снова обратившись к сценарию «приложение Main. swf загружает приложение Module. swf» из предыдущих разделов.

Предположим, что мы хотим создать новый экземпляр приложения Module. swf в приложении Main. swf. Сначала мы сделаем так, чтобы класс Module был непосредственно доступен для приложения Main. swf, используя методику путей исходных файлов, методику путей библиотек или методику путей внешних библиотек, которые были рассмотрены ранее. Повторяя изученный материал, напомним, что как только класс Module станет доступен для приложения Main. swf, мы сможем ссылаться на него напрямую, как показано в операции приведения, взятой из кода приемника события Event. INIT, представленного в листинге 28.9:

private function initListener (e:Event):void { traceC’init»);

Module(e. target. content).start( ); // Прямая ссылка на класс Module

}

Точно так же, чтобы создать новый экземпляр класса Module, мы просто используем оператор new:

private function initListener (e:Event):void { var moduleObj:Module = newModule( );

}

Теперь предположим, что на этапе компиляции приложение Main, swf не имеет доступа к классу Module, но мы по-прежнему хотим создать новый экземпляр приложения Module. swf в приложении Ma in. swf. В подобной ситуации мы должны получить ссылку на класс Module, используя метод экземпляра getDefini t ion ( ) класса ApplicationDomain. Когда в данный метод передается имя класса, он возвращает ссылку на указанный класс. Возвращенную ссылку можно присвоить переменной типа Class для использования в последующих операциях создания экземпляров. Следующий код демонстрирует общую методику:

var SomeClass:Class = иекийАрр^ cati onDomai п. де^е^лт^опГИмяИекоегоКласса»): var obj:Object = new SomeClass( );

Здесь некийАрр! icationDomain — ссылка на объект ApplicationDomain SWF-файла, а имяНекоегоКласса — полностью уточненное строковое имя получаемого класса. Таким образом, чтобы получить ссылку на класс Module из приложения Main. swf, необходимо следующее:

? ссылка на объект ApplicationDomain приложения Module. swf;

? полностью уточненное имя класса Module.

Руководство по actionscript. часть 6, стр. 042

К объекту ApplicationDomain SWF-файла можно обратиться через его объект Loaderlnfo, который доступен через переменную loaderlnfo любого экземпляра класса DisplayObject данного SWF-файла. Полностью уточненное имя для основного класса SWF-файла можно получить с помощью метода flash. utils. getQualifiedClassName ( ). Как только приложение Module. swf будет загружено, внутри приемника события Event. INIT в приложении Main. swf мы можем использовать следующий код для получения ссылки на основной класс приложения Module. swf:

var ModuleClassName:String = getQualifiedClassName(e. target. content); var appDomain:ApplicationDomain =

e. target. content.1oaderInfо. appli cati onDomai n: // После выполнения следующей строки кода переменная ModuleClass будет // ссылаться на основной класс приложения Module. swf var ModuleCl ass:Class = appDomain. getDefinition(ModuleClassName);

Получив ссылку на класс Module, мы можем использовать ее для создания новых объектов:

var newModule:Object = new ModuleClass( );

I Как всегда, обязательно дождитесь завершения процесса инициализации загружаемого SWF-м?; d „ файла перед тем, как обратиться к нему. Метод getDefinition() должен применяться только fffi после того, как среда выполнения Flash осуществит диспетчеризацию события Event. INIT.

Обратите внимание, что в предыдущем коде типом данных переменной newModule является Ob j ect, а не Module, поскольку в данном примере приложение Main. swf не имеет непосредственного доступа к основному классу приложения Module. swf. Таким образом, для любых последующих обращений к методам и переменным класса Module через переменную newModule типы не будут проверяться вплоть до этапа выполнения. Если проверка типов требуется на этапе компиляции, вместо метода getDefinition ( ) используйте методики путей исходных файлов, путей библиотек или путей внешних библиотек.

Стоит отметить, что методики, рассмотренные в этом разделе, можно применять не только для создания нового экземпляра SWI^-файла, но и для создания экземпляра любого символа из этого SWF-файла. Предположим, что мы хотим создать экземпляр символа с именем Ball из приложения Module. swf. Для этого нам придется экспортировать символ Ball для кода на языке ActionScript, а затем выполнить одно из следующих действий:

? получить ссылку на экспортированный класс Ball, используя метод экземпляра getDefinition ( ) класса ApplicationDomain;

? сделать так, чтобы класс Ball был непосредственно доступен для приложения Main. swf, используя методику путей исходных файлов, путей библиотек или путей внешних библиотек.

Руководство по actionscript. часть 6, стр. 043

Создание экземпляра загруженного изображения

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

Как мы уже знаем, после завершения загрузки файла изображения загруженные пиксельные данные автоматически помещаются в объект BitmapData. Чтобы создать копию пиксельных данных загруженного изображения, мы вызываем метод BitmapData. clone ( ) над этим объектом BitmapData. Данная методика продемонстрирована в следующем коде. Этот код создает копию данных загруженного изображения и передает созданную копию данных в конструктор нового объекта Bitmap. Новый объект Bitmap будет являться копией загруженного элемента растрового изображения. Обращаться к загруженному элементу, как обычно, можно только после возникновения события Event. INIT.

private function initListener (e:Event):void { // Переменная e. target. content ссылается на объект элемента. // представляющего загруженное растровое изображение var newlmage:Bitmap = new Bitmap(e. target. content. bitmapData. clone( )):

// Переменная newlmage теперь содержит копию загруженного // растрового изображения

Использование сокетов для загрузки отображаемых элементов на этапе выполнения

В начале этой главы мы узнали, что язык ActionScript предоставляет два различных механизма для добавления внешнего отображаемого элемента в приложение на этапе выполнения, а именно классы:

? flash. display. Loader;

? flash. net. Socket, применяемый совместно с методом loadBytes ( ) класса Loader.

Теперь, когда мы освоили применение класса Loader, рассмотрим, как он может быть использован совместно с классом Socket для получения отображаемых элементов непосредственно через сокет TCP/IP. Методика, описываемая в данном разделе, может применяться для загрузки элементов в приложении, в котором широко используются сокеты, например в многопользовательской игре, или просто для того, чтобы предотвратить появление загруженного элемента в кэше конечного пользователя.

Руководство по actionscript. часть 6, стр. 044

Общий процесс получения отображаемых элементов непосредственно через сокет TCP/IP заключается в следующем.

1. Подключиться к серверу, который может передавать среде выполнения Flash файлы GIF, PNG, JPEG или SWF в бинарном формате.

2. Получить байты для желаемого элемента.

3. Преобразовать загруженные байты в объект элемента, пригодный для отображения на экране.

Для выполнения первых двух шагов мы используем класс flash. net. Socket языка ActionScript. Взаимодействие класса Socket с сервером осуществляется посредством формата бинарных данных (необработанных байтов). Для выполнения последнего шага мы используем метод экземпляра loadBytes ( ) класса Loader. Метод loadBytes ( ) преобразует необработанные байты в отображаемый объект языка ActionScript.

Описанный процесс подробно рассматривается в следующих разделах.

Серверная часть: отправка элемента

С помощью класса Socket мы можем получать байты для отображаемого элемента с любого сервера, который знает, как отправлять файлы GIF, PNG, JPEG или SWF в бинарном формате. Например, класс Socket может быть использован для получения изображений с большинства почтовых, новостных и чат-серверов — они все обычно поддерживают передачу изображений в бинарном формате.

Вместо того чтобы изучать процесс загрузки элемента с сервера существующего типа (например, почтового, новостного или чат-сервера), рассмотрим более законченный

сценарий, в котором мы разработаем не только клиента, функционирующего в среде выполнения Flash и получающего элемент, но и сервер, отправляющий данный элемент. Мы назовем наш собственный сервер именем FileSender и напишем его на языке Java. Поведение сервера FileSender чрезвычайно простое: при подключении нового клиента сервер автоматически отправляет этому клиенту один файл, затем передает ASCII-символ 4 (завершение передачи) и закрывает соединение.



Полезные ссылки
Случайные записи
  • 29.07.2010">Начало начал
  • 23.01.2011">Руководство по actionscript. часть 1, стр. 081
  • 07.03.2011">Руководство по actionscript. часть 4, стр. 114
  • 04.03.2011">Руководство по actionscript. часть 5, стр. 048
  • 03.06.2010">Самоучитель по креативному веб-дизайну. Книга 3, стр.49
  • 22.01.2011">Руководство по actionscript. часть 1, стр. 128
  • 23.01.2011">Руководство по actionscript. часть 1, стр. 060
  • 14.03.2011">Руководство по actionscript. часть 3, стр. 084
  • 27.02.2011">Руководство по actionscript. часть 6, стр. 031
  • 02.06.2010">Самоучитель по креативному веб-дизайну. Книга 3, стр.119
  • 23.02.2011">Руководство по actionscript. часть 7, стр. 036
  • 02.03.2011">Руководство по actionscript. часть 5, стр. 087
  • 15.03.2011">Руководство по actionscript. часть 3, стр. 055
  • 24.02.2011">Руководство по actionscript. часть 7, стр. 013
  • 23.02.2011">Руководство по actionscript. часть 7, стр. 040
Опрос

Какие цвета вы предпочитаете?

View Results

Loading ... Loading ...