Илья Панин написал о достоинствах и недостатках различных IDE для создания приложений под Flash Platform (это же — его презентация на UAFPUG-2; Илья — спасибо, что опубликовал!)
Соглашусь с выводами автора (в скобках указаны оценки от Google, который тоже согласен):
Илья также приводит сводную таблицу по более чем 25 показателям для каждого из рассматриваемых редакторов — отличная работа!
Денис Коляко в ruFlash представил две полезные ссылки, не пропустите:
1) Alexis' SWF Reference (SWF версий 1-9)
2) ActionScript Virtual Machine 2 (AVM2) Overview
После этих материалов саму официальную спецификацию SWF / FLV 9 можно считать скорее дополнением к ним...
Сегодня я получил письмо такого содержания:
"Я студентка, и в связи с написанием курсовой работы у меня возникли некоторые затруднения.. Суть курсовой в том, что мне надо написать программку на С++, которая способна из *.swf файла вытащить звук и сохранить его в *.mp3 формате.. Я заглянула на ваш сайт http://flash-ripper.com/ ..нашла там много полезной информации, но мне стало интересно.. не могли бы вы мне помочь разобраться в структуре *.swf файла?" Наталья
Наталья
Кто поможет девушке разобраться в структуре *.swf файла?
так же, как и я до сих пор побаиваюсь их свободного применения в своих проектах, то вот добрые боги завели песочницу для игры с регулярными выражениями.
Песочница получилась славная. Во-первых, она уже содержит стартовое регулярное выражение в первом текстовом поле. Это выражение можно сразу редактировать и на лету получать результат обработки этим выражением строки из второго текстового поля. Этот результат отображается в третьем текстовом поле. Пока выражение правильное, фон второго поля остается зеленым. Если в регулярном выражении обнаружена ошибка (то есть оно ничего не возвращает в результате обработки исходной строки из второго поля) -- фон становится красным, из монитора высовывается рука пожарного и обливает неумелого регулятора холодной водой из брандспойта всеобщего осуждения.
Подсмотреть синтаксис регулярных выражений Flex 2 можно здесь.
Регулярные выражения -- это средство компактной и быстрой обработки строк. Турбонаддув для любого умеющего работать с ними языка. Жить можно и без них, так разве это жизнь?
Update: Constantine в комментариях подкинул еще одну хорошую ссылку на освоитель регулярных выражений: www.regexbuddy.com
А еще что я вам скажу: в Eclipse, так там вообще есть мгновенная подсказка по регуляркам прямо в диалоге Find/Replace [Ctrl+F]: обратите внимание на иконку лампочки, появляющуюся рядом с текстовым полем после простановки галочки "Regular Expression".
Майк Лида провел тесты производительности Actionscript в разных версиях проигрывателя сравнении с Javascript. Результаты интересные. Так, Flash Player 8.5 немного проигрывает в некоторых специфических случаях (например, в сортировке массива), но с просто огромным отрывом делает всех в misc тесте (этот тест надо понимать как смешение нескольких видов функциональности в одном скрипте, так?) Там же есть исходники чтобы скачать и проверить.
Antares (в миру -- Майкл Клишин, инициатор перевода документации к Flash 8 на русский язык и разработчик системы автоматизации отслеживания прогресса этого перевода) опубликовал статью про ActionSctipt3.0, которая так и называется: Обзор ActionScript 3.0 (мой вольный перевод). Радует фраза в самом начале статьи Майка: "[Водопад обещаний в первом абзаце умышленно вырезан.]"
Пытаясь не отстать от Майкла, Flashguru публикует статью под названием Actionscript 3 - New Capabilities", где перечислены некоторые нововведения.
Любой, программирующий более, чем на одном языке (а кто -- нет?) знает, что перенос кода из хорошо изученного языка в менее знакомый может превратиться в пытку. Чтобы ускорить этот мучительный процесс, Хэлен Триоло (Helen Triolo), в разделе "Запчасти" своего сайта actionscript-toolbox.com создала таблицу соответствия между ActionScript (1.0) и PHP (4) кодом: перенос кода из Flash в PHP или из PHP во Flash, as<->php. Таблица включает примеры преобразований типов, строковые функции, операции над массивами, математические действия и кое-что еще. Таким образом, зная один из этих языков, можно писать на другом с меньшими потерями времени. Смотреть здесь: перенос кода из PHP во Flash, PHP2AS
Конечно, искушенным в каждом из языков таблица flash2php покажется несовершенной, но начинающим в любом из них лучше все же использовать ее, чем таблетки от головной боли (:
При создании форм, содержащих поля для ввода адреса электронной почты, практически всегда возникает задача проверки email-адреса на валидность. Вот простая (дописано позже: не окончательная) функция, проверяющая, на своем ли месте находятся символы "@" ("собака") и "." (точка, отделяющая домен первого уровня от остальной части адреса):
function checkEmail(strEmail:String):Boolean{ return strEmail.indexOf("@")>0 && strEmail.indexOf(".")>2 && strEmail.length-strEmail.indexOf(".")>2; }
Хорошая новость, а точнее, даже несколько. В последнее обновление для среды разработки Flash MX 2004 вошел новый класс mx.utils.Delegate. Его назначение -- избавить разработчиков от еще одной старой головной боли, связанной с обработкой событий. Это была старая проблема с областью видимости: вызывая функцию-обработчик события компонента (или, например, XML-объекта, или мувиклипа), мы автоматически попадаем в область видимости этого компонента (XML-объекта, мувиклипа и т.д.), а это означает, что ключевое слово this внутри такой функции будет указывать на вызвавший событие компонент (XML-объект, мувиклип..), а не на класс или мувиклип, которому принадлежит функция-обработчик. Но чаще всего внутри функции-обработчика нам нужна как раз область видимости содержащего ее класса или мувиклипа, а не вызвавшего событие компонента (XML-объекта, мувиклипа и т.д.)!
mx.utils.Delegate
this
Как раз для решения это проблемы и предназначен класс mx.utils.Delegate. Изначально, класс Delegate был выпущен компанией Macromedia с целью прямой передачи событий компонентов в использующие их классы (раньше это приходилось делать с помощью всевозможных ухищрений по передаче событий.) Но, как мы сейчас увидим, этот полезный класс можно с успехом использовать и для обработки любых других, самых обычных событий.
Delegate
Итак, первичная задача класса Delegate -- передать событие от компонента к использующему его объекту; вот синтаксис, изначально предлагаемый Macromedia (случай с компонентом):
import mx.utils.Delegate; имяЭкземпляра.addEventListener("названиеСобытия", Delegate.create(областьВидимости, функция));
(См.: Оригинальная статья на LiveDocs по делегированию событий компонентов.)
Прекрасная возможность! Но, оказывается, с помощью класса Delegate можно делегировать не только события компонентов, но и любые, самые привычные и простые события, например, такие, как события кнопок или объекта XML. В качестве практического примера рассмотрим распространенную ситуацию: мы загружаем некий XML и хотим, что по окончании его загрузки была вызвана функция-обработчик, из которой мы могли бы получить прямой доступ к классу или мувиклипу, содержащему эту функцию.
В этом случае мы можем использовать следующий, еще более простой синтаксис:
import mx.utils.Delegate; xmlData.onLoad=Delegate.create(this, processXML);
processXML
// Это некоторый класс, использующий загружаемый XML, код содержитя в файле "SomeClassThatUsesLoadedXML.as": import mx.utils.Delegate; class SomeClassThatUsesLoadedXML{ // with Delegate class private var inited:Boolean=false; private var xmlData:XML; function SomeClassThatUsesLoadedXML(){ if(!inited){ init(); } } private function init(){ xmlData=new XML(); xmlData.onLoad=Delegate.create(this,processXML); inited=true; } private function processXML():Void{ trace("Событие onLoad вызвано на объекте: "+this + "\nXML данные: "+ xmlData); } public function loadXML(urlPath:String):Void{ xmlData.load(urlPath); } public function toString(){ return "[SomeClassThatUsesLoadedXML]"; } } //Пример использования, код в fla-файле: var experimental:SomeClassThatUsesLoadedXML=new SomeClassThatUsesLoadedXML(); experimental.loadXML("content/xml/data.xml");
import mx.utils.Delegate;
class SomeClassThatUsesLoadedXML{ // with Delegate class
private var inited:Boolean=false; private var xmlData:XML; function SomeClassThatUsesLoadedXML(){ if(!inited){ init(); } } private function init(){ xmlData=new XML(); xmlData.onLoad=Delegate.create(this,processXML); inited=true; } private function processXML():Void{ trace("Событие onLoad вызвано на объекте: "+this + "\nXML данные: "+ xmlData); } public function loadXML(urlPath:String):Void{ xmlData.load(urlPath); } public function toString(){ return "[SomeClassThatUsesLoadedXML]"; } }
//Пример использования, код в fla-файле: var experimental:SomeClassThatUsesLoadedXML=new SomeClassThatUsesLoadedXML(); experimental.loadXML("content/xml/data.xml");
// Вывод в окне Output: Событие onLoad вызвано на объекте: [SomeClassThatUsesLoadedXML] XML данные: Item 1
Разве это не хорошо? Спасибо ребятам из Macromedia! //Обратите внимание: класс mx.utils.Delegate можно использовать как в AS1, так и в AS2, в любом предпочитаемом вами стиле кодирования.
С появлением все более и более сложных Флэш-проектов возрастает и количество подгружаемых в них XML-данных, что влечет за собой целесообразность оптимизации процесса загрузки XML.
Mattias Strindsman (более известный как Strille) изобрел, как ускорить загрузку XML за счет сокращения его размера (сжатия) в несколько раз. Очевидцы первых сжатий утверждают, что XML-файл размером в 225Кб был сжат до 16Кб, а затем успешно загружен и правильно обработан во Flash-приложении.
По порядку:
AS1-Код парсера:
XML.prototype.parseXMLStandard = XML.prototype.parseXML; XML.prototype.parseXML = function(i) { if (i.charAt(0) != '<') { var ecPos = i.indexOf(" ")+1; var eC = i.charAt(ecPos); i = i.substr(ecPos+1); var o = ""; var iL = i.length; for (var n=0;n<iL;n++) { if (i.charAt(n) == eC) { var p = i.charCodeAt(n+1)*114 + i.charCodeAt(n+2) - 1610; var l = i.charCodeAt(n+3)-14; o += o.substr(-p, l); n += 3; } else { o += i.charAt(n); } } this.parseXMLStandard(o); } else { this.parseXMLStandard(i); } }
На сайте автора выложена программа для сжатия XML -- Flash XML Compressor (Zip, 14 Кб). Для ее работы нужна установленная Microsoft .Net Framework.
Чтобы сжать XML-файл, просто перетащите его на иконку или окно приложения Flash XML Compressor. Не забудьте заглянуть в опции программы и на домашнюю страницу Flash XML Compressor
// via Strille Tutorials
Andre Michelle разработал класс для изометрического искажения изображений. Класс разбивает мувиклип на несколько треугольников, а затем искажает каждый из них в свободной трансформации.
Качать: DistortImage Class by Andre Michelle.
В конференции ruFlash появилось интересное сообщение от Fix aka Serg Pilguy:
"Когда я прочитал, что в Flash 7 оптимизирован и быстреее работает скрипт, я думал, что это реализовано на уровне плеера, который просто быстрее воспроизводит скрипт.
Однако что я прочитал..
"Whether you use ActionScript 1.0 or ActionScript 2.0, the performance of ActionScript is now blazingly fast. The compiler in Flash now performs enhanced optimizations to all ActionScript code that is compiled. These compiler optimizations greatly enhance the byte code that is generated from ActionScript. Variable-lookup function calls have all been greatly optimized. This results in impressive performance boosts for all ActionScript code, even if you are still writing your applications using ActionScript 1.0. In fact, just by republishing existing applications in Flash MX 2004 (even those that still use Flash Player 6), you can realize significant performance gains. The new ActionScript compiler alone justifies the upgrade to Flash MX 2004!"
Если я правильно понял, оптимизирован на самом деле компилятор в среде разработки, выдающий в итоге более качественный swf. То есть, чтобы ускорить работу старых приложений, нужно их перекомпилировать в FMX2004. Какие соображения?"
// via Fix|ruFlash
В конференции ruFlash сегодня обсуждался вопрос точного программного рисования прямоугольников с контурами произвольной толщины. В результате решения данной задачи появилась следующая функция (если нужна -- берите):
function drawRectangle(x, y, w, h, mc, c, a, lw, lc, la){ mc.lineStyle(lw, lc, la); l=Math.max(lw,1)/2; mc.beginFill(c, a); mc.moveTo(x+l, y+l); mc.lineTo(x+w-l, y+l); mc.lineTo(x+w-l, y+h-l); mc.lineTo(x+l, y+h-l); mc.lineTo(x+l, y+l); mc.endFill(); } drawRectangle(0, 0, 300, 300, _root, 0xFF8900, 100, 0, 0x000000, 100); // hairline drawRectangle(300, 0, 100, 100, _root, 0xFF8900, 100, 1, 0x000000, 100); // тонкий контур drawRectangle(300, 100, 30, 30, _root, 0xFF8900, 100, 10, 0x000000, 100); // толстый контур
Для получения эффективного результата достаточно вставить вышеприведенный код в первый кадр вашего Флэш-приложения.
И -- успеха вам, дорогие мои =)
Darron Schall показывает, как вызвать событие onEnterFrame, не создавая для этого мувиклип. Техника основана на использовании встроенного класса Flash MX 2004 mx.transitions.OnEnterFrameBeacon. Там же -- Пример использования класса OnEnterFrameBeacon для вызова события onEnterFrame.
mx.transitions.OnEnterFrameBeacon
OnEnterFrameBeacon
onEnterFrame
Ниже коротко перечислим известные нам способы прослушивания событий на примере обработки события "клик по кнопке cmpButton". Если вы хотите проверять приводимый код по ходу действия, разместите на рабочем поле компонент "Button" (из набора компонентов второй версии, т.е. тех, что поставляются вместе с Flash MX 2004 Professional) и присвойте ему имя cmpButton.
cmpButton
var objListener:Object = new Object(); objListener.click = function(evtObj:Object){ trace(this) // [object Object], т.к. this здесь ссылается на объект objListener }; cmpButton.addEventListener("click", objListener);
Этот способ является предпочтительным с точки зрения хорошей практики программирования, так как приводит к минимальной путанице при создании многих обработчиков многих событий.
function fncListener(eventObj){ trace(this) // _level0.cmpButton - т.к. this здесь ссылается на компонент cmpButton } cmpButton.addEventListener("click", fncListener);
.handleEvent
.handleEvent -- встроенный метод, имеющийся по умолчанию у каждого объекта. Он вызывается каждый раз, когда объект получает оповещение о событии (а для этого его надо подписать на события, используя синтаксис типа component.addEventListener("event", objListener); где objListener -- наш объект-листенер). Не забудьте добавить на рабочее поле экземпляр компонента TextInput и присвоить ему имя cmpTextInput:
component.addEventListener("event", objListener);
objListener
TextInput
cmpTextInput
objListener=new Object(); objListener.handleEvent = function(o){ if (o.type == "click"){ trace(this) // [object Object], this сылается на объект objListener trace("кнопка кликнута"); // клик пришел от кнопки } else if (o.type == "change"){ trace("текст изменен") // в поле ввода изменился текст } } cmpButton.addEventListener("click", objListener); cmpTextInput.addEventListener("change", objListener);
Кажущаяся простота этого способа может привести к путанице при прослушивании многих событий (исходный код будет менее наглядным).
Здесь используется особенность модели событий компонентов второй версии: при возникновении какого-либо события всегда вызывается метод, имя которого состоит из имени события и суффикса "Handler" (в нашем примере это событие "click"):
Handler
click
cmpButton.clickHandler = function(o){ trace(this); // _level0.cmpButton, this ссылается на компонент cmpButton }
(Человек без подписи добавляет в комметариях: "...этот способ - довольно стрёмный. Иногда назначенные обработчики не выполняются. Так что лучше его не пользовать -- легче жить будет...")
Этот способ рекомендуется использовать только в процессе разработки, когда нужно быстро создать обработчик какого-либо события.
Выделить компонент cmpButton, и прямо на нем написать:
on(click){ trace(this); // _level0.cmpButton }
В подавляющем большинстве случаев первого способа достаточно, однако, зная остальные, вы можете сами выбирать лучший способ для конкретных обстоятельств.
Полная документация по формату SWF7 недавно была выложена на сайте Macromedia и в данный момент доступна для скачивания. В данной документации можно увидеть много общего с предыдущей версией, для формата SWF6. В то же время, полторы страницы посвящены перечню нововведений (главными из которых можно назвать расширения ActionScript, поддержку нового формата видео, управление выполнением ActionScript (оказывается, теперь можно задать максимально допустимое время вычислений и т.п.), рендеринг текстов с низким значением кегля). Документ пригодится тем, кто хочет знать "как все происходит на самом деле". Спецификация файлов формата SWF7
hOk, о котором мы уже неоднократно упоминали, написал код автозаполнения текстовых полей. Вот рабочий пример автозаполнения, а вот исходные файлы.
Приятно отметить, что hOk снова активизировал свою "журнальную" деятельность :)
Речь идет о новых ключевых словах try, catch и finally, появившихся в языке ActionScript 2.0. Применение try и catch довольно очевидно; вы "пытаетесь" (try) выполнить часть кода, и если в процессе его выполнения возникнут ошибки, вы можете "поймать" (catch) их соответствующим блоком catch, (в противном случае код продолжает нормально выполняться дальше). Не столь очевидно применение finally:
try
catch
finally
function myFunction () : Boolean { try { doSomething(); } catch (e:MyError) { doSomethingSafe(); } finally { return true; } }
return true
Автор: Joey Lott [http://www.person13.com/]
В первых двух частях [часть 1 | часть 2] мы рассматривали структуру и синтаксис классов в ActionScript 2.0. Мы узнали, как создавать классы в ActionScript 2.0, включая использование пакетов, членов класса с разными режимами доступа (public/private/static), а также геттеров и сеттеров. Теперь поговорим о наследовании (inheritance) и интерфейсах (interfaces).
public/private/static
Наследование связано с иерархичностью классов. Можно определить подкласс и суперкласс. Подкласс автоматически наследует всех членов суперкласса без необходимости их явного повторного определения. Это важное и полезное свойство классов, поскольку позволяет использовать высокий уровень абстракции. А высокий уровень абстракции ведет к высокой эффективности рабочего процесса, и чем сложнее проект, тем это заметнее.
Например, вы хотите создать класс Car, подобный тому, что мы создавали в предыдущих частях статьи. Ясно, что Автомобиль — это один из многих типов Машины, помимо Автомобилей существуют Вертолеты, Дрезины, Джипы, Терминаторы и т.д. Хотя Машины и отличаются друг от друга, у них есть много общего. Все вышеперечисленные машины могут иметь такие свойства, как "грузоподъемность" или "пробег" (для Самолетов — "пролет"). А если Машина еще и передвигается в пространстве, у нее есть методы для перемещения с заданной скоростью.
Car
Так вот, если вы создадите суперкласс Vehicle (т. е. "Машина"), то можно в него поместить все общие для машин характеристики (свойства и методы). При этом код будет написан только в одном месте, а использовать его можно будет во многих местах: во всех подклассах класса Машины. Для создания суперкласса не нужно быть чемпионом по программированию среди домохозяек (или домохозяинов). Просто берете и создаете суперкласс, как раньше создавали обычные классы. А вот чтобы наследовать от этого класса (иными словами, расширить его), потребуются новая техника. Довольно легкая в освоении.
Vehicle
В терминах ООП можно сказать, что подкласс расширяет (extends) суперкласс. В нашем примере подкласс Car расширяет суперкласс Vehicle. Чтобы Flash создал такую связь между ними, нужно при объявлении подкласса использовать ключевое слово extends:
extends
В случае с Автомобилем и Машиной получится приблизительно следующее:
Вы всего один раз говорите, что класс Car расширяет класс Vehicle, и получаете при этом в свое распоряжение все свойства и методы класса Vehicle, как будто бы они были определены в классе Car.
Часто возникает ситуация, когда в подклассе необходимо унаследовать метод суперкласса без каких-либо изменений в этом методе. В таких случаях в определением подкласса просто не нужно ничего делать с этими методами. Но во многих других случаях метод суперкласса может быть перекрыт — для реализации в данном методе особенностей подкласса. Это называется перекрытием (overriding) метода суперкласса, поскольку при этом подкласс определяет в себе собственную реализацию метода, которая перекрывает унаследованную, родительскую.
Перекрывать методы суперкласса можно по-разному:
Чтобы полностью перекрыть родительский метод, просто определите в классе-потомке метод с точно таким же именем, как и у родительского метода. Например, если у суперкласса есть метод типа:
Потом можно определить реализацию метода в подклассе, которая перекроет реализацию этого метода в суперклассе:
Это был первый подход.
Если же вы хотите реализовать в подклассе метод, который будет вызывать также свою реализацию в суперклассе, можете использовать ключевое слово super, чтобы ссылаться на суперкласс и явно вызывать его метод из метода подкласса. Например, пример с методом display() в таком случае можно переписать следующим образом:
super
display()
Затем, если из экземпляра подкласса вызвать метод display() подкласса, в панели Output увидим следующее:
Ссылку super можно использовать в любом месте подкласса. Например, вызов super() будет ссылаться на метод конструктора суперкласса. Это пригодится, если вы хотите, чтобы конструктор подкласса выполнял некоторые действия, уникальные для подкласса, но в то же время вы хотите вызывать конструктор суперкласса, передавая ему некие конкретные значения. Единственное предостережение: конструктор суперкласса должен всегда вызываться в первой строке конструктора подкласса, если вы вызываете его явно. В противном случае получите ошибку компиляции.
super()
Конец теории. Выполним упражнение. Создадим суперкласс Vehicle (Машина) и подкласс Car (Автомобиль). Если вы сделали упражнение из второй части данной статьи, то вам будет легко следить за мыслью.
Niva
Kukuruzniq
Plane
Интерфейсы — это просто. Это набор правил, в соответствии с которыми реализуется некий набор классов. Когда вы определяете класс, который следует правилам интерфейса, то говорят, что класс реализует (иногда на жаргоне говорят — "имплементит", от англ. "implements") интерфейс.
Какие правила определяются в интерфейсе? Интерфейс в ActionScript 2.0 сообщает Flash, какие методы должны реализоваться в классе, включая следующую информацию:
private
static
В интерфейсе недопустимы:
Затем можно реализовывать интерфейс в классе. При этом, кроме всего прочего, в классе должны реализовываться методы, объявленные в интерфейсе. В противном случае на этапе компиляции Flash выдаст сообщение об ошибке.
Не все разработчики схватывают на лету плюсы интерфейсов. На первый взгляд кажется, что это только лишняя неблагодарная работа. Ведь в самом интерфейсе нет функциональности, потому что в нем нет реализаций объявляемых в нем же методов.
Реальное величие интерфейсов видится с некоторого расстояния. если вы создаете один класс для одного приложения, то интерфейсы вам и не нужны. И не все классы обязаны реализовать интерфейс. Но если вы работаете в команде, а проект не маленький — тут интерфейсы приходят на выручку, помогая создавать основные вехи проекта, что повышает эффективность процесса не только на этапе разработки иерархии классов приложения, но также и на этапе применения этих классов.
Например, вы работаете в команде, которая создает классы Vehicle (Машина), Animal (Животное), Wind (Ветер) и Planet (Планета). В то время как у каждого из этих классов может быть собственный API, между ними есть и общее — все они способны двигаться. Если вы хотите реализовать движение в каждом из этих классов, можно создать интерфейс IMoveable, который будет реализовываться всеми этими классами. Интерфейс IMoveable будет содержать объявление метода move(), так что теперь каждый конкретный человек, работающий над реализацией конкретного класса, будет учитывать этот факт в процессе разработки и реализует метод move() в разрабатываемом им классе. Это большой плюс при командной работе. Когда вы создаете интерфейс и определяете, какие классы будут его реализовать, то потом все разработчики, работающие над классом, будут заранее знать, какие методы писать, и это облегчает стандартизацию API всех классов. Еще одно преимущество получает разработчик, использующий такой класс. Зная, какой именно конкретный интерфейс реализуется в классе, вы ужен знаете много о своем API.
Animal
Wind
Planet
IMoveable
move()
Один класс может реализовывать многочисленные интерфейсы. Поэтому интерфейсы часто используются как форма множественного наследования в языках, изначально не поддерживающих такой вид наследования. В ActionScript подкласс может наследовать только от одного суперкласса. Например, класс Car расширяет класс Vehicle, и следовательно не может расширять ни один другой класс. Но Car может реализовывать множественные интерфейсы (продолжая при этом наследовать от класса Vehicle.) Например, Car может реализовать интерфейсы типа IDrivable (автомобиль можно водить), IManufacturable (можно производить), ISellable (можно продать).
IDrivable
IManufacturable
ISellable
Рассмотрим пример объявления и определения интерфейса. Вы уже знаете синтаксис и структуру классов, так что нового здесь будет совсем немного.
Декларация (объявление) интерфейса выглядят почти идентично декларации класса. Единственное различие в том, что при объявлении интерфейса используется ключевое слово interface, вместо ключевого слова class. Например:
interface
class
В интерфейсе можно только объявлять методы, но не реализовывать их. Реализовываться методы будут в классах, реализующих интерфейс. В интерфейсе нельзя также объявлять свойства. Еще раз кратко перечислим то, что может и должно содержаться в интерфейсе:
Вот пример готового интерфейса IMoveable:
Как и классы, интерфейсы удобно хранить в пакетах. Например, можно упаковать IMoveable в пакет com.person13. В декларации интерфейса это выглядит вот так:
И также, как и классы, интерфейсы могут расширять друг друга Например, IDrivable может расширять IMoveable, вот как будет при этом выглядеть код:
После определения интерфейса можно указать, что некий класс реализует этот интерфейс. Для этого используется ключевое слово implements, за которым будет следовать список разделенных запятыми реализуемых интерфейсов. Например, если класс Vehicle реализует интерфейс IMoveable, то начало объявления класса будет выглядеть так:
implements
Конечно, при этом можно пользоваться импортом (как и с классами):
А вот класс Car реализует интерфейсы IDrivable, IManufacturable, и ISellable:
Когда класс реализует интерфейс, Flash будет проверять правильность этой реализации во время компиляции. И если какой-то метод пропущен или объявлен неверно, не так, как в интерфейсе, то Flash выдаст сообщение об ошибке.
Вот и разобрались. Комментарии приветствуются как никогда. Спасибо :]
1) Часто вместо "перекрытие" говорят "переопределение". Пусть это вас не смущает!
2) Не забывайте, что иногда вместо "реализовать" говорят "имплементить".
Статья "Введение в ActionScript 2.0 для пользователей ActionScript 1.0: Часть Третья" ("Наследование и интерфейсы") находится в процессе перевода и на днях будет выложена на сайте Ф. Потрошителя.
А пока предлагаем вам насладиться красотой. Вот цитата (по материалам конференции "ruFlash"):
"я это еще нигде не публиковал... только сегодня приснилось: Народ постоянно парится по поводу перевода XML в массивы и прочая. - Нифига это не нужно. Достаточно добавить две строчки кода и на тебе, обращайся к узлам XML как к элементам массива!!!
Народ постоянно парится по поводу перевода XML в массивы и прочая. - Нифига это не нужно. Достаточно добавить две строчки кода и на тебе, обращайся к узлам XML как к элементам массива!!!
- последняя версия находится здесь: http://proto.layer51.com/d.aspx?f=1075
— Ivan Dembicki
Как и обещали, в этой части поговорим о формальном синтаксисе классов в ActionScript 2.0 (сокращенно — AS2). Сразу заметим, что для правильного усвоения этой статьи вы должны быть уже знакомы с объектно-ориентированным программированием. Для этого можно почитать ООП от Робина Дебройла (на русском) или вот это на английском:
http://www.oreillynet.com/pub/a/javascript/2003/08/12/actionscriptckbk.html http://www.oreillynet.com/pub/a/javascript/2003/08/19/actionscriptckbk.html
(Если вы можете отличить конструктор от метода, читать это необязательно).
Начнем с освещения ключевых моментов нового синтаксиса и структуры, затем рассмотрим все это поближе.
import
public
Если не все здесь вам знакомо, — не волнуйтесь, продолжайте читать. Далее по тексту все объясняется и приводятся примеры (желательно иметь под рукой Flash MX 2004 или Flash MX Professional 2004.) (Скачать триал).
Если вы не работали с языками типа Java или C#, то хранение каждого класса в его собственном файле вам пока незнакомо. Особенно, если вы работали только с ActionScript 1.0, в котором могли определять многочисленные классы в пределах единственного файла. Пофайловое хранение классов имеет свои плюсы. Главный — лучшая организация, из которой следует удобство хранения и распространения. Если пихать классы куда попало, хаос наступит быстро. Ясно, что при работе с 2-3 классами такой проблемы нет. Но ActionScript 2.0 вводит новую парадигму для ActionScript. Разработчики могут создавать и распространять библиотеки классов, содержащие неборы базовых функций. Просто чтобы колесо не изобреталось по нескольку раз в день в разных точках мира, а чтобы образовывалиь все более сложные механизмы из экземпляров одного хорошо продуманного колеса. Macromedia подает пример: посмотрите стандартные классы в каталоге First Run/Classes (и его подкаталогах) в той директории, где у вас установлена Flash MX 2004.
Итак, в отличие от классов ActionScript 1.0, все классы ActionScript 2.0 должны быть сохранены во внешних .as-файлах. Более того, имя файла должно совпадать с именем класса. Например, класс Car должен храниться в файле Car.as.
Файлы классов можно хранить в пакетах (packages). Если вы не знакомы с пакетами (в мире .NET их называют простраствами имен (namespaces) то знайте, что это очень просто и удобно. Пакеты — это способ организации классов. Здесь есть два аспекта. Во-первых, в определении класса нужно указывать его пакет (об том будет подробнее). Во-вторых, .as-файл должен быть сохранен в соответствующей директории. Например, если пакет для класса — com.person13, то .as-файл для этого класса должен быть сохранен в директории com/person13.
Работа с пакетами тоже имеет преимущества. Наиболее очевидное: пакеты есть способ быстрой организации ваших файлов класса. Примеры найдете в классах, поставляемых вместе с Flash MX 2004 (в каталоге First Run/Classes). Вы увидите, что многие классы для UI-компонентов организованы в пределах пакета mx.controls и, следовательно, сохранены в директории mx/controls. Второе преимущество пакетов: они помогают избегать конфликтов имен. Вы не можете иметь два класса с одним и тем же именем в одном и том же пакете хотя бы той по очевидной причине, что путь к файлу класса должен быть уникальным. Так что если бы пакетов не было, вы бы столкнулись с такой проблемой очень быстро. Конечно, если вы сами пишете все классы, то вы можете дать каждому классу уникальное имя. Но когда вы загружаете и устанавливаете классы других разработчиков, ситуация может выйти из под контроля. А вот когда классы хранятся в пакетах, все становится на стои места. Например, класс Car в пакете com.person13 и класс Car в пакете com.ejepo никогда не подвергнутся опасности конфликта имен.
com.person13
com.ejepo
По умолчанию Flash ищет файлы классов в директории First Run/Classes. Если не находит там, то ищет дальше в директории вашего исходного fla-файла или документа ActionScript. Classpath — это список директорий, в которых Flash ищет файлы класса. Вы можете указать дополнительные директории для classpath или изменить порядок поиска файлов классов по директориям. Выберите меню Edit>Preferences, затем жмите закладку "ActionScript". Потом жмите "ActionScript 2.0 Settings". В открывшемся диалоге используйте кнопку с плюсом, чтобы добавить директорию и т.д. (Надеюсь, дочитавшим до этого места не нужно разжевывать назначение давно знакомых элементов интерфейса — прим перев.)
Рис. 1: определение списка classpath
На рис. 1 все хорошо видно. Мы добавили свою директорию D:\Swf\Classes. На то есть причины:
Класс состоит из членов — свойств и методов. Доступ к членам класса может происходить в разных режимах (публично или приватно). Если вы не использовали некоторые изощренные или недокументированные возможности ActionScript 1.0, то все члены классов ActionScript 1.0 были публичными (public). Когда мы говорим, что член является публичным, это означает, что он доступен извне определения класса. Например, если вы создаете класс Car, а у него — свойство make, доступное из экземпляра класса Car, тогда это свойство является публичным. Но часто вы не хотите, чтобы свойства и методы класса были публично доступны. Класс может иметь свойства и переменные, которые используются только непосредственно внутри него. В таких случаях, вы можете объявить, что член будет приватным (private).
make
Примечание: приватный член класса в ActionScript 2.0 ведется себя подобно защищенному (prtotected) члену в языках типа Java или C#.
Для того, чтобы объявить член класса как публичный или приватный, используйте ключевые слова public и private соответственно. Например, следующий код объявляет приватное свойство:
private var _nInterval:Number;
Мы рассмотрим объявление публичных и приватных членов далее в этом разделе. На примерах все станет намного понятнее (мы создадим собственный класс).
Примечание: Если не указан режим доступа (публичный или приватный), то считается, что член публичный.
Статические члены класса доступны непосредственно из класса, а не из его экземпляров. Это не новое понятие из ActionScript 2.0. Фактически, начиная с Flash 5, появились встроенные классы со статическими членами. Например, класс Math полностью состоит из статических членов. Доступ к свойствам и методам производится непосредственно из класса, без создания экземпляра. Например:
Math
cos()
Упрощенно, класс состоит из таких частей:
Используйте ключевое слово class и следующее за ним имя класса. Затем следует определение класса, заключенное в фигурные скобки. Например:
Если вы включаете класс в пакет, то при объявлении нужно включить имя пакета в имя класса. При вызове класса нужно использовать его полное имя, с включенным в него именем пакета. Например, если класс Car содержится в пакете com.person13, то объявление класса должно быть таким:
И, конечно, при помещении класса в пакет нужно сохранять файл в соответствующем каталоге. В случае с com.person13.Car файл класса Car.as должен быть в каталоге com/person13, (а директория com размещена там, куда указывает classpath. (Например, если ваш classpath включает D:\Swf\Classes, то вы можете сохранить файл класса в D:\Swf\Classes\com\person13\Car.as.)
com.person13.Car
Все объявления свойств должны содержаться внутри фигурных скобок определения класса. Все объявления свойств должны находиться вне объявлений методов. По общему соглашению, объявление свойств производится в начале определения класса. Например:
class com.person13.Car {
private var _sMake:String; private var _sModel:String; private var _nYear:Number; private var _nMiles:Number; private var _nInterval:Number;
// Остальные определения класса.
}
После объявления свойств класса нужно объявить конструктор. На самом деле, если вы не объявите конструктор явно, Flash сама создаст пустой конструктор. Но даже если ваш конструктор ничего не делает, все равно желательно объявлять его явно. Помните, что конструктор является специальным методом, его имя совпадает с именем класса. Конструктор используется при создании экземпляров. Конструктор должен быть объявлен как обычная функции, и даже если он принимает параметры, он не должен возвращать никакой величины. Вот пример класса Car с конструктором:
function Car(sMake, sModel, nYear, nMiles) {
_sMake = sMake; _sModel = sModel; _nYear = nYear; _nMiles = nMiles;
В отличие от некоторых других языков, в ActionScript 2.0 конструкторы не перегружаются.
Затем можно объявить методы вашего класса. Объявление методов подобно объявлениям стандартных функций. Используется ключевое слово function и тот же синтаксис. Помните, что метод является функцией, но связан классом. Но поскольку вы объявляете эту функцию в пределах класса, Flash понимает, что ее нужно связать с классом. Единственное различие между стандартными функциями и методами — это то, что вы можете объявить методы как публичные, приватные или статические. Вот пример того же самого класса Car с двумя методами — публичным и приватным:
function
public function drive(nMPH:Number):Void {
if(nMPH == null || nMPH == 0) {
clearInterval(_nInterval);
} else {
_nInterval = setInterval(this, "increment", 1000, nMPH);
private function increment(nMPH:Number):Void {
_nMiles += nMPH;
Геттеры и сеттеры являются специальными методами, которые доступны за пределами класса как свойства, но определены в пределах класса как методы. К их преимуществам относится то, что эти методы позволяют создавать такие члены класса, которые работают как внешние свойства класса, но могут при этом иметь достаточно сложную внутреннюю логику. На примере класса Car: нам может потребоваться проверка валидности года выпуска авто, так как первый автомобиль появился в 1886 (значит, дата выпуска не может быть меньше 1886) и пробега (он не может быть меньше нуля). Дополнительные преимущества использования геттеров и сеттеров:
_nMiles
miles
Геттер-метод никогда не принимает параметров и всегда возвращает некое значение. Синтаксис геттер-метода:
// Определение метода, включая выражение return.
Геттер-метод может, как и другие методы, обладать разными режимами доступа, для чего применяются те же ключевые слова public, private или static. Вот пример простого геттер-метода, который возвращает значение внутреннего свойства класса _nMiles как доступное снаружи класса свойство miles.
public function get miles():Number {
return _nMiles;
Синтаксис для сеттер-метода очень похож на синтаксис для геттер-метода за исключением того, что он всегда принимает параметр, никогда не возвращает значения и использует ключевое слово set вместо get. Вот базовый синтаксис:
set
get
function set внешнееИмяСвойства(имяПараметра:типДанных):Void {
// Определение метода.
И так же, как и в случае с геттер-методом, вы можете использовать модификаторы public, private и static, устанавливающие соответствующий режим доступа с сеттеру. Вот пример сеттер-метода, который связывает новое значение с приватным свойством _nMiles. Заметьте, что он проверяет значение на валидность (должно больше или рано нулю). Если это не так, используется значение по умолчанию 0.
public function set miles(nMiles:Number):Void {
if(nMiles >= 0) {
_nMiles = nMiles;
else {
_nMiles = 0;
Когда вы помещаете классы в пакеты, нужно в ссылках на этот класс всегда использовать полное имя класса. Это означает, что если вы создали класс com.person13.Car, то для создание экземпляров этого класса конструктор должен быть написан следующим образом:
Хотя можно создать и ярлык для класса. Можно использовать выражение import, чтобы сообщить Flash, о каких пакетах и классах он должен "знать", чтобы вам не приходилось каждый раз включать имя пакета в имя класса. После этого Flash будет автоматически добавлять имя пакета, а вы о нем можете не тревожиться. Вот простой пример с импортом класса Car и созданием его экземпляра:
Такой код читается легче. А если вам приходится часто использовать имя класса, то экономится время, которое вы проводите с клавиатурой.
При импорте классов из пакета можно использовать символ звездочки (*). Например, следующий код импортирует все классы из пакета com.person13:
*
Конец теории, практикуем создание собственного класса. Начнем с создания класса Car:
Затем объявим пять приватных свойств. Первые четыре довольно очевидны, а последнее свойство используется для хранения ID интервала вызова метода, который будет определен далее в методах.
Затем объявим конструктор. Он будет принимать четыре параметра и присваивать их значения соответствующим свойствам. Обратите внимание, что в двух случаях мы ссылаемся на свойства, которые мы не объявляли, так как они будут добавлены с помощью сеттер-методов. Мы импользуем этот механизм, чтобы включить сюда некоторую логику проверки свойств на валидность
_sMake = sMake; _sModel = sModel; year = nYear; miles = nMiles;
drive()
increment()
if(nMPH == null || nMPH <= 0) {
// Если nMPH = null или меньше/равно 0 // то останавливаем автомобиль // путем очистки интервала clearInterval(_nInterval);
// В противном случае // устанавливаем интервал, раз в секунду // вызывающий приватный метод increment() _nInterval = setInterval(this, "increment", 1000, nMPH);
// Каждый раз при вызове методв обновляем значение _nMiles, // прибавляя к нему nMPH. _nMiles += nMPH;
Осталось задать геттер/сеттер методы:
public function get make():String {
return _sMake;
public function get model():String {
return _sModel;
public function get year():Number {
return _nYear;
public function set year(nYear:Number):Void {
if(nYear >= 1886) {
_nYear = nYear;
_nYear = 1886;
// Функция отображения длины проделанного пути в милях объекта Car function displayMileage(carObj:Car):Void {
trace(carObj.miles);
// Создаем объект Car var car:Car = new Car("Oldsmobile", "Alero", 2000, 43000);
// Начинаем ехать со скоростью 65 миль в час car.drive(65);
// Устанавливаем интервал для периодического показа пройденного пути setInterval(displayMileage, 100, car);
Вы увидите результат в панели Output.
Мы рассмотрели основы работы с классами в ActionScript 2.0. На самом деле это еще не все: мы пока не затрагивали расширение классов (extending) и реализацию интерфейсов классов (interfaces). Эти темы будут рассмотрены в третьей части этой статьи, и так уже слишком длинной. Спасибо за вдумчивое чтение и в добрый путь по флэш-океану :-]
Автор: Joey Lott (www.person13.com)
Если вы привыкли работать с Flash ActionScript, появление ActionScript 2.0 может хорошо вас встряхнуть). Конечно, есть некоторое возбуждение от новых возможностей, появившихся в ActionScript 2.0. В конце концов, 2.0 должно быть лучше, чем 1.0, так? С другой стороны, перспектива изучения нового синтаксиса и новых особенностей языка может несколько охладить пыл первооткрывателя ) В этой статье мы будем рассеивать страхи по поводу ActionScript 2.0.
Начнем с терминологии. ActionScript, на котором вы писали до этого во Flash 5 и Flash MX, теперь называется ActionScript 1.0.
ActionScript 2.0 — это новшество, появившееся в Flash MX 2004 и Flash MX Professional 2004, и по большей части это все тот же ActionScript 1.0. Это означает, что подавляющая часть ваших знаний в ActionScript 1.0 остается актуальной для ActionScript 2.0 (вздохи облегчения). Фактически, если Вы не писали свои классы в ActionScript, разница между ActionScript 1.0 и ActionScript 2.0 будет для вас довольно незначительной. Если вы фанат ActionScript 1.0, вы можете продолжать писать код на ActionScript 1.0. (Поймите, тем не менее, что смешивание ActionScript 1.0 с ActionScript 2.0 может дать нестабильный результат).
MovieClip
String
Color
Number
Если вы дочитали до этого места: сейчас мы рассмотрим все вышеперечисленное более подробно. Сначала — строгий контроль типов и контроль возвращаемого функцией результата. Затем — формальный синтаксис классов (во второй части).
Конечно, на таком простом примере ясно, что переменная должна иметь значения только одного типа. Переменная sProduct всегда должна содержать строки типа "Flash MX 2004" или "Dreamweaver MX 2004", но не число 6. Но если ваше приложение достаточно сложно, вы захотите полностью положиться на переменную, чтобы она всегда возвращала ожидаемый вами результат и сама проверяла тип своего значения при присваиваниях, ведь обращение к этой переменной может происходить в самых разных ситуациях, и вы не сможете (да и зачем это нужно) держать в своей голове их все. Например, если вы хотите отобразить значение sProduct, важно чтобы ее значение имело именно тип String, а не какой-либо другой. В этом есть определенный смысл!
sProduct
"Flash MX 2004"
"Dreamweaver MX 2004"
6
Использование ActionScript 1.0 ведет к не самой лучшей практике программирования и к ошибкам, связанным с несоответствием типов данных. Вы тратили многие часы на отладку, просто чтобы найти строку кода, где переменной присваивалось значение неверного типа. Строгий контроль типов в ActionScript 2.0 производится во время компиляции (compile-time) (то есть до этапа выполнения). А значит, если вы случайно попытаетесь присвоить переменной значение неверного типа, то при проверке синтаксиса (она производится автоматически при публикации/экспорте), Flash выдаст сообщение об ошибке, указывая вам, где именно в коде произошел конфликт типов. Чтобы объявить переменную со строгим контролем типа, нужно использовать ключевое слово var, после которого следует имя переменной, затем — двоеточие и тип данных. Имена всех типов данных начинаются с заглавной буквы. Вот пример, где объявляется переменная sProduct типа String:
var
После того, как sProduct была объявлена как String, попытка присвоить ей числовое значение приведет к ошибке. Например, если вы попробуете сделать так:
То в окне Output увидите:
**Error** Scene=Scene 1, layer=Layer 1, frame=1:Line 2: Type mismatch in assignment statement: found Number where String is required. sProduct = 6;
Total ActionScript Errors: 1 Reported Errors: 1
Важно: Используйте ключевое слово var только при первом объявлении переменной. Если попытаетесь затем использовать его еще раз с этой же переменной, Flash подумает, что вы объявляете новую переменную. И будет создана новая переменная с тем же самым именем, а оригинал будет перезаписан ею. Например:
Flash создаст новую переменную с именем sProduct. Новая переменная не будет проходить строгий контроль типов. А контроль типов для оригинальной переменной не будет проходить для новой переменной, так что вы даже не получите никакого сообщения об ошибке. Будьте внимательны с этим.
При использовании строгого контроля типов (далее — "контроль типов") вы получаете в помощники еще одну разновидность подсказок по коду (code hints) — это список возможных типов данных, он появляется после того, как вы введете двоеточие. Рис. 1 показывает это.
Рис. 1: подсказки кода при строгом контроле типов
Их как минимум два:
Во Flash MX подсказки по коду были очень удобны, но нужно было всегда использовать правильные суффиксы, чтобы их получать. А с контролем типов в Flash MX 2004 вы можете получать эти подсказки, продолжая использовать ваш любимый способ именования переменных. Например, в данной статье используется модифицированная Венгерская нотация использующая одно-, дву-, и трехсимвольные префиксы в именах переменных. Например, мы использовали переменную sProduct. Префикс "s" указывает на то, что это переменная типа String. Конечно, Flash ничего об этом не знает. И не нужно, потому что тип переменной задан строго, и Flash в нужный момент выдаст правильную подсказку по коду. Вот пример с объявлением переменной, которая ссылается на объект Color. Затем, если я введу имя переменной и точку, появится подсказка по коду. Рис. 2 это демонстрирует.
s
Рис. 2: еще один пример подсказки по коду
В ActionScript 2.0 вы можете указать тип возвращаемого функциией результата. Это дает вам преимущество: теперь вы уверены, что придерживаетесь ваших собственных намерений и программируете последовательно в пределах вашего собственного кода. Чтобы задать тип возвращаемого результата, нужно после закрывающей скобки оператора вызова функции приписать двоеточие и тип данных. Синтаксис очень похож на тот, что используется при строгом контроле типов переменных. Вот пример, в котором тип возвращаемого функцией результата определяется как Number:
Обратите внимание, что в этом примере также проводится контроль типов данных для входных параметров функции. Ведь параметры по существу являются переменными, и если вы попытаетесь присвоить им значение неверного типа при вызове функции, Flash сгенерирует ошибку. Например, следующий код:
Выдаст такую ошибку (потому что второй параметр строковый, а должен быть числом):
**Error** Scene=Scene 1, layer=Layer 1, frame=1:Line 5: Type mismatch. trace(multiply(6, "Flash MX 2004"));
Вернемся к контролю типа возвращаемого значения. Это работает на вас двумя способами. Если вы забудете вернуть значение правильного типа, то Flash вам об этом скажет. Например, если вы напишете функцию multiply() вот так:
multiply()
То получите ошибку типа:
**Error** Scene=Scene 1, layer=Layer 1, frame=1:Line 2: The expression returned must match the function's return type. return "Flash MX 2004";
Потому что тип реально возвращаемого значения должен соответствовать заявленному типу.
Также, если вы попытаетесь назначить возвращаемое функцией значение некой переменной, Flash проверит, соответствуют ли типы переменной и возвращаемого значения. Например:
function multiply(nA:Number, nB:Number):Number { return (nA * nB); }
var sProduct:String = multiply(6, 5);
В приведенном примере производится попытка присвоить переменной типа String возвращаемое функцией multiply() значение типа Number. Так как функция multiply() возвращает значение типа Number, Flash выдаст ошибку:
**Error** Scene=Scene 1, layer=Layer 1, frame=1:Line 5: Type mismatch in assignment statement: found Number where String is required. var sProduct:String = multiply(6, 5);
Мы рассмотрели строгий контроль типов данных и контроль типа возвращаемого функцией результата в ActionScript 2.0. Программисты с опытом в языках, уже поддерживающих такие возможности (например, Java, C#, C++) и сами знают, в чем заключаются преимущества такого подхода. Но тем, кто не имеет такого опыта, может показаться, что вместо преимуществ они получают только новые проблемы и ограничения. Так в чем же состоят эти преимущества?
Выше мы уже упоминали о некоторых из них. Вот главные плюсы:
Важно отметить, что есть множество моментов, для которых не производится проверка на этапе компиляции. Мы видели пример такого момента, когда рассматривали строгий контроль типов — я о возможности перезаписи переменных при повторном объявлении с использованием ключевого слова var. Это нехорошо! Большaя часть языков, реализующих контроль типов, выдаст ошибку при попытке сделать такой трюк. Помните: Flash MX 2004 — это первый релиз с поддержкой ActionScript 2.0. Очевидно, мы увидим множество улучшений в будущих версиях (ага, типа ActionScript 3.0 — прим перев).
Надеюсь, это введение в ActionScript 2.0 не напугало кого-либо из присутствующих). Во второй части мы рассмотрим формальный синтаксис классов в ActionScript 2.0.
Полезно почитать также статью Евгения "John" Потапенко "НЕМНОГО О СЕДЬМОМ FLASH".
Дельная вещь, и исходник прилагается. Смотреть здесь: http://dembicki.narod.ru/fla/circle3PT.html Качать это: http://dembicki.narod.ru/fla/circle3PT.fla
Peter Hall собрал свои самые-самые наработки в ActionScript-кодинге (а мы знаем, что он — далеко не последний в этом деле человек) и упаковал их в т.н. ActionScript Library Extension v1.0.1, которое вы можете скачать с его сайта и установить себе с помощью Extension Manager. Питер пишет, что брал исходные файлы прямо из своей личной Include-директории. Вот список этих файлов:
com/peterjoel/MovieClip/FrameEvent.as
com/peterjoel/Patterns/Broadcaster.as
com/peterjoel/Patterns/Parasite.as
com/peterjoel/MovieClip/getCentre.as
com/peterjoel/MovieClip/getCorner.as
com/peterjoel/String/splice.as
com/peterjoel/XML/getNode.as
com/peterjoel/XML/getNodes.as
Одной из трудностей при написании ActionScript является неадекватная реакция среды разработки Flash на наши попытки доступа к несуществующим функциям или переменным — а точнее, полное отсутствие такой реакции. Из-за этого отладка кода становится более сложной, чем могла бы быть. Вспомните, как часто вы клевали носом в клавиатуру до полуночи или дольше, и ложились спать в недоумении, так и не добившись нужного результата — а утром, но свежую голову, вы видели, что вместо flyingCow_mc написали flaingCow_mc — вся проблема бла в одной буковке..
Сколько невнимательных умов разбивалось об эти скалы.. пока не появился Майк Чамберс со следующим кодом:
Foo.prototype.__resolve = function(name) { trace("[" + name + "] property / function does not exist"); }
var f = new Foo();
f.barProp; f.barFunc();
Чтобы использовать это, просто добавьте функцию __resolve к тому классу или объекту, за которыми хотите установить наблюдение.
__resolve
Можно также написать просмтой код, который проходит через весь ваш скрипт и бережно прикрепляет эту полезную функцию ко всем объектам вашего клипа (только не забудьте удалить этот кусочек кода, когда закончите разработку основного кода).
Очевидно, что если вы хотите установить наблюдение за всеми, за кем оно еще не установлено, можно написать так:
Еще одно преимущество использования встроенного редактора ActionScript.
Как известно, встроенный во Flash редактор кода помогает нам при последовательном кодировании. Речь идет о применении "правильных" суффиксов, таких, как "_mc" (класс MovieClip), "_txt" (класс TextField) и др. в именах переменных — при этом Flash "подсказывает" (code hints) возможные дальнейшие варианты написания кода (подробнее об этом написано в Стандартах ActionScript).
_mc
_txt
TextField
Теперь представьте, что вы создаете новый объект, например, класса Sound. Но вы хотите использовать для его обозначения имя mySnd, а не mySound_sound — и чтобы при этом для mySnd показывались подсказки (code hints), как для mySound_sound. Существует очень быстрый способ (не XML) сделать это прямо в среде разработки Flash, не отрываясь от процесса кодирования. Просто напишите прямо в коде такую конструкцию:
Sound
mySnd
mySound_sound
Это все. Вот общий синтаксиc всех конструкций такого типа:
Остановимся подробнее на целесообразности описанного трюка. Что происходит? Происходит объявление идентификатора переменной (mySnd, имяПеременной) как относящегося к классу (Sound, Класс) — и больше ничего. Это прием хорош, чтобы выделять одно имя переменной, указывая его принадлежность к классу, и тем самым "включив" для него встроенный механизм подсказок — "code hints". Это никак не противоречит применению "правильных" суффиксов при написании кода. А значит, и стандарты целы, и хацкеры сыты :).
имяПеременной
Класс
Роберт Пеннер опубликовал обновленную версию разработанных им easing equations, если по-русски — это библиотека уравнений, описывающих динамику движения точки: (линейная, квадратичная, кубическая, экспоненциальная и т.д.). Лучше увидеть easing equations в действии и начать применять их в собственных работах. Для этого их можно скачать.
Андрей Михайлов [Andre Michelle] хорошо поработал в сфере трехмерного Actionscript'а; результат его усилий — отличный пример вращающейся геосферы. Такой красивой реализации до этого не существовало; к тому же, Андрей еще и не жадный человек, он делится с нами исходным кодом основанным на очень быстром движке рендеринга. Вообще, посмотрите другие его работы [на сайте] — оно того стоит. Хочется также отметить, что Андрей в данной разработке отличился еще и красивым логическим подходом. Логика была такова:
— Где бы взять оптимальный алгоритм рендеринга? — спросил себя Андрей. — Там, где этот алгоритм проработан и оптимизирован до мелочей! — ответил себе Андрей, взял MaxScript от discreet и превратил его в ActionScript!
Оригинально и эффективно. Думайте!
Ralf Bokelberg однажды спросил в конференции FlashCoders: как быстро остановить выполнение кода в Flash Player? Ответов последовало большое множество, но методы Питера Холла [Peter Hall] кажутся наиболее оптимальными:
Вот скрипт, состоящий всего из одной строки:
((a={}).__proto__=a).a;
А вот этот использует меньше символов:
function f(){f()};f();
(мы бы написали, чем еще отличаются эти два метода (и в чем суть), но это уже отдельная статья.)
Может быть, есть лучший способ? while(true) не предлагать, та как это сработает только через 15 секунд. // via peterjoel
while(true)
Совсем древнее: 17-20.09.2002, 23-30.09.2002, 01-04.10.2002, 07-11.10.2002, 14-19.10.2002, 20-26.10.2002, 27.10-02.11.2002, 04-08.11.2002, 11-16.11.2002, 18-23.11.2002 25-30.11.2002, 02-07.12.2002, 09-14.12.2002 Сайт заработал 17.09.2002