Import assets from Library

In ActionScript 2.0 it is quite easy to import movie clips from Library via the MovieClip.attachMovie() function. In ActionScript 3.0 it’s a little bit different. The movie clips (or assets in the Library) don’t have a linkage id anymore. Instead they have class names.

So the way to import a movie clip (or another asset) is to first get a reference to that class specified as class name. This is done using the flash.utils.getDefinitionByName() function. Then instantiate the class and finally add the object to the display list.

Here is a simple example:

1
2
3
4
5
6
7
8
9
import flash.utils.getDefinitionByName;
 
var className:String = "TestClip";
var ClassReference:Class = getDefinitionByName(className) as Class;
var clip:MovieClip = new ClassReference();
 
addChild(clip);
clip.x = 100;
clip.y = 100;

Skinning applications using a single image

A few days ago one of my colleagues showed me this interesting tutorial on how to use a single image as a sprite map to skin an entire application. The idea isn’t new at all, desktop applications use it a lot to change their appearances.

Basically, you have a single large image that contains graphical elements used by the controls of the application. You read the image and extract those graphical elements (bitmap images). This Flash tutorial shows you just how you could do it in Flash: http://flash.tutsplus.com/tutorials/effects/build-a-smart-flash-decalsheet-system/. This is quite interesting and worth going through.

Listing the properties of an object

This is easy for AS2 – you just use a for() statement to go through all the properties the object has:

for (var i in obj) trace(i+" = "+obj[i]);

There would be the property names listed in the Output panel along with their values.

But for AS3, it seems that this is not always working. You would use that for() statement but not all the properties would be listed. It happened to me quite a few times. So, how can you display all the properties of an object ? Well, ActionSscript 3.0 has a useful function called describeType(). It is located in the flash.utils package. It must receive the target object (or even a class name) as argument and it returns a XML object containing the properties and methods of that object/class. Pretty neat, huh ?

Now, I’ve played around with it a little and it seems that there’s a catch to it. If your target object is an instance of a dynamic class (it allows you to add new properties dynamically), the describeType() function will only display the properties and methods listed in the class, without the extra properties you might have added. So, practically the final solution might be the use of both the for() loop and the describeType() function, especially if you want to make sure that all of the properties are listed and you’re not sure whether the object is an instance of a dynamic class or not. Something like this:

1
2
3
4
5
6
7
8
9
10
11
12
import flash.utils.describeType;
 
var obj:Object = new Object();
obj.param1 = "param1";
obj.param2 = 23.3;
obj.param3 = 29;
obj.param4 = false;
 
for (var i:* in obj) trace(i+" :: "+obj[i]);
trace("---------");
var description:XML = describeType(obj);
trace(description);

Displays

param1 :: param1
param2 :: 23.3
param3 :: 29
param4 :: false
---------
<type name="Object" isDynamic="true" isFinal="false" isStatic="false">
  <method name="hasOwnProperty" declaredBy="Object" returnType="Boolean" uri="http://adobe.com/AS3/2006/builtin">
    <parameter index="1" type="*" optional="true"/>
  </method>
  <method name="isPrototypeOf" declaredBy="Object" returnType="Boolean" uri="http://adobe.com/AS3/2006/builtin">
    <parameter index="1" type="*" optional="true"/>
  </method>
  <method name="propertyIsEnumerable" declaredBy="Object" returnType="Boolean" uri="http://adobe.com/AS3/2006/builtin">
    <parameter index="1" type="*" optional="true"/>
  </method>
</type>

If you want to list the properties and methods separately, using the describeType() function, here’s how to do it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import flash.utils.describeType;
import flash.media.Camera;
 
var obj:Camera = new Camera();
var description:XML = describeType(obj);
 
trace("Properties:\n------------------");
for each (var a:XML in description.accessor) trace(a.@name+" : "+a.@type);
 
trace("\n\nMethods:\n------------------");
for each (var m:XML in description.method) {
	trace(m.@name+" : "+m.@returnType);
	if (m.parameter != undefined) {
		trace("     arguments");
		for each (var p:XML in m.parameter) trace("               - "+p.@type);
	}
}

Displays

Properties:
------------------
motionTimeout : int
activityLevel : Number
loopback : Boolean
fps : Number
height : int
width : int
motionLevel : int
bandwidth : int
muted : Boolean
name : String
index : int
keyFrameInterval : int
currentFPS : Number
quality : int
 
 
Methods:
------------------
setKeyFrameInterval : void
     arguments
               - int
setLoopback : void
     arguments
               - Boolean
setQuality : void
     arguments
               - int
               - int
setCursor : void
     arguments
               - Boolean
setMotionLevel : void
     arguments
               - int
               - int
setMode : void
     arguments
               - int
               - int
               - Number
               - Boolean
hasEventListener : Boolean
     arguments
               - String
dispatchEvent : Boolean
     arguments
               - flash.events::Event
removeEventListener : void
     arguments
               - String
               - Function
               - Boolean
willTrigger : Boolean
     arguments
               - String
addEventListener : void
     arguments
               - String
               - Function
               - Boolean
               - int
               - Boolean
toString : String

Please note that the function will not return any static properties the object might have. If you want to get the list of static properties too, you need to provide the class name as argument of the function and not an instance of the class:

1
2
3
4
import flash.utils.describeType;
 
var description:XML = describeType(Event);
trace(description);

Displays

<type name="flash.events::Event" base="Class" isDynamic="true" isFinal="true" isStatic="true">
  <extendsClass type="Class"/>
  <extendsClass type="Object"/>
  <constant name="COMPLETE" type="String"/>
  <constant name="FULLSCREEN" type="String"/>
  <constant name="UNLOAD" type="String"/>
  <constant name="CONNECT" type="String"/>
  <constant name="CLOSE" type="String"/>
  <constant name="SCROLL" type="String"/>
  <constant name="DEACTIVATE" type="String"/>
  <constant name="ENTER_FRAME" type="String"/>
  <constant name="ID3" type="String"/>
  <constant name="SELECT" type="String"/>
  <constant name="SOUND_COMPLETE" type="String"/>
  <constant name="TAB_CHILDREN_CHANGE" type="String"/>
  <constant name="INIT" type="String"/>
  <constant name="TAB_ENABLED_CHANGE" type="String"/>
  <constant name="MOUSE_LEAVE" type="String"/>
  <constant name="ADDED_TO_STAGE" type="String"/>
  <constant name="OPEN" type="String"/>
  <constant name="CANCEL" type="String"/>
  <constant name="REMOVED" type="String"/>
  <constant name="REMOVED_FROM_STAGE" type="String"/>
  <constant name="ADDED" type="String"/>
  <constant name="RENDER" type="String"/>
  <constant name="TAB_INDEX_CHANGE" type="String"/>
  <constant name="CHANGE" type="String"/>
  <constant name="RESIZE" type="String"/>
  <constant name="ACTIVATE" type="String"/>
  <accessor name="prototype" access="readonly" type="*" declaredBy="Class"/>
  <factory type="flash.events::Event">
    <extendsClass type="Object"/>
    <constructor>
      <parameter index="1" type="*" optional="false"/>
      <parameter index="2" type="*" optional="true"/>
      <parameter index="3" type="*" optional="true"/>
    </constructor>
    <method name="stopImmediatePropagation" declaredBy="flash.events::Event" returnType="void"/>
    <accessor name="type" access="readonly" type="String" declaredBy="flash.events::Event"/>
    <method name="preventDefault" declaredBy="flash.events::Event" returnType="void"/>
    <accessor name="currentTarget" access="readonly" type="Object" declaredBy="flash.events::Event"/>
    <method name="toString" declaredBy="flash.events::Event" returnType="String"/>
    <accessor name="target" access="readonly" type="Object" declaredBy="flash.events::Event"/>
    <accessor name="bubbles" access="readonly" type="Boolean" declaredBy="flash.events::Event"/>
    <accessor name="cancelable" access="readonly" type="Boolean" declaredBy="flash.events::Event"/>
    <method name="clone" declaredBy="flash.events::Event" returnType="flash.events::Event"/>
    <method name="formatToString" declaredBy="flash.events::Event" returnType="String">
      <parameter index="1" type="String" optional="false"/>
    </method>
    <accessor name="eventPhase" access="readonly" type="uint" declaredBy="flash.events::Event"/>
    <method name="stopPropagation" declaredBy="flash.events::Event" returnType="void"/>
    <method name="isDefaultPrevented" declaredBy="flash.events::Event" returnType="Boolean"/>
  </factory>
</type>

In this case the constants are all listed as sub-nodes of the main node and the properties and events are actually found in a sub-node called <factory> so the way to get the list of properties and methods will be relative to the <type><factory> node. Also, the isStatic attribute of the base <type> node will tell you that the target object is static or not.

A Boolean value occupies 4 bytes ???

I had a little time today to go through some of the blogs I read and Lee Brimelow wrote on The Flash Blog that a Boolean takes up 4 bytes (confirmed by the Flash player team). Initially, in his article he wrote about one byte being occupied by a Boolean but he updated it later on.

While I understand having a Boolean occupy 1 byte (guess that would be a minimum size for objects), I think having 4 bytes for a Boolean is a little too much. Especially since a Boolean value can only have two values (true/false – 0/1) so it would only need a single bit. In this case, 10 Booleans would take up to 40 bytes. Now, for the great majority of Flash apps this isn’t really a problem but for those who need to keep their apps to a VERY VERY minimal, that space could count, or in case when high speed is needed.

The conclusion: don’t use too many Booleans if you don’t have to or use Lee’s method of to handle more Boolean values (a good one I might add), by using ByteArrays.

Loader class with content scaling

Some time ago I needed a loader object that would allow scaling the content. So I simply created a class that extends the Loader class itself and adds that extra feature to it. The scaling occurs write after the content has been loaded and during resizing. I’ve named the class SimpleLoader and it has a Boolean property that allows the scaling when set to true, otherwise it just behaves like the standard Loader class.

I thought I should share it with you, so here it is. The class is documented so you should have no problem understanding it. Feel free to use it as you like.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package {
 
	import flash.display.Loader;
	import flash.events.Event;
 
 
	/**
	 * class SimpleLoader
	 * 
	 * @author negush
	 */
	public class SimpleLoader extends Loader {
 
		/**
		 * The width and height setters have effect only after the content has been loaded.
		 */
 
		private var _scale:Boolean = false;
		private var _width:Number = 0;
		private var _height:Number = 0;
 
		private var scaleRatio:Number;
 
 
		/**
		 * Constructor.
		 */
		public function SimpleLoader() {
			super();
			this.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
		}
 
 
		/**
		 * Handler function for the Event.COMPLETE event. Initializes the width and height of the
		 * content and calculates the scale ratio of the image, used when the loader is resized
		 * with the content being scaled. Catches the Loader's event and dispatches it as SimpleLoader.
		 */
		private function completeHandler(evt:Event):void {
			// The initial size of the content.
			this._width = this.contentLoaderInfo.width;
			this._height = this.contentLoaderInfo.height;
			// The scale ratio content_width / content_height.
			this.scaleRatio = this.contentLoaderInfo.width / this.contentLoaderInfo.height;
			if (this.scale) scaleToWidth();
			var newEvent:Event = new Event(Event.COMPLETE);
			dispatchEvent(evt);
		}
 
 
		/**
		 * Resizes the loader keeping the aspect ratio according to the new width. In this case the
		 * new height is calculated so that the content keeps its aspect ratio according to the
		 * loader's new width.
		 */
		private function scaleToWidth():void {
			this._height = Math.round(this.width / this.scaleRatio);
			super.width = this._width;
			super.height = this._height;
		}
 
 
		/**
		 * Resizes the loader keeping the aspect ratio according to the new height. In this case the
		 * new width is calculated so that the content keeps its aspect ratio according to the
		 * loader's new height.
		 */
		private function scaleToHeight():void {
			this._width = Math.round(this.height * this.scaleRatio);
			super.width = this._width;
			super.height = this._height;
		}
 
 
		//***********************************************************************
		//
		//	getters and setters
		//
		//***********************************************************************
 
		/**
		 * Setter/getter for the _scale property. Activates or deactivates the scaling for the
		 * current loader instance. If the scale is set to true, the content's height will be
		 * recalculated so that the content keeps the current width but will have the original
		 * aspect ratio.
		 * 
		 * true = resize keeping content aspect ratio
		 * false = resize without keeping content aspect ratio
		 * 
		 */
		public function set scale(value:Boolean):void {
			if (this._scale == value) return;
			this._scale = value;
			if (value) scaleToWidth();
		}
 
		public function get scale():Boolean {
			return this._scale;
		}
 
 
		/**
		 * Overrides the Loader's width setter and getter. The setter resizes the content
		 * according to the scale property's value.
		 */
		override public function set width(value:Number):void {
			if (this._width == value) return;
			this._width = value;
			if (this.scale) scaleToWidth();
			else super.width = value;
		}
 
		override public function get width():Number {
			return this._width;
		}
 
 
		/**
		 * Overrides the Loader's height setter and getter. The setter resizes the content
		 * according to the scale property's value.
		 */
		override public function set height(value:Number):void {
			if (this._height == value) return;
			this._height = value;
			if (this.scale) scaleToHeight();
			else super.height = value;
		}
 
		override public function get height():Number {
			return this._height;
		}
 
	}
 
}

UPDATE:
And here is how you can use it. It works just like the Loader class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import SimpleLoader;
 
var ldr:SimpleLoader = new SimpleLoader();
ldr.load(new URLRequest("myimage.jpg"));
ldr.x = 20;
ldr.y = 20;
ldr.scale = true;
addChild(ldr);
 
ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
 
function completeHandler(evt:Event):void {
	ldr.width = 300;
	ldr.height = 100;
	trace("loader size: "+ldr.width+" x "+ldr.height);
}

ActionScript 3.0 code performance tester

I just found a cool Flex application that shows some tests for various ActionScript 3.0 code blocks like loops, increments, division or Array instantiation. This might be good to know when you work on a project that should have code that executes fast. Here’s the link: http://businessintelligence.me/projects/performance_tester/performanceTester.html

A Happy 2009 to all of you !

Now that 2009 has begun, I wish everybody A Happy New Year !

Looking back at 2008 it really was a busy year from the Flash/AS3 point of view and hope that 2009 will bring us more interesting stuff. I’ve started this blog a year ago and unfortunately I cannot say that it’s where I wanted it to be.

Still, after 30 posts and 32 comments, it’s not so bad… (it’s good to be optimistic). Hopefully in 2009 I’ll have more time to write more interesting articles on ActionScript 3, Flash and possibly Flex and AIR.

For the future, I intend to start working a little bit in Flex and AIR too. I’ll be working on a mp3 player in AIR so I could use it on Mac too – I’m not satisfied with iTunes’ playlist functionalities. So I guess this will be my first project with Flex and AIR. But don’t worry, once I’ll get it finished, I’ll make it available to all of you (fingers crossed) :D. I’d really like to get better with Flash/ActionScript 3 (and of course Flex and AIR), but this depends totally on me. So I really have to find the time for extra study and work.

With that said I hope this year will be much better than the last one, both on professional and personal level. And this is what I wish for all of you: surpass yourselves, be better than you were, make greater things, love more, learn more, be more you can be.

Happy New Year !

Personal website or blog: that is the question

I’ve been pondering from quite some time whether there’s any reason for me to have a personal website and the blog or simply the blog. Last year, when I’ve started this blog, I had in mind to create my own personal website (in Flash of course) that I would fill with all sorts of stuff. A year has passed and… nothing… I didn’t really have the time to think at my site, let alone to start working on it. Naturally, I started wondering if I would really need a site since the blog could cover all the topics I want. I could have a page with all my personal projects, a page for Flash/Flex/Air resources, maybe even a photo gallery and all this in the blog itself. So I could just concentrate on shaping and customizing my blog instead of creating a personal site from scratch. I mean, the blog is already there. It’s all set up. All I have to do is come up with some nice design (that I could even find ready-made on the Internet) and simply add all the information I want to share… easy as that. Plus, the entire back-end is already in place.

Right now, I think today is much easier to set up a personal website based on a blog, than to create your own site from scratch. Of course you could just purchase a website template, but that would need more tinkering since it usually doesn’t fit one’s needs. So, finally, I took the decision to drop the idea of a personal website and instead just have some sort of welcome page that would redirect to the blog itself and do my magic on the blog. Hopefully I’ll have some spare time to create that welcome page in the next year :)).