Знаешь ли ты что?
Знаешь ли ты что? – это 100 советов по AS3. Данный перевод осуществлялся на форуме flasher.ru. Для массового распространения культуры ActionScript 3, я решил выложить его и на этом сайте, в более удобном, как я думаю, формате.
[Страница в процессе]
В ActionScript 3, можно динамически менять частоту кадров (frame rate) ролика используя класс Stage.
Класс Stage (flash.display.Stage) связан со сценой главного ролика и имеет свойство frameRate, которое может принимать значения от 0.01 до 1000, и определяет частоту кадров, с которой Flash плеер проигрывает ролик. Изменять это значение можно на лету.
Пример:
// изменить частоту кадров на 12 fps: stage.frameRate = 12;
ActionScript 3 полностью базируется на классах. Создавая классы, вы создаете переменные и функции (методы) которые связаны с экземпляром класса. В отличие от ActionScript 2 методы в ActionScript 3 сохраняют область видимости их класса, даже если вызываются из другого объекта, или через Function.call и Function.apply.
Пример:
package { import flash.display.Sprite; public class ClassScope extends Sprite { public function ClassScope() { traceThis(); // "Class Instance" var obj:Object = new Object(); obj.traceThis = traceThis; obj.traceThis(); // "Class Instance" traceThis.call(new Sprite()); // "Class Instance" } public override function toString():String { return "Class Instance"; } public function traceThis():void { trace(this); } } }
Как и в ActionScript 1,2 в ActionScript 3 есть методы для динамического рисования в отображаемых объектах (movie clips, sprites, и т.п.), которые имеют свойство graphics (flash.display.Graphics). Свойство graphics выступает в роли специального слоя для рисования, который расположен под всеми дочерним клипами. Так же в ActionScript 3 добавлены новые методы для рисования прямоугольников (в том числе и со скругленными углами), окружностей и эллипсов:
-
drawCircle(x:Number, y:Number, radius:Number):void -
drawEllipse(x:Number, y:Number, width:Number, height:Number):void -
drawRect(x:Number, y:Number, width:Number, height:Number):void -
drawRoundRect(x:Number, y:Number, width:Number, height:Number, ellipseWidth:Number, ellipseHeight:Number):void
Пример:
// Нарисовать синий прямоугольник со скругленными углами: var square:Sprite = new Sprite(); square.graphics.beginFill(0xFF); square.graphics.drawRoundRect(0, 0, 100, 50, 10, 10); square.graphics.endFill(); addChild(square);
ActionScript 3 поддерживает широкий диапазон типов переменных, включая несколько отсутствующих в предыдущих версиях ActionScript. Основные типы для AS3:
Простые:
BooleanintnullNumberStringuintundefined
Сложные:
ObjectArrayDateErrorFunctionRegExpXMLXMLList
Существуют также дополнительные типы, которые относятся к их классам; такие как : Matrix (flash.geom.Matrix), Shape (flash.display.Shape), URLRequest (flash.net.URLRequest), и т.д.
Примечание:
- Специальный тип
Voidизменился в AS3 на слово в нижнем регистре (void, а неVoid) - Новый тип
*используется для обозначения любого типа данных. Рекомендуется использовать вместо опущенной информации о типе для ваших переменных.
Пример:
var anything:*;
object) теперь определен как XMLObject. XML теперь обозначает новый E4X-based XML объект.int и uint - новые простые типы данных для целых (числа без дробной части) и unsigned integer (неотрицательные числа без дробной части). Могут быть полезны для значений, не подразумевающих дробные значения, как, например, итераторы цикла. В большинстве случаев использование типа данных int вместо Number обеспечит небольшое увеличение производительности, а uint лучше использовать только когда это необходимо, например для значений цветаActionScript 3 пополнилась коллекция "отображаемых объектов", которые могут быть видимы на экране и добавлены в "display list".
Отображаемые объекты AS3 :
- AVM1Movie
- Bitmap
- Loader
- MorphShape*
- MovieClip
- Shape
- SimpleButton
- Sprite
- StaticText*
- TextField
- Video
* Для ссылки на объекты существующие в timeline; вы не можете создавать их с помощью AS.
AVM1Movie представляет собой flash-ролик, созданный в ActionScript 1 или 2. Эти ролики используют ActionScript Virtual Maching 1, тогда как AS3 ролики используют AVM2. AVM2 ролики могут проигрывать ролики AVM1, но не могут взаимодействовать с ними (с их ActionScript) используя AS3.
Bitmaps - объекты bitmap. Вы можете задавать им изображение с помощью BitmapData объектов или это могут быть bitmap-картинки из файлов.
Объекты Loader - отображаемые объекты, которые загружают в себя внешнее содержимое. Это могут быть изображения или другие SWF-приложения.
MorphShapes - это shape tweens (анимации фигур), созданные на timeline. Хотя вы не можете создать их в ActionScript, вы можете получить доступ к уже существующим на timeline, используя ActionScript и они будут иметь тип MorphShape.
MovieClips - это ролики, которые вы знаете и любите.
Shapes это разобранные ролики, которые по существу содержат только graphics object для рисования в нем с использованием vector drawing API. Использование Shapes вместо MovieClips или Sprites может помочь сэкономить память
Sprite объекты - по существу ролики без timelines. Это наиболее часто используемый тип в AS3, и обычно он расширяется при создании вашего собственного подкласса отображаемых объектов.
StaticText, как и MorphShapes, не могут быть созданы в ActionScript, ссылаясь вместо этого на объекты static text, созданные на Flash timeline.
Объекты TextField включают dynamic и input text.
Объекты Video представляют Flash video.
Директива import в ActionScript 3 немного отличается от import в ActionScript 2. В AS2 import использовался только для сокращения имен классов, определенных в пакетах; она не была обязательной для использования класса. Вместо использования import, вы могли просто использовать полное имя класса, например:
// ActionScript 2 var myPoint:flash.geom.Point = new flash.geom.Point(0,0);
В ActionScript 3, директива import обязательна для доступа к классам в их пакетах, даже если вы ссылаетесь на класс по его полному имени. Вы все еще можете использовать полное имя (или только проимпортированное имя класса), но использование import необходимо
Пример:
// ActionScript 3 import flash.geom.Point; var myPoint:flash.geom.Point = new flash.geom.Point(0,0);
Как и в AS2, в AS3 вы можете также использовать символ шаблона (*) для импорта всех классов в пакете.
Например:
import class
ActionScript позволяет заменить назначенный объекту тип на другой совместимый при необходимости. Это называется приведением (casting). Оба ActionScript 2 и 3 поддерживают приведение с использованием синтаксиса type(object). Например, если объект вашего класса был назначен переменной как object, вы можете переопределить типизацию для этого объекта приведением его к типу вашего класса, дав таким образом возможность Flash знать какие именно методы и свойства доступны у этого объекта
Пример:
var obj:Object = getMyCustomObject(); var customObj:MyClass = MyClass(obj);
ActionScript 3 вводит новый оператор для приведения типов - оператор as. Оператор as заменяет приведение типа с использованием type(object) синтаксиса в ActionScript 2 на синтаксис object as type.
Пример:
var obj:Object = getMyCustomObject(); var customObj:MyClass = obj as MyClass;
Оператор as работает весьма схоже с приведением в ActionScript 2. Если преобразование не может быть выполнено, его результат null. В противном случае приводимый объект возвращается и ему назначается указанный тип.
ActionScript 3 все еще поддерживает type(object) приведение, но его поведение имеет теперь некоторые отличия. Вместо возврата null при неправильном приведении, генерируется TypeError. Сбой происходит когда вы пытаетесь привести объект к несовместимому типу, например при попытке привести объект к не связанному (not associated) или унаследованному типу.
Примечание: ActionScript также имеет глобальные функции преобразования для этих целей в стиле Class(object), имеющие приоритет над приведением type(object). Это такие функции, как String(), Number(), Array() и т.д. Они не выполняют приведение настолько же как фактическое преобразование одного объекта в другой (когда это возможно). Т.к. эти функции приоритетнее type(object), предпочтительнее использовать оператор as для приведения объектов к другому типу данных.
В ActionScript 2 переменные со значениями объявленные в теле класса сохранялись в прототипе класса. Из-за этого возникали проблемы с переменными, которые являются ссылками на объекты (например массивы Array):
Пример:
class myClass{ public var list:Array = [1,2,3]; } var a = new myClass(); var b = new myClass(); trace(a.list === b.list); // true
Здесь a.list и b.list фактически ссылаются на один и тот же массив.
В ActionScript 3 этой проблемы нет, такие переменные будут уникальны.
В ActionScript 2 событие MouseMove срабатывало глобально, неважно над каким клипом находилась мышка, любой listener от Mouse или любой мувиклип получали событие о перемещении мышки.
В ActionScript 3 для того чтобы получать события от мышки, нужно у интерактивного клипа (InteractiveObject такие как Sprites, MovieClips, Stage) добавить слушателя событий мышки (Listener), но события будут приходить только тогда, когда мышка находится над этим клипом. Для того чтобы получать события мышки в любом месте ролика, нужно добавить Listener к Stage.
Пример:
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
Ключевое слово delete во Flash используется для удаления определений переменных. Оно не удаляет объекты из памяти (это происходит за кулисами с помощью так называемого "сборщика мусора" /"Garbage Collector"/ ), а просто берет созданную вами переменную и избавляется от нее, делая ее недоступной и невидимой для итераторов (for..in циклы, и т.п.).
Внутренние механизмы Garbage Collector (GC для краткости), знают когда физически удалять объекты из памяти - когда больше нет переменных, ссылающихся на них. Так, например, если у вас есть две переменные A и B и они обе ссылаются на ObjectX, удаление переменной A не приведет к удалению сборщиком мусора ObjectX из памяти. Однако, если вы удалите обе переменные A и B, больше не будет ссылок на ObjectX и GC будет знать, что объект нуждается в удалении из памяти
Пример:
var a:Object = new Object(); var b:Object = a; // reference same new Object(); delete a; trace(b); // [object Object] - still exists in memory delete b; // GC will mark object for deletion from memory
Этот механизм работает практически одинаково для Flash 8 и Flash 9 (ActionScript 1, 2, и 3), однако в 8 были сделаны некоторые изменения для оптимизации GC. (Примечание: GC очищает память не сразу.)
Хотя GC и новая виртуальная машина, управляющая им, на самом деле не сильно изменились в ActionScript 3, что изменилось, так это поведение ключевого слова delete. Теперь ключевое слово delete работает только для динамических свойств экземпляров класса, но не для объявленных членов класса (переменных и методов). В ActionScript 1 и 2 delete можно было использовать для всего. ActionScript 3 позволит только удалить динамические переменные и заблокирует прочее.
// ActionScript 2 class DeleteVarClass { public var myVar:Number; function DeleteVarClass() { myVar = 1; trace(myVar); // 1 delete myVar; trace(myVar); // undefined } }
// ActionScript 3 package { public class DeleteVarClass { public var myVar:Number; public function DeleteVarClass() { myVar = 1; trace(myVar); // 1 delete myVar; trace(myVar); // 1 } } }
Поскольку myVar в примере выше был объявлен как свойство класса, он не может быть удален в ActionScript 3.
Поскольку вы не можете удалять члены класса в ActionScript 3, если вы хотите, чтобы переменная больше не ссылалась на объект или значение в памяти, вы можете установить значение переменной в null вместо ее удаления.
myVar = null;
Класс Dictionary (flash.utils.Dictionary) - новое дополнение в ActionScript. Он представляет собой то же самое, что и базовые объекты Object, за исключением одной особенности: в объектах Dictionary в качестве ключей могут быть использованы не только строки, но и любые другие значения.
Object использует только строковые ключи. Если в качестве для ключа используется не строковое значение, оно интерпретируется в строку.
Пример:
var obj:Object = new Object(); obj["name"] = 1; // string key "name" obj[1] = 2; // key 1 (converted to "1") obj[new Object()] = 3; // key new Object() converted to "[object Object]" for (var prop:String in obj) { trace(prop); // traces: [object Object], 1, name trace(obj[prop]); // traces: 3, 2, 1 };
Если вы попытаетесь использовать разные объекты в качестве ключей для Object, которые одинаково преобразуются в строку, в контейнере это будет один и тот же ключ, ссылающийся на единственное значение.
Пример:
var a:Object = new Object(); var b:Object = new Object(); var obj:Object = new Object(); obj[a] = 1; // obj["[object Object]"] = 1; obj[b] = 2; // obj["[object Object]"] = 2; for (var prop:String in obj) { trace(prop); // traces: [object Object] trace(obj[prop]); // traces: 2 }
Класс Dictionary подобного ограничения не имеет. В качестве ключа вы можете использовать любой тип. Таким образом, если в примере выше использовать Dictionary, вы получите два различных ключа, по одному для каждого объекта.
Пример:
import flash.utils.Dictionary; var a:Object = new Object(); var b:Object = new Object(); var dict:Dictionary = new Dictionary(); dict[a] = 1; // dict[a] = 1; dict[b] = 2; // dict[b] = 2; for (var prop:* in dict) { trace(prop); // traces: [object Object], [object Object] trace(dict[prop]); // traces: 1, 2 }
И несмотря на то, что вы все же получили [object Object] при трассировке, это просто результат строкового преобразования в команде trace; это уникальный объектный ключ в экземляре Dictionary.
Обратите внимание, что prop здесь определена как *. Это важно, т.к. ключи в объекте dict могут быть любого типа. Если вы используете String как тип prop, объекты a и b при их выборке в цикле будут приводиться к строкам, помещая в prop "[object Object]" вместо действительных ссылок на a и b, которыми они должны быть для корректного доступа к значениям 1 и 2 из dict.
В ActionScript 3 введены метки, новые идентификаторы, которые можно привязывать к блокам циклов. Зачем вам может понадобиться идентифицировать блок цикла? Потому, что этот идентификатор можно использовать в командах break и continue. Представьте себе два цикла, один вложен в другой. Если в какой-то момент вы захотите прервать оба цикла, находясь во внутреннем, вы этого сделать не сможете. Команда break прервет только текущий блок. Обычно для этих целей используют переменную-флаг, которую устанавливают во внутреннем цикле, чтобы иметь возможность проверить во внешнем и, при необходимости, выйти также и из него. Пример:
Пример:
var i:Number; var j:Number; var exit:Boolean = false; for (i=0; i<10; i++) { for (j=0; j<10; j++) { if (i > 3 && j > 3) { exit = true; break; } } if (exit) { break; } }
Когда i больше 3 и j больше 3, используется break для выхода из текущего цикла, но это выход только из цикла по j. Для того, чтобы выйти и из цикла i, была использована переменная exit с условным оператором if в цикле по i.
Метки позволяют вам идентифицировать и прерывать указанный цикл (а также все вложенные в него). Формат метки label: statement
Пример:
var i:Number; var j:Number; mainLoop: for (i=0; i<10; i++) { for (j=0; j<10; j++) { if (i > 3 && j > 3) { break mainLoop; } } }
Задав для первого цикла метку mainLoop, мы получили возможность легко прервать вложенный цикл, используя break mainLoop; Это позволяет писать более понятный код и избавляет от необходимости использовать дополнительные переменные.
В ActionScript 3 можно определить что мышка ушла за пределы флеш-ролика, используя событие mouseLeave для stage. Это событие происходит каждый раз, когда мышка покидает пределы ролика. Нет события mouseEnter, но можно использовать mouseMove для определения того, что мышка вернулась к нам.
Простой пример использования нарисованного квадрата в качестве своего курсора.
Пример:
package { import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; import flash.ui.Mouse; public class Test extends Sprite { private var cursor:Sprite = new Sprite(); public function Test() { cursor.graphics.beginFill(0xFF); cursor.graphics.drawRect(0, 0, 25, 25); addChild(cursor); stage.addEventListener(Event.MOUSE_LEAVE, cursorHide); stage.addEventListener(MouseEvent.MOUSE_MOVE, cursorFollow); Mouse.hide(); } public function cursorHide(evt:Event):void { cursor.visible = false; } public function cursorFollow(evt:MouseEvent):void { if (!cursor.visible) cursor.visible = true; cursor.x = stage.mouseX; cursor.y = stage.mouseY; evt.updateAfterEvent(); } } }
Когда мышка уходит за пределы флеш-ролика, наш курсор прячется. Когда мышка возвращается по событию mouseMove курсор снова отображается. Сделать такое в предыдущих версиях AS было нельзя.
В ActionScript 3 появился новый класс SimpleButton (flash.display.SimpleButton). Теперь можно динамически с помощью ActionScript создавать кнопки (Button).
Пример:
var myButton:SimpleButton = new SimpleButton();
Класс SimpleButton имеет 4 основных свойства, которые управляют возможными состояниями кнопки: upstate (кнопка не нажата), overState (мышка над кнопкой), downstate (кнопка нажата), и hitAreaState (область реагирования на мышку). Необходимо создать визуальные объекты для этих состояний и присвоить их к соответствующим свойствам.
Пример:
myButton.upState = mySprite1; myButton.overState = mySprite2; myButton.downState = mySprite3; myButton.hitAreaState = mySprite4;
При определении массива в ActionScript 3 с использованием квадратных скобок, теперь можно оставить запятую после последнего элемента и это не вызовет ошибки.
Пример:
var myList:Array = [ "The", "quick", "brown", "fox", ];
Наличие запятой после "fox" в ActionScript 1 и 2 вызвало бы ошибку.
Это не работает с Array() или new Array(), только с [].
Это конечно мелочь, но при отладке может сэкономить время, если вам, к примеру, нужно временно убрать последний элемент массива, просто закомментировать его. Раньше еще приходилось и убирать запятую перед ним, теперь все проще.
Пакеты в ActionScript 3 немного отличаются от пакетов в ActionScript 2. Теперь пакет это не часть имени класса, а блок определяемый ключевым словом package, который содержит в себе определение класса. Структура такова:
Пример:
package my.package.path { class MyClass { } }
В AS2 подобная запись выглядела бы так:
// ActionScript 2: class my.package.path.MyClass { }
Фактически в AS3 все классы должны быть внутри пакета, если не нужно давать имя пакету, то следует


