Этот swf файл не содержит код actionscript
Стиль
Принципы присвоения имен
Имена функций и переменных должны начинаться со строчной буквы (a, b, c, . x, y, z). Имена объектов и конструкторов объектов должны начинаться с заглавной буквы (A, B, C, . X, Y, Z). Использование смешанных регистров символов рекомендуется в случае именования переменных. Другие форматы именования приемлемы, если они используются последовательно во всем проекте. Имя переменной может содержать только буквы, числа и символы подчеркивания. Не начинайте имя переменной с числа или символа подчеркивания. Неправильными именами переменных будут следующие:
- _count = 5; // начинается с символа подчеркивания
- 5count = 0; // начинается с числа
- foo/bar = true; // содержит символ "слэш"
- foo bar = false; // содержит пробел
Кроме того, в качестве имен переменных нельзя использовать ключевые слова ActionScript. Также избегайте использования в качестве имен переменных слов из популярных конструкций программирования, даже если Macromedia Flash Player к настоящему времени не поддерживает эти конструкции в качестве ключевых слов. Это дает больше уверенности в том, что будущие версии проигрывателя не вступят в конфликт с вашим приложением. Например, не нужно делать так:
- var = "foo";
- MovieClip = "myMovieClip";
- switch = "on";
- case = false;
- abstract = "bar";
- extends = true;
- implements = 5;
Редактор кода ActionScript в среде разработки Flash MX имеет встроенную функцию "завершения кода". Эта функция помогает вам писать код, предоставляя в виде выпадающего списка возможные варианты завершения кода. Чтобы вы могли пользоваться этим преимуществом, имена ваших переменных должны соответствовать определенному формату. В этом встроенном формате суффикс имени переменной является строкой, указывающей на тип переменной. Ниже приведена таблица поддерживаемых суффиксов:
Таблица 3: Суффиксы для активации функции завершения кода
Рисунок 1: Пример действия помощника завершения кода.
Помните, что вышеуказанные рекомендации являются общими принципами. Важнее всего, выбрав определенную схему именования, использовать ее последовательно во всем приложении или проекте.
Комментирование кода
Когда вы пишете "обходной" код для решения специфических, нестандартных задач вашего приложения, добавьте комментарий, из которого другие разработчики поймут, в чем заключалась сложность, и как вы ее обошли. Это облегчает понимание специфических проблем теми разработчиками, которые еще могут с ними столкнуться. Это просто облегчает им жизнь.
Вот пример простого комментария для переменной:
var clicks = 0; // переменная для подсчета нажатий кнопки
Блочные комментарии полезны для больших кусков текста:
/*
Инициализирует переменную clicks , хранящую количество нажатий кнопки.
*/
Ниже приведены некоторые общие методы для указания особо важных комментариев (в скобках предложены русскоязычные аналоги):
// :TODO: topic (// :СДЕЛАТЬ: тема)
Указывает, что код нужно доделать или сделать что-то еще.
// :BUG: [bugid] topic (// :ОШИБКА: [номер ошибки] тема)
Показывает известную ошибку ("глюк", "баг"). Комментарий также должен объяснять, в чем состоит проблема, и содержать " bug ID " (номер "бага"), если необходимо.
// :KLUDGE: (// :ВОЗМОЖЕН ДРУГОЙ ВАРИАНТ:)
Показывает, что соответствующий код не является элегантным или лучшим решением. Этот комментарий оповещает других, что в будущем код следует усовершенствовать.
Уведомляет разработчиков, что код со многим взаимосвязан (его изменение повлечет изменения в других местах). Это совет разработчику: "подумай, прежде чем что-то изменять".
Пример
/*
:TODO: msw 654321: проблемы с отображением больших объемов данных из БД. Наверное, следует разбивать данные на более мелкие порции для каждого запроса.
*/
Формат временной диаграммы (таймлайна)
Избегайте использования названий слоев, принятых по умолчанию ( Layer 1 , Layer 2 , и т.п.), так как это может привести к путанице. Слои таймлайна должны называться интуитивно понятным образом. Слои также должны быть сгруппированы вместе путем использования папок там, где это имеет смысл. Например, следует располагать все слои с кодом ActionScript на самом верху стека слоев, чтобы в таймлайне можно было легко найти весь код.
Область видимости
Flash Player 6 поддерживает концепцию "цепочки областей видимости" (как определено в стандарте ). Таким образом, устранены значительные недостатки "прямой области видимости" в .
Цепочка областей видимости для типичного сценария ActionScript:
- Объект Global ;
- Объект MovieClip ;
- Локальные переменные.
Конструкция with временно добавляет объект в конец цепочки областей видимости. Когда действие with прекращается, объект удаляется из цепочки областей видимости.
При определении функции текущая цепочка областей видимости копируется и хранится в объекте функции. При вызове функции происходит переключение текущей цепочки областей видимости на цепочку областей видимости объекта функции, а в конец цепочки добавляется новый объект Local Variables.
В Flash 5 область видимости функции всегда была следующей:
- Объект Global ;
- мувиклип, содержащий функцию;
- Локальные переменные.
Список областей видимости никогда не содержал более трех пунктов, кроме случая с использованием with . Это было отклонением от стандарта , и область видимости метода всегда находилась в мувиклипе, содержащем метод, а не в месте определения этого метода.
В Macromedia Flash Player 6 при определении метода мувиклипа вне самого мувиклипа цепочка областей видимости метода будет содержать внешний объект, а не объект мувиклипа, для которого определяется метод. В таком случае в теле определяемого метода необходимо использовать ключевое слово this , чтобы используемые в этом методе идентификаторы ссылались на объект мувиклипа, а не на внешний объект.
Имейте в виду, что поддерживается обратная совместимость с Flash Player 5. Для среды разработки Flash 5 применимы те же правила использования области видимости, что и для .
Используйте относительные пути для задания области видимости
Область видимости должна быть задана для каждой переменной. Исключением являются параметры функций и локальные переменные. Область видимости переменных должна задаваться относительно их текущего положения, если это возможно. Использование _root для задания области видимости переменной не рекомендуется, поскольку это ограничивает мобильность кода. Вместо _root используйте ключевое слово _parent или this , например:
this.myVar.blah = 100; // определяйте область видимости для переменных, используя относительную адресацию, как в этой строке
_root.myMovieClip.myVar.blah = 100; // НЕ задавайте область видимости переменных, используя абсолютные ссылки, как в этой строке
Если все же приходится использовать абсолютную адресацию к главному таймлайну, вместо использования _root создайте переменную-ссылку на главный таймлайн. Это позволит изменять всего один параметр, если структура таймлайна изменится. Чтобы создать удобную ссылку на основной таймлайн клипа, добавьте такую строку кода к основному таймлайну:
_global.myAppMain = this; // (замените "myApp" названием вашего приложения)
После вставки этой строки в ваше приложение, используйте _global.myAppMain.someFunction , чтобы ссылаться на функции главного таймлайна. Это позволяет изменять структуру приложения, не нарушая область видимости вызовов функций и переменных в клипе.
_root против _global
Важно понимать разницу между _global и _root . Ссылка _root уникальна только в рамках каждого загруженного .swf-клипа. Ссылка _global применима ко всем клипам в пределах проигрывателя. В общем случае для ссылок лучше использовать _global , а не _root .
Соглашения ActionScript
Держите весь код в одном месте
Когда в первом кадре расположен большой код, разделите его на части комментариями, чтобы повысить читабельность, например:
/*** Раздел функций для кнопок ***/
/*** Константы и переменные ***/
Одно исключение при размещении всего кода в первом кадре возникает в случае предварительной загрузки клипов. В приложении с предзагрузкой клипов размещение всего кода в первом кадре может быть невозможным. Но все равно нужно стремиться к централизации кода.
Помните, что функции и объекты, созданные программными методами ActionScript, существуют на протяжении всего клипа. Вместе с этим продолжает действовать механизм создания и уничтожения мувиклипов, базирующийся на состояниях временной диаграммы. Временная диаграмма должна отражать эту взаимосвязь.
Рисунок 2: Пример временной диаграммы ("таймлайна") с предзагрузчиком.
Любой определенный вами объект или библиотека созданных вами функций должны определяться во внешнем ActionScript файле и использоваться в качестве файла включаемого (include) файла. Например, если приложение использует объекты с именами "Foo" и "Bar", каждый из этих объектов должен содержаться в отдельном включаемом ActionScript-файле. Имя включаемого файла должно соответствовать имени объекта, например:
Библиотеки многократно используемых функций должны также определяться во включаемых файлах ActionScript. В этом случае имя включаемого файла должно состоять из букв нижнего и верхнего регистра (начинаясь с буквы нижнего регистра), например:
Такая система использования включаемых файлов делает объектно-ориентированный код ActionScript более легким для идентификации. Но более важно то, что код становится модульным, позволяя разработчикам создавать ActionScript-библиотеки объектов и функций. Только необходимый для приложения код включается из библиотеки внешних файлов.
Кроме того, используя внешние файлы ActionScript, разработчики могут интегрировать файлы кода с системой управления версиями, например, такими, CVS или SourceSafe. Это облегчает отслеживание исходного кода.
Кадры как состояния приложения
Разработчики часто пишут построчный код (программу) прямо на отдельных кадрах, чтобы определять состояния приложения. Такая практика нежелательна.
Правильная организация кода базируется на описании состояний приложения в ключевых кадрах. Поместите в функцию любое действие, необходимое для конкретного состояния, а затем вызывайте эту функцию как единственное действие в соответствующем ключевом кадре.
Продолжая организацию приложения, создайте в клипе два слоя с кодом. В первом кадре первого слоя, существующего по всей длине клипа, располагается самая большая часть кода. Второй слой содержит действия, необходимые ключевым кадрам для изменения состояний приложения. Единственный код в каждом ключевом кадре второго слоя должен быть вызовом функции для конкретного состояния (вызываемая функция должна быть описана в первом кадре первого слоя). Для создания некоторых состояний (например, для вызовов диалоговых окон) допускается использование мувиклипов, присоединенных с помощью действия attachMovie во время выполнения приложения.
Избегайте размещения кода на мувиклипах и кнопках
Не размещайте код на мувиклипах и кнопках, если в этом нет крайней необходимости. Если код все же должен быть размещен на мувиклипе или кнопке, используйте при этом минимальное количество кода. С этой точки зрения лучше всего вызывать функции, как в следующем примере:
myButton.onMouseDown = function() _parent.doMouseDown(this);
>
Использование вызова функции переносит всю функциональность на основной таймлайн мувиклипа.
Инициализация
// кадр 1
this.init();
function init() if (this.inited != undefined)
return;
this.inited = true;
// здесь идет код инициализации.
>
Используйте ключевое слово var для локальных переменных
Все локальные переменные должны использовать ключевое слово var . Это предохраняет переменные от глобального доступа и, что более важно, предохраняет переменные от неумышленного переназначения [3] . Например, следующий код функции не использует ключевое слово var при объявлении переменной, что приводит к (неумышленной) перезаписи внешней переменной, не относящейся к функции:
function loopTest()
trace(counter);
for(counter = 0; counter < 5; counter++)
trace(counter);
>
>
trace(counter);
loopTest();
trace(counter);
Этот код выводит:
В данном случае переменная counter , находящаяся на основной временной диаграмме, переназначается переменной counter , которая находится внутри функции. Ниже приведен исправленный код, который использует ключевое слово var , для объявления обеих переменных. Использование декларации var в функции устраняет ошибку вышеуказанного кода:
function loopTest()
trace(counter);
for(var counter = 0; counter < 5; counter++)
trace(counter);
>
>
trace(counter);
loopTest();
trace(counter);
Исправленный код выводит следующее:
Из последней строки видно, что не принадлежащая функции переменная counter сохранила свое значение после вызова функции.
Создание объектов
Пример лучшей практики создания объекта:
MyObject.prototype.name = "";
MyObject.prototype.setName = function(name)
this.name = name;
>
MyObject.prototype.getName = function()
return this.name;
>
Следующий пример демонстрирует неправильный метод создания объекта:
MyObject = function()
this.name = "";
this.setName = function(name)
this.name = name;
>
this.getName = function()
return this.name;
>
>
В первом примере каждый экземпляр объекта MyObject указывает на одни те же функции и свойства, определенные в прототипе объекта. При этом в оперативной памяти находится только одна копия getName() , независимо от количества созданных объектов MyObject .
Во втором примере каждый созданный экземпляр MyObject создает копию каждого свойства и функции. Эти дополнительные свойства и функции занимают дополнительную память, и в большинстве случаев не предоставляют при этом никаких преимуществ.
Наследование объектов
ChildClass.prototype = new ParentClass();
Пример этой практики:
function Shape()
>
function Rectangle()
>
Rectangle.prototype = new Shape();
Следующая практика НЕ рекомендуется:
Если разработчики беспокоятся, что такая форма наследования приведет к тому, что весь конструктор будет признан необязательным, следующий код поможет предотвратить это:
_global.SuperClassConstructor = function() if (this._name!=undefined) // код конструктора размещается здесь
>
>
В вышеприведенном примере код конструктора не будет выполнен, потому что еще не определен экземпляр. Заметьте, что этот код работает только в классах, основанных на классе MovieClip.
Производительность
Предварительная загрузка
Типы данных и их размеры в файлах .swf
Следующая информация может использоваться для оптимизации времени загрузки критических частей приложения.
Таблица 2: Основные объекты ActionScript
Таблица 3: Простые .swf-файлы
Таблица 4: Объекты компонентов (по одному экземпляру)
Предосторожности использования оперативной памяти
Текст. Каждый отдельный текстовый объект использует 10 КБ памяти. Это относится к динамическим текстовым полям, полям для ввода текста и статическим текстовым полям, использующим шрифты устройств ("device fonts"), например, "_sans".
Мувиклип. Каждый мувиклип использует около 1 КБ памяти. Это число может стремительно возрастать при увеличении количества используемых мувиклипов. Имейте в виду, что графические символы (graphic) не обладают такими высокими требованиями к памяти, как мувиклипы.
Вывод
Этот документ не является завершенным набором лучших методов создания кода. Macromedia продолжает расширение документа, основываясь на информации от людей, создающих и продвигающих критически важные по своему значению приложения для Flash Player. Этот документ живой, он управляется сообществом разработчиков, как это всегда было с ActionScript и Macromedia Flash Player с самого начала их существования.
В приложение на языке ActionScript 3.0 можно загрузить любые внешние активы для показа:
SWF-файл, разработанный в ActionScript 3.0 — этот файл может относиться к классу Sprite, MovieClip или любому классу, являющемуся расширением Sprite. В приложениях AIR в ОС iOS можно загружать только SWF-файлы, не содержащие байт-код ActionScript. Это означает, что можно загрузить SWF-файлы, содержащие внедренные данные, такие как изображения и звук, но нельзя загрузить SWF-файлы, содержащие исполняемый код.
Файл изображения — файлы в форматах JPG, PNG и GIF.
Файл AVM1 SWF — это SWF-файл, созданный на языке ActionScript 1.0 или 2.0. (не поддерживается в приложениях AIR для мобильных устройств)
Загрузка этих активов производится с помощью класса Loader.
Загрузка экранных объектов
Объекты Loader используются для загрузки SWF-файлов и файлов графики в приложение. Класс Loader — это подкласс класса DisplayObjectContainer. Объект Loader может содержать в своем списке отображения только один дочерний экранный объект, который представляет собой загружаемый SWF-файл или файл графики. При добавлении объекта Loader в список отображения (как в следующем коде) в него после завершения загрузки добавляется также загруженный дочерний экранный объект:
После загрузки SWF-файла или изображения можно переместить загруженный экранный объект в другой контейнер экранного объекта (например, в данном примере это container DisplayObjectContainer):
Просмотр хода загрузки
После начала загрузки файла создается объект LoaderInfo. Объект LoaderInfo предоставляет информацию о процессе загрузки, URL-адресах загружающего объекта и загружаемого содержимого, общем количестве байтов для носителя, а также номинальной высоте и ширине содержимого. Объект LoaderInfo также отправляет события, позволяющие следить за ходом загрузки.
На следующей диаграмме показаны различные применения объекта LoaderInfo (как экземпляр основного класса SWF-файла, как объект Loader и как объект, загруженный объектом Loader):
Объект LoaderInfo можно вызвать как свойство одновременно объекта Loader и загруженного экранного объекта. Как только начнется загрузка, объект LoaderInfo можно вызвать с помощью свойства contentLoaderInfo объекта Loader. По завершении загрузки экранного объекта объект LoaderInfo можно также вызвать в качестве свойства загруженного экранного объекта с помощью свойства loaderInfo экранного объекта. Свойство loaderInfo загруженного экранного объекта относится к тому же объекту LoaderInfo, что и свойство contentLoaderInfo объекта Loader. Другими словами, объект LoaderInfo совместно используется загруженным объектом и загрузившим его объектом Loader.
Чтобы вызвать свойства загруженного содержимого, необходимо добавить прослушиватель событий в объект LoaderInfo так, как это сделано в следующем коде:
Дополнительные сведения см. в разделе «Обработка событий».
Указание контекста загрузки
При загрузке внешнего файла в Flash Player или AIR с помощью метода load() или loadBytes() класса Loader можно при желании указать параметр context . Этот параметр является объектом LoaderContext.
Класс LoaderContext включает три свойства, которые позволяют определить контекст применения загруженного содержимого.
checkPolicyFile : используйте это свойство только при загрузке файла изображения (а не SWF-файла). Если этому свойству задано значение true , объект Loader проверяет наличие файла политики на исходном сервере (см. раздел Элементы управления веб-сайта (файлы политики)). Это необходимо выполнить только для содержимого, взятого из доменов, которые отличаются от домена SWF-файла, содержащего объект Loader. Если сервер дает разрешение на доступ к домену Loader, ActionScript из SWF-файлов в домене Loader может вызывать данные в загруженном изображении. Иными словами, можно использовать команду BitmapData.draw() для доступа к данным в загруженном изображении.
Учтите, что SWF-файл из доменов, которые отличаются от домена объекта Loader, могут вызвать Security.allowDomain() , чтобы разрешить определенный домен.
securityDomain : используйте это свойство только при загрузке SWF-файлов (но не изображений). Его следует указывать для SWF-файла из домена, который отличается от домена файла, содержащего объект Loader. Когда указывается этот параметр, Flash Player проверяет наличие файла политики. Если он существует, SWF-файлы из доменов, разрешенных файлом междоменной политики, могут применять загруженное содержимое SWF в разных сценариях. В качестве данного параметра можно указать flash.system.SecurityDomain.currentDomain .
applicationDomain : используйте это свойство только при загрузке SWF-файлов, написанных на языке ActionScript 3.0 (а не изображений или SWF-файлов, написанных на ActionScript 1.0 или 2.0). При загрузке этого файла можно указать, чтобы файл был включен в тот же домен приложений, что и объект Loader, присвоив параметру applicationDomain значение flash.system.ApplicationDomain.currentDomain . Разместив загруженный SWF-файл в том же домене приложений, можно вызывать его классы напрямую. Это может оказаться полезным, если загружается SWF-файл, содержащий встроенные мультимедийные файлы, доступ к которым может осуществляться по связанным именам классов. Дополнительные сведения см. в разделе «Работа с доменами приложений».
Вот пример проверки наличия файла политики при загрузке растрового изображения из другого домена:
Вот пример проверки наличия файла политики при загрузке SWF-файла из другого домена в целях размещения файла в той же изолированной программной среде, что и объект Loader. Кроме того, этот код добавляет классы в загруженном SWF-файле в тот же домен приложения, что и у объекта Loader:
Загрузка SWF-файлов в среде AIR для iOS
На устройствах под управлением iOS имеются ограничения на загрузку и компиляцию кода во время выполнения. Из-за этих ограничений возникают следующие сложности при загрузке внешних SWF-файлов в приложение.
Все SWF-файлы, содержащие код ActionScript, должны входить в пакет приложения. Загрузка SWF с кодом из внешнего ресурса (например, по сети) невозможна. При создании пакета приложения весь код ActionScript в SWF-файлах пакета компилируется в собственный код устройств iOS.
Загрузка, выгрузка и повторная загрузка SWF-файла невозможна. При попытке выполнить эти действия возникнет ошибка.
Поведение среды при загрузке в память и выгрузке из нее не отличается от поведения настольных платформ. После выгрузки загруженного SWF-файла все визуальные ресурсы, содержащиеся в нем, будут выгружены из памяти. Однако все ссылки на классы ActionScript из загруженного SWF-файла останутся в памяти и могут быть использованы кодом ActionScript.
Все загружаемые SWF-файлы должны быть загружены в том же домене приложения, что и основной SWF-файл. По умолчанию такого не происходит, поэтому для каждого загружаемого SWF-файла следует создавать объект LoaderContext с указанием на основной домен приложения и передавать этот объект LoaderContext при вызове метода Loader.load(). При попытке загрузить SWF-файл в домен приложения, отличный от домена приложения основного SWF-файла, возникает ошибка. Это правило также выполняется, если загружаемый SWF-файл содержит только визуальные ресурсы и не содержит кода ActionScript.
В следующем примере показан код, которым осуществляется загрузка SWF-файла из пакета приложения в домен приложения основного SWF-файла.
SWF-файл, содержащий только ресурсы без кода, может быть загружен как из пакета приложения, так и по сети. В обоих случаях этот SWF-файл так же необходимо загружать в основной домен приложения.
Если среда AIR имеет более раннюю версию, чем AIR 3.6, в процессе компиляции игнорируется весь код во всех SWF-файлах, кроме основного файла приложения. В пакет приложения для загрузки во время выполнения можно включать только SWF-Файлы, содержащие визуальные ресурсы и не содержащие код. При попытке загрузить SWF-файл, содержащий код ActionScript, возникнет ошибка. Эта ошибка приведет к появлению в приложении диалогового окна Uncompiled ActionScript (Нескомпилированный ActionScript).
См. также
Использование классов ProLoader и ProLoaderInfo
В среде Flash Professional CS5.5 представлены новые классы fl.display.ProLoader и fl.display.ProLoaderInfo, помогающие выполнить предварительную загрузку удаленной общей библиотеки (RSL). Эти классы зеркально воспроизводят классы flash.display.Loader и flash.display.LoaderInfo, но обеспечивают более последовательное взаимодействие при загрузке.
В частности, ProLoader помогает загрузить файлы SWF, использующие Text Layout Framework (TLF) с предварительной загрузкой RSL. Во время выполнения файлам SWF, предварительно загружающим другие файлы SWF или SWZ, например TLF, требуется только внутренний файл оболочки SWF. Дополнительный уровень сложности, связанный с использованием файла оболочки SWF, может привести к нежелательному поведению. ProLoader позволяет решить проблемы, связанные с загрузкой этих файлов, загружая их как обычные файлы SWF. Решение, используемое классом ProLoader, является прозрачным для пользователей и не требует специальной обработки в среде ActionScript. Помимо этого, класс ProLoader правильно загружает обычное содержимое SWF.
В среде Flash Professional CS5.5 и более поздних версий можно без последствий заменить все используемые экземпляры класса Loader классом ProLoader. Затем необходимо экспортировать программу в среду Flash Player 10.2 или более поздней версии, чтобы класс ProLoader мог получать доступ к необходимым функциям ActionScript. Класс ProLoader также можно использовать при разработке приложений для более ранних версий Flash Player, поддерживающих ActionScript 3.0. Однако полный функциональный набор класса ProLoader доступен только в среде Flash Player 10.2 или более поздних версий. Всегда используйте класс ProLoader вместе с TLF в среде Flash Professional CS5.5 или более поздних версий. Класс ProLoader не требуется в средах, отличных от Flash Professional.
Важная информация. Для файлов SWF, опубликованных во Flash Professional CS5.5 и более поздних версий, всегда можно использовать классы fl.display.ProLoader и fl.display.ProLoaderInfo вместо классов flash.display.Loader и flash.display.LoaderInfo.Проблемы, которые решает класс ProLoader
Класс ProLoader решает проблемы, обработка которых не предусмотрена существующим классом Loader. Эти проблемы возникают в связи с предварительной загрузкой RSL библиотек TLF. В частности, они относятся к файлам SWF, использующим объект Loader для загрузки других файлов SWF. В числе решаемых проблем:
Программа SWF должна активно управлять процессом загрузки. Для этого требуется реализация дополнительных событий, таких как added , removed , addedToStage и removedFromStage . Если приложение предназначено для проигрывателя Flash Player 10.2 или более поздних версий, класс ProLoader исключает необходимость выполнения дополнительной работы.
Обновление кода для использования класса ProLoader вместо класса Loader
Поскольку класс ProLoader является зеркальным повторением класса Loader, можно без труда поочередно использовать в коде эти два класса. Следующий пример демонстрирует обновление существующего кода для использования нового класса.
Этот код можно обновить для использования класса ProLoader следующим образом:
Платформа Adobe Flash является основой для разработки многофункциональных интерактивных веб-приложений, презентаций и пользовательских интерфейсов. Приложение Flash позволяет разработчикам и дизайнерам использовать графику, текст, аудио и видео.
В последние годы самые популярные браузеры пытаются избавиться от использования Flash в пользу возможностей HTML5. Например, в последних версиях Google Chrome плагин Adobe Flash Player остановлен по умолчанию и на сайтах, использующих Flash, необходимо включать его вручную. Многие популярные видео-сервисы, такие как YouTube, также отказались от использования Flash в пользу HTML5. Тем не менее, до сих пор особо популярными остаются игры на flash, где возможности HTML5 пока значительно уступают.
У Flash есть два «лица»: то которое вы видите на экране, и комплексный механизм сценариев, называемый ActionScript, который вы не видите. Являясь языком сценариев, встроенным во Flash, ActionScript позволяет создавать интерактивные решения. Любой ролик, где нужно что-то нажать, перетащить или поставить на паузу, требует использования ActionScript, который укажет Flash, что надо делать. ActionScript является основой всей интерактивности и логики, встроенной во Flash.
В выпуске Flash CS3 был представил ActionScript 3.0 - значительно усовершенствованный язык сценариев. Старые версии ActionScript медленно выполняли большие и сложные сценарии. ActionScript 3.0 изменил это. Он почти в 10 раз быстрее по сравнению с ActionScript 2.0 и обладает намного большей функциональностью.
Из этой статьи вы узнаете, почему ActionScript 3.0 — тот язык программирования, который вы захотите начать использовать, что изменилось по сравнению с более ранними версиями ActionScript, а что осталось таким же и как сделать наши приложения еще мощнее. Единственная проблема, которую вам придется решить - это выбрать, что разрабатывать в первую очередь.
Использование объектно-ориентированного программирования в ActionScript
Объекты являются ключом к пониманию объектно-ориентированного программирования (ООП). В ООП объект является столь же реальным, как и обычный объект в нашем мире. Например, собака или даже компьютер - объекты, которые существуют в реальном мире. Объекты реального мира схожи с объектами компьютерного мира по двум параметрам: у них есть определенное состояние и поведение. Например, состояние собаки можно описать такими свойствами, как ее имя, окрас, порода, и тем, голодна ли она. Поведением собаки будет лай, привлечение внимания и виляние хвостом.
Компьютерные объекты моделируются по образцу объектов реального мира в плане конкретных состояния и поведения. Класс является представлением объекта, который хранит информацию о типе его данных, состоянии и поведении. Класс может включать в себя три типа характеристик: свойства, методы и события. Свойства представляют различные данные, связанные с объектом. Методы означают действия, которые могут быть выполнены с объектом. Событие – это действие системы, приложения или пользователя (например, щелчок кнопкой мыши, который вызывает действие, связанное с объектом).
После создания класса вы можете создавать классы на основе существующего, которые называются подклассами, или расширениями класса. Подкласс наследует все свойства и методы родительского класса, который, в свою очередь, будет называться суперклассом. Например, вы можете создать суперкласс Parent и подкласс Children. Наследование позволяет одному определению класса (подклассу) включать все функции другого определения класса (суперкласса). Вы также можете создавать дополнительные методы и свойства подкласса, а также переопределять методы, унаследованные от суперкласса, что называется полиморфизмом.
Наследование и подклассы очень удобны для больших проектов, где вы можете делиться своей функциональностью и уменьшать количество кода.
Объект поддерживает свое состояние с помощью одной переменной или большего их количества. Переменная – это элемент данных, названный определенным идентификатором. Все, что объект понимает (его состояние) и может сделать (его поведение), выражается через переменные и методы внутри этого объекта.
Объект, представляющий собой движущийся автомобиль, будет иметь переменные, которые отражают его скорость, направление и цвет, как показано на рисунке ниже. Эти переменные известны, как переменные экземпляра, потому что они содержат состояния конкретного объекта, а в объектно-ориентированной терминологии конкретный объект называется экземпляром. Вдобавок к своим переменным у автомобиля будут методы, отвечающие за изменение скорости и включение фар. Эти методы называются методами экземпляра, поскольку они проверяют или изменяют состояние конкретною экземпляра.
Настройка Flash для движка AVM 2.0
- плагин, который установлен в веб-браузере для воспроизведения файлов SWF, является ключом к успеху при создании быстрых приложений. Чтобы скомпилировать, а затем запустить любой код ActionScript в роликах, Flash Player использует инструмент, называемый ActionScript Virtual Machine (виртуальная машина ActionScript) или AVM. Для ActionScript 1.0 и 2.0 Flash Player использует AVM 1.0. Flash Player 9 представил новый AVM версии 2.0, который используется для работы только с SWF-файлами ActionScript 3.0. Освоить его довольно просто.
Используя AVM 2.0. вы можете создавать приложения, которые характеризуются высокой скоростью и сложностью традиционных настольных приложений. Примерами таких приложений являются WorkFlow Lab от Adobe — инструмент, который позволяет разрабатывать составные приложения Workflow и конкурирует непосредственно с инструментом Visio от Microsoft; Adobe Story — инструмент, который позволяет создавать сценарии мультимедийной и видеопродукции, а также Kuler - сложный инструмент управления цветами. Использование данных инструментов дает такую же ответную реакцию, как и традиционные настольные приложения.
Разработка на ActionScript 3.0 решений, которые ориентированы на движок AVM 2.0, гарантирует, что вы значительно оптимизируете свою работу во Flash.
Flash Player 9 поддерживает AVM 1.0 для обратной совместимости с существующими и устаревшим содержимым. Flash Player 7 и 8 поддерживают только AVM 1.0. Однако есть несколько моментов, касающихся совместимости, о которых вы должны знать. SWF-файл не может объединить ActionScript 1.0 или 2.0 с кодом версии 3.0, при этом код может загрузить файл SWF с версиями 1.0 или 2.0, но он не может получить доступ к переменным и функциям файла (за исключением возможности использовать команду loadMovieNum() и передать параметр уровня). Если у вас есть код версий 1.0 или 2.0 и вы хотите использовать код версии 3.0, необходимо привести весь старый код к ActionScript 3.0. Если вы хотите использовать поведения, вам нужно прибегнуть к ActionScript 2.0, так для 3.0 поведения недоступны.
Виртуальные машины и JavaScript
Веб-браузеры используют виртуальные машины для запуска JavaScript, который является «двоюродным братом» ActionScript. Обе технологии построены на международном формате ECMA-262, или ECMAScript, как его часто называют. Такие браузеры, как Google Chrome, Safari, FireFox и Internet Explorer используют виртуальные машины сценариев JavaScript (JavaScript Virtual Machines - JVM) для воспроизведения содержимого.
Многие из компаний, создающих движки для браузеров, дали им яркие названия: V8 для Google Chrome, SquirrelFish для Safari и SpiderMonkey для FireFox. Но победителем в оригинальных названиях конечно можно дать Microsoft – ее творческое вдохновение ограничилось названием своей виртуальной машины JS (для JavaScript).
Конечно AVM 2.0 от Adobe здесь занимает второе место. Есть ли шанс, что Adobe все-таки присвоит AVM 3.0 какое-нибудь яркое имя?)
Использование ActionScript 3.0
По сравнению с предыдущими версиями, ActionScript 3.0 претерпел значительные изменения. Это не означает, что если вы работали с ActionScript 1.0 или 2.0, то вам придется тяжело. Просто освоение новых способов использования кода потребует времени.
Понимание ActionScript 3.0
Объектно-ориентированное программирование позволяет разбивать код на объекты, которые могут быть легко использованы повторно. С помощью ООП легче управлять приложением, которое состоит из целой коллекции файлов маленького размера, а не из одного большого файла.
Рассмотрим основные изменения, которые потребуют определенного времени на привыкание к ним:
ActionScript находится в файлах класса или на временной шкале.
Проектирование кода действительно объектно-ориентированное.
Вы не можете добавлять ActionScript непосредственно к фрагментам роликов или экземплярам кнопок.
Запуск событий претерпел изменения.
Загрузка данных изменилась.
XML управляется по-другому.
Кроме того, добавлено использование информации о типе во время выполнения, улучшено использование свойств и классов с изолированными кассами, добавлено использование метода замыкания для обработки событий, включен стандарт ECMAScript для XML, улучшена поддержка регулярных выражений и добавлены примитивные типы (например, int – целочисленный тип).
Работа с ActionScript 3.0
Есть два способа работы с ActionScript. Первый заключается в добавлении ActionScript на временную шкалу. Это знакомо давним разработчикам Flash. Рекомендуется иметь слой на этой временной шкале, посвященный только работе с ActionScript. Adobe советует пометить его как actions. Блокировка данного слоя предотвратит случайное добавление на него фрагментов ролика.
Второй метод заключается во вставке ActionScript в файлы Flash с файлом класса (Class). Файлы класса имеют долгую историю в мире разработки. С их помощью вы можете указать как публичные, так и приватные классы. Ключевое слово Private ограничивает использование атрибута, определенного только в этом классе, а не совместно с другими классами. Это полезно, когда вы разрабатываете инструкции, которые должны быть выполнены в отдельном пространстве в частном порядке.
Другие важные изменения перечислены ниже:
Разработка построения решений с моделью событий DOM 3.
Использование пространств имен в ваших проектах.
Рисование с помощью класса фигуры (Shape).
Возможность легко работать с внешними библиотеками ActionScript.
Несмотря на все изменения в ActionScript 3.0 по сравнению с 2.0, важно помнить, что есть много функциональных возможностей, одинаковых для обеих версии. Например, вы по-прежнему можете использовать тем же самым образом следующие элементы: переменные, объект Math, выражения if/else, выражения switch, строки, даты, массивы и логические значения.
Следующий код работает как в ActionScript 2.0, так и в версии 3.0:
Как видите, общая структура синтаксиса одинакова в обеих версиях ActionScript. Код завершается фигурной скобкой, имена переменных чувствительны к регистру и не могут начинаться с цифры, объекты классов используются одинаково.
Расширение ActionScript открытыми библиотеками
Основой языка ActionScript 3.0 является то, что он может быть легко расширен. Для этого можно использовать десятки больших отрытых библиотек, расширяющих функциональность Flash. Достойными примерами являются:
Box2D Physics Engine;
CoreLib – коллекция базовых утилит, таких как хеширование MD5, сериализация JSON и расширенный анализ данных;
Syndication Library – библиотека, которая позволяет легко разбирать базовые каналы ATOM и RSS;
Alive PDF – библиотека, позволяющая преобразовывать содержимое экрана с Flash в формат PDF.
Дважды в месяц мы возвращаемся к любимым постам наших читателей на протяжении всей истории Activetuts +. Этот учебник был впервые опубликован в феврале 2010 года.
В этом уроке я продемонстрирую технику, которую я использую для защиты кода и активов от кражи.
Декомпиляторы действительно волнуют людей, которые создают Flash-контент. Вы можете приложить немало усилий, чтобы создать лучшую игру, затем кто-то может украсть ее, заменить логотип и разместить его на своем сайте, не спрашивая вас. Как? Использование Flash Decompiler. Если вы не наделили свою защиту SWF-файлом, ее можно декомпилировать одним нажатием кнопки, и декомпилятор выведет читаемый исходный код.
Прежде чем мы начнем
Я использовал свой небольшой проект, чтобы продемонстрировать, насколько уязвимы SWF для декомпиляции. Вы можете скачать его и проверить себя по ссылке на источник выше. Я использовал Sothink SWF Decompiler 5, чтобы декомпилировать SWF и заглянуть под него. Код вполне читабелен, и вы можете легко понять и использовать его повторно.
Что мы можем сделать по этому поводу?
Я придумал метод защиты SWF-файлов от декомпиляторов, и я собираюсь продемонстрировать его в этом уроке. Мы должны быть в состоянии произвести это:
Декомпилированный код на самом деле является кодом для дешифрования контента и не имеет ничего общего с вашим основным кодом. Кроме того, имена являются незаконными, поэтому они не будут компилироваться. Попробуйте декомпилировать это самостоятельно .
Прежде чем мы начнем, я хочу отметить, что этот учебник не подходит для начинающих, и вы должны иметь глубокие знания AS3, если вы хотите следовать. Это руководство также о низкоуровневом программировании, которое включает байты, ByteArrays и манипулирование SWF-файлами с помощью шестнадцатеричного редактора.
Вот что нам нужно:
Шаг 1. Загрузите SWF во время выполнения
Откройте новый проект ActionScript 3.0 и установите его для компиляции с Flex SDK (я использую FlashDevelop для написания кода). Выберите SWF-файл, который вы хотите защитить, и вставьте его как двоичные данные, используя тег Embed:
Теперь SWF-файл встроен в виде ByteArray в SWF-загрузчик и может быть загружен через Loader.loadBytes () .
loader.loadBytes(new content(), new LoaderContext(false, new ApplicationDomain()));В конце концов мы должны иметь этот код:
loader.loadBytes(new content(), new LoaderContext(false, new ApplicationDomain()));Шаг 2: проанализируйте результат
Давайте попробуем декомпилировать и посмотрим, работает ли он.
Yey! Активы и оригинальный код исчезли! Теперь показан код, который загружает защищенный SWF, а не его содержимое. Это, вероятно, остановит большинство начинающих злоумышленников, которые не слишком знакомы с Flash, но все еще недостаточно хороши для защиты вашей работы от опытных злоумышленников, поскольку защищенный SWF ждет их нетронутыми внутри загрузочного SWF.
Шаг 3: Распаковка SWF
Давайте откроем загрузочный SWF с помощью шестнадцатеричного редактора:
Функция делает несколько вещей:
- Он читает несжатый заголовок (первые 8 байтов) без подписи и запоминает его.
- Он читает остальные данные и распаковывает их.
- Он записывает обратно заголовок (с подписью «FWS») и несжатые данные, создавая новый несжатый SWF.
Шаг 4: Создание утилиты
Далее мы создадим удобную утилиту во Flash для сжатия и распаковки SWF-файлов. В новом проекте AS3 скомпилируйте следующий класс как класс документа:
Как вы, наверное, заметили, я добавил 2 вещи: загрузку файлов и функцию сжатия.
Функция сжатия идентична функции распаковки, но в обратном порядке. Загрузка файла выполняется с использованием FileReference (требуется FP10), а загруженный файл является сжатым или несжатым. Обратите внимание, что вы должны запускать SWF локально из автономного проигрывателя, поскольку FileReference.browse () должен вызываться при взаимодействии с пользователем (но локальный автономный проигрыватель позволяет запускать его без него).
Шаг 5: Распаковка загрузочного SWF
Чтобы проверить инструмент, запустите его, выберите загрузочный SWF-файл и укажите, где его сохранить. Затем откройте его с помощью шестнадцатеричного редактора и пролистайте. Вы должны увидеть строки ascii внутри следующим образом:
Шаг 6: снова проанализируйте
Давайте вернемся к шагу 2. Хотя декомпилятор не показал никакой полезной информации о защищенном SWF-файле, довольно просто получить SWF-файл из несжатого загрузчика; просто найдите подпись «CWS» (если защищенный SWF-файл распакован, найдите «FWS») и посмотрите результаты:
Шаг 7: Шифрование
Шаг 8: Шифрование данных
15. Это гарантирует, что количество зашифрованных байтов может быть разделено на 16, и мы не исчерпываем данные при вызове aes.encrypt () .
Примечание. В этом случае важно понимать смысл шифрования. На самом деле это не шифрование, а запутывание, поскольку мы включаем ключ в SWF. Цель состоит в том, чтобы превратить данные в двоичный мусор, и приведенный выше код выполняет свою работу, хотя он может оставить до 15 незашифрованных байтов (что не имеет значения в нашем случае). Я не криптограф, и я совершенно уверен, что приведенный выше код может выглядеть неубедительным и слабым с точки зрения криптографа, но, как я уже сказал, он совершенно не имеет значения, поскольку мы включаем ключ в SWF.
Шаг 9: Утилита шифрования
Пришло время создать еще одну утилиту, которая поможет нам шифровать SWF-файлы. Он почти такой же, как компрессор, который мы создали ранее, поэтому я не буду много говорить об этом. Скомпилируйте его в новый проект как класс документа:
Теперь запустите его и создайте зашифрованную копию защищенного SWF-файла, сначала выбрав его, а затем сохранив под другим именем.
Шаг 10: Модификация загрузчика
Вернитесь к загрузочному SWF-проекту. Поскольку контент теперь зашифрован, нам нужно изменить загрузочный SWF и добавить в него код дешифрования. Не забудьте изменить src в теге Embed, чтобы он указывал на зашифрованный SWF.
loader.loadBytes(data, new LoaderContext(false, new ApplicationDomain()));Это то же самое, что и раньше, за исключением кода расшифровки, застрявшего в середине. Теперь скомпилируйте загрузочный SWF и проверьте, работает ли он. Если вы внимательно следили за этим, защищенный SWF-файл должен загружаться и отображаться без ошибок.
Шаг 11: Загляните внутрь, используя декомпилятор
Откройте новый загрузочный SWF-файл с помощью декомпилятора и посмотрите.
Он содержит более тысячи строк жесткого кода шифрования, и, вероятно, получить из него защищенный SWF труднее. Мы добавили еще несколько шагов, которые должен предпринять атакующий:
- Он (или она) должен найти DefineBinaryData, который содержит зашифрованный контент, и извлечь его.
- Он должен создать утилиту для его расшифровки.
Шаг 12: Обфускация строк
Сначала мы поместили защищенный SWF-файл в загрузочный SWF-файл, затем зашифровали его, и теперь мы добавим последние штрихи к загрузочному SWF-файлу. Мы переименуем классы, функции и переменные в недопустимые имена.
Вот как это выглядит перед запутыванием любой строки:
Давайте начнем! Распакуйте загрузочный SWF-файл, используя утилиту, которую мы создали ранее, и запустите шестнадцатеричный редактор.
Шаг 13: твое первое запутывание
Попробуем переименовать класс документа. Предполагая, что вы оставили оригинальное имя (Main), давайте поищем его в несжатом загрузчике SWF с помощью шестнадцатеричного редактора:
При переименовании убедитесь, что вы не переименовываете ненужные строки, иначе SWF не запустится.
Сохраните и запустите SWF. Оно работает! И посмотрите, что говорит декомпилятор:
Шаг 14: переименование остальных классов
После завершения переименования классов и пакетов вы можете начать переименовывать функции и переменные. Их даже легче переименовать, поскольку они обычно появляются только один раз в одном большом облаке. Опять же, убедитесь, что вы переименовываете только «ваши» методы, а не встроенные методы Flash. Убедитесь, что вы не стираете ключ (в нашем случае это «activetuts»).
Шаг 15: Сжать SWF
После завершения переименования вы, вероятно, захотите сжать SWF, чтобы он был меньше по размеру. Нет проблем, мы можем использовать утилиту сжатия, которую мы создали ранее, и она выполнит свою работу. Запустите утилиту, выберите SWF и сохраните его под другим именем.
Вывод: сделайте окончательный взгляд
Откройте его в последний раз и посмотрите. Классы, переменные и имена методов запутываются, а защищенный SWF-файл где-то внутри зашифрован. Сначала этот метод может быть медленным, но через несколько раз это займет всего несколько минут.
Некоторое время назад я создал автоматическую утилиту для добавления защищенного SWF-файла в загрузочный SWF-файл, и он работал нормально. Единственная проблема заключается в том, что если его можно внедрить с помощью автоматической утилиты, его можно расшифровать с помощью другой утилиты, поэтому, если злоумышленник создаст для этого утилиту, он легко получит все ваши SWF. Из-за этого я предпочитаю каждый раз защищать SWF-файлы вручную, добавляя небольшие изменения, чтобы их было сложнее автоматизировать.
Другие методы защиты
Поскольку кража SWF является большой проблемой в мире Flash, существуют и другие варианты защиты SWF. Существует множество программ для маскировки AS на уровне байт-кода (например, secureSWF от Kindisoft). Они испортили скомпилированный байт-код, и когда декомпилятор попытается вывести код, он потерпит неудачу и даже иногда будет зависать. Конечно, эта защита лучше с точки зрения безопасности, но стоит $$$, поэтому перед тем, как выбрать, как защитить свой SWF, подумайте о необходимой безопасности. Если речь идет о защите запатентованного алгоритма, который ваша студия с 50 сотрудниками разрабатывает в течение последних двух лет, вы можете подумать о чем-то лучше, чем переименовать переменные. С другой стороны, если вы хотите, чтобы дети не давали ложные высокие оценки, вы можете рассмотреть возможность использования этой техники.
Что мне нравится в этой технике, так это то, что ваш защищенный SWF-файл остается нетронутым при запуске. Обфускация AS вмешивается в байт-код, и это может повредить SWF-файл и вызвать ошибки (хотя я сам с ними не сталкивался).
На сегодня все, надеюсь, вам понравился урок и вы узнали что-то новое! Если у вас есть какие-либо вопросы, не стесняйтесь оставлять комментарии.
Читайте также: