Subcribe via RSS

Brand new property MovieClip.isPlaying

January 18th, 2012 | 2 Comments | Posted in ActionScript3

I have discovered recently the new isPlaying property for the MovieClip class that Adobe introduced in Flash Player 11.

I do recommend you read What’s New in Flash Player 11 where you will find interesting new features like this one.

It’s great we finally have an easy way to know if our animations are running or simply stopped.

Take a look at the following code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import flash.events.Event;
import flash.events.MouseEvent;

this.addEventListener(Event.ENTER_FRAME, onLoop);
stage.addEventListener(MouseEvent.CLICK, onClick);

mc.play();

function onLoop(e:Event):void
{
txtInfo.text = mc.isPlaying ? "MovieClip playing!" : "MovieClip stopped";
}

function onClick(e:MouseEvent):void
{
if (mc.isPlaying) {
mc.stop();
} else {
mc.play();
}
}

As we see the use of this property keep things very simple and this is really welcome! Quite surprising this has not been available before.

Note the mc.play() in line 7. It seems this property does not know the MovieClip is playing by default, and the value gets updated when we use the MovieClip playback functions such as play(), stop() and so on…

If you are going to use the isPlaying property ensure to use those functions to have the correct value.

This is the result of the above code (Flash Player 11 required):

This movie requires Flash Player 9

You can download this example in Flash CS5 here.

UPDATE: I forgot to mention you need to target Flash Player 11 in your Flash IDE. This is not available by default in Flash CS5 or CS5.5 as you can only select up to Flash Player 10.2. In order to add Flash Player 11 follow the instructions explained here.

Important: If you run the movie within the Flash IDE it won’t work. The movie will be played by Flash Player 10.2. Test your published SWF file in your browser. You can now download the Release/Debug Flash Player 11.1 from the Adobe website here.

Building ActionScript3 components in Flash CS5 (part 3)

October 13th, 2011 | 2 Comments | Posted in ActionScript3

This is the last part of this tutorial and we are going to implement to our component a live preview that will display the text with the CSS styles in authoring time.

First of all we need to simplify the original implementation of the component class as we have functionality there for the preview of the component.

CSSLabel.as

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
package  {
  import fl.core.UIComponent;
  import flash.text.AntiAliasType;
  import flash.text.StyleSheet;
  import flash.text.TextField;
  import flash.events.Event;
 
  public class CSSLabel extends UIComponent {

    private var _textfield:TextField;
    private var _text:String;
    private var _styles:String;
   
    public function CSSLabel() {
      super();
      _text = "";
      _styles = "";
      addEventListener(Event.ENTER_FRAME, onEnterFrame);
    }
   
    private function onEnterFrame(e:Event):void {
      removeEventListener(e.type, onEnterFrame);
     
      var styles:StyleSheet = new StyleSheet();
      styles.parseCSS(unescape(_styles));
     
      _textfield = new TextField();
      _textfield.width  = width;
      _textfield.height = height;
      _textfield.autoSize = "none";
      _textfield.wordWrap = true;
      _textfield.multiline = true;
      _textfield.antiAliasType = AntiAliasType.ADVANCED;
      _textfield.selectable = false;
      _textfield.embedFonts = true;
      _textfield.styleSheet = styles;
      _textfield.htmlText = csstext;

      addChild(_textfield);
    }
   
    [Inspectable (name = "csstext", variable = "csstext", type = "String", defaultValue = "")]
    public function get csstext():String {
      return _text;
    }
   
    public function set csstext(value:String):void {
      _text = unescape(value);
    }

    [Inspectable (name = "styles", variable = "styles", type = "String", defaultValue = "")]
    public function get styles():String {
      return _styles;
    }
   
    public function set styles(value:String):void {
      _styles = unescape(value);
    }
  }
}

We have removed the drawSquare method and now in the onEnterFrame we just add the textfield.

Now the functionality for the live preview will be implemented in a separate file. Go ahead and create a new ActionScript 3.0 document named as CSSLabelLivePreview and save the file in the folder of the component. Do the same for a new ActionScript 3.0 class with the same name.

Here is the implementation we are going to use for the class:

CSSLabelLivePreview.as

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
package {
  import fl.core.UIComponent;

  import flash.text.AntiAliasType;
  import flash.text.Font;
  import flash.text.StyleSheet;
  import flash.text.TextField;
 
  public class CSSLabelLivePreview extends UIComponent {
 
    public var txtField:TextField;
    private var _csstext:String;
    private var _styles:String;
    private var _css:StyleSheet;
 
    public function CSSTextComponentLivePreview() {
      _width = super.width;
      _height = super.height;
      _csstext = "";
      _styles = "";
    }
   
    override public function setSize(w:Number, h:Number):void {
      _width = w;
      _height = h;
      draw();
    }

    public override function get width():Number {
      return _width;
    }
   
    public override function set width(w:Number):void {
      setSize(w, height);
    }

    public override function get height():Number {
      return _height;
    }
   
    public override function set height(h:Number):void {
      setSize(width, h);
    }
   
    public function set csstext(value:String):void {
      _csstext = value;
      invalidate();
    }
   
    public function get csstext():String {
      return _csstext;
    }

    public function set styles(value:String):void {
      _styles = value;
      _css = new StyleSheet();
      _css.parseCSS(unescape(_styles));
      invalidate();
    }
   
    public function get styles():String {
      return _styles;
    }
   
    override protected function draw():void {
      try {
        removeChild(txtField);
      } catch(e:Error) {}
     
      graphics.clear();
      graphics.beginFill(0xFFFFFF, 0);
      graphics.drawRect(0, 0, _width, _height);
      graphics.endFill();
      graphics.lineStyle(1, 0x333333, 0.3);
      graphics.drawRect(0, 0, _width, _height);
      drawTextField();
     
      super.draw();
    }

    public function drawTextField():void {
      txtField = new TextField();
      txtField.antiAliasType = AntiAliasType.ADVANCED;
      txtField.embedFonts = false;
      txtField.styleSheet = _css;
      txtField.width = _width;
      txtField.height = _height;
      txtField.multiline = true;
      txtField.wordWrap = true;
      txtField.htmlText = csstext == null ? "" : unescape(csstext);
     
      addChild(txtField);
    }
  }
}

Let’s understand what we do here. Pay attention to the class we extend from. It’s UIComponent and it’s the same as the component itself.

In the first part of this class we see that we override the setSize method as we need to manage the updates in size in the component.

In the second part we have setters and getters for the same properties we exposed with Inspectable in the component. This will connect the component properties to this class properties automatically so it’s essential to use the same names here.

In the last part we override the draw method where we draw a square and call the method drawTextField where we essentially add the textfield for displaying the text.

Now it’s time to put this all together! In the CSSLabelLivePreview Flash file we are going to use the following Document Class:

fl.livepreview.LivePreviewParent

This class provides the timeline of the component and manages the resize in authoring time.

We are going to set up now the classpaths needed for this movie. Remember that the class extends from UIComponent and for using that class we need to add this path:

$(AppConfig)/Component Source/ActionScript 3.0/User Interface

The same happens with the LivePreviewParent. We will need to add the following path:

$(AppConfig)/ActionScript 3.0/projects/Flash/src

The next thing we are going to do is add the preview graphics and link them to our class. Just create a new MovieClip with name Avatar and inside we will add a solid rectangle shape. It’s very important the size of this rectangle matches exactly the same size of the one we used in CSSLabel Flash file.

Now go ahead and create a new MovieClip with name CSSLabelPreview and place the Avatar MovieClip inside. Take care all the MovieClips has the same center coordinates and same location. I am using top-left and 0,0 for all the MovieClips positioning.

Once we have that ready open the properties of CSSLabelLivePreview from the Library and select Export to ActionScript. That will add the class name automatically with the same name as the MovieClip.

Now that all is in place let’s publish this movie!

Go back to CSSLabel Flash file and select the Component Definitions. Click the Set button for the Live Preview and add select Live Preview with .swf embeded .fla file. Browse to CSSLabelLivePreview.swf and click OK.

The component is now ready to be published. Following the same we did in the previous parts of this tutorial, select the option Export SWC File and overwrite the previous version.

Refreshing the Components Panel you can now drag and drop the component to a new Flash document and see that typing in the text field or the CSS in the Component Inspector the changes are being displayed in the component instantly.

Pretty cool huh? :)

You can download the source files and a sample movie in Flash CS5 here.

I hope this tutorial is helpful and let you get started with Flash custom component development.

Related tutorials
Part 1
Part 2

Building ActionScript3 components in Flash CS5 (part 2)

October 7th, 2011 | No Comments | Posted in ActionScript3

In the second part of this tutorial we are going to go ahead and add a custom panel for our component that will replace the parameters in the Component Inspector panel.

We have great benefits when we have a customized panel for the parameters. First of all because it’s much more user friendly and secondly because you can expose different parameters depending on other parameters.

The panel is going to be in a different file, so let’s create a new Flash ActionScript 3.0 document with name CSSLabelPanel.

In here we will need basically two TextArea components to allow us to edit the text to display and the CSS to apply. Below is how the panel looks:

CSSLabel Component Definitions Panel

Now that we have the UI ready to go, we can add the functionality. Go ahead and create a new ActionScript 3.0 class file named as CSSLabelPanel. Replace the content with the following:

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
package {
  import adobe.utils.MMExecute;

  import fl.controls.TextArea;

  import flash.display.Sprite;
  import flash.display.StageScaleMode;
  import flash.events.Event;

  public class CSSLabelPanel extends Sprite {
    private const CONTENT_TEXT:String = 'fl.getDocumentDOM().selection[0].parameters["csstext"].value';
    private const STYLES_CSS:String   = 'fl.getDocumentDOM().selection[0].parameters["styles"].value';
   
    public var contentText:TextArea;
    public var stylesCSS:TextArea;
   
    public function CSSLabelPanel() {
      this.stage.scaleMode = StageScaleMode.NO_SCALE;
      addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
    }
   
    private function init():void {
      contentText.addEventListener(Event.CHANGE, onContentTextChange);
      contentText.text = unescape(MMExecute(CONTENT_TEXT));

      stylesCSS.addEventListener(Event.CHANGE, onStylesCSSChange);
      stylesCSS.text = unescape(MMExecute(STYLES_CSS));
    }
   
    private function onAddedToStage(e:Event):void {
      removeEventListener(e.type, onAddedToStage);
      init();
    }

    private function onContentTextChange(e:Event):void {
      MMExecute(CONTENT_TEXT + ' = "' + escape(contentText.text) + '"');
    }

    private function onStylesCSSChange(e:Event):void {
      MMExecute(STYLES_CSS + ' = "' + escape(stylesCSS.text) + '"');
    }
  }
}

This class uses Flash JavaScript API to allow the comunication of the panel with the component. We have a couple of constants that point to that properties in the component (csstext and styles). Remember that those properties are exposed in the component as Inspectable.

The MMExecute is a method that runs Flash JavaScript commands from ActionScript. Using it we can retrieve or assign values to the properties of the component easily. See the way we initialize the textArea components and how we update the values when the content changes.

Note the use of escape and unescape needed here for storing the values with returns characters.

The last thing to highlight is we set the scaleMode as NO_SCALE. That is because we don’t want the panel to be resized with the window of the Component Inspector.

Now set the Document Class of the movie as CSSLabelPanel and publish the SWF.

Next we are going to do some changes from the original code in CSSLabel class.

1. Update the following methods as now the values may have return characters:

1
2
3
4
5
6
7
  public function set csstext(value:String):void {
    _text = unescape(value);
  }

  public function set styles(value:String):void {
    _styles = unescape(value);
  }

2. Update this line in the method onEnterFrame because now we are going to use embed fonts for the text:

1
  _textfield.embedFonts = true;

The last step is to add the panel to the component. For doing that we have to select the MovieClip in the library in the CSSLabel document and click the option Component Definition.

Now click the button Set for the Custom UI and browse to the SWF file of the panel. I recommend you to use the Custom UI in external .swf file when you are working on your panel as that will save you time when you republish the panel, but we have to select the option Custom UI with embeded in .fla file when we want to distribute the component.

Export your component as SWC file as we saw in the part 1 of this tutorial.

Drag the component to a new document, and open the Component Inspector. You will see the custom panel up and running!

One last thing to do is to add the fonts embeded in the movie. An easy way to do it is to create empty dynamic text fields on the stage and adding the characters to embed there. It’s important to create one per style we need like (regular, bold,…).

You can download the source files and a sample movie in Flash CS5 here.

In the next and last part of this tutorial we will add a live preview that will display the text in the Flash Authoring tool the same way it will be displayed once published.


Happy codding! :)

Related tutorials
Part 1
Part 3

Building ActionScript3 components in Flash CS5 (part 1)

October 3rd, 2011 | No Comments | Posted in ActionScript3

Components provides great advantages when we build our UI as they let you add functionality very quickly and ready to be used with components like Button, TextInput, ComboBox and so on.

Building our own components is a fantastic idea and it saves you a lot of time when you work on big projects that need the same functionality in different places over and over again.

I am going to show you how you can build a custom component not based on any standard component and it will have the following capabilities:

  • Display of a dynamic HTML text with CSS styling
  • Custom UI Panel
  • Live Preview

This component will give you a great overview about what you can do with components and how you can build your own.

This tutorial will consists of three parts being the same as the above list.

Ready? Let’s go!

The first thing we have to do is to give a name to our component. In this case I will name it as CSSLabel. Now go ahead and create a folder in your project workspace.

Next step is to create an ActionScript 3.0 document and save it in the folder as CSSLabel.

This component will be based on UIComponent class and therefore we will need to add to our source classpath an extra location. For doing that, open your ActionScript Settings and add a new entry to the Source path pointing to:

$(AppConfig)/Component Source/ActionScript 3.0/User Interface

Now we have to create an ActionScript class named CSSLabel in the same folder of our Flash document.

Go ahead and use the following content for the class:

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
package  {
    import fl.core.UIComponent;
    import flash.display.Sprite;
    import flash.text.AntiAliasType;
    import flash.text.StyleSheet;
    import flash.text.TextField;
    import flash.events.Event;
    import flash.utils.getQualifiedClassName;

    public class CSSLabel extends UIComponent {

        private var _textfield:TextField;
        private var _text:String;
        private var _styles:String;

        public function CSSLabel() {
            super();
            _text = "";
            _styles = "";
            addEventListener(Event.ENTER_FRAME, onEnterFrame);
        }

        override public function setSize(w:Number, h:Number):void {
            super.setSize(w, h);
            drawSquare();
        }

        private function drawSquare() {
            super.draw();

            graphics.clear();
            graphics.lineStyle(1,0x999999);
            graphics.beginFill(0x0000FF, 0);
            graphics.drawRect(0, 0, width, height);
            graphics.endFill();
        }

        private function onEnterFrame(e:Event):void {
            removeEventListener(e.type, onEnterFrame);

            var isLivePreview:Boolean = (parent != null && getQualifiedClassName(parent) == "fl.livepreview::LivePreviewParent");

            if (isLivePreview) {
                drawSquare();
            } else {
                graphics.clear();

                var styles:StyleSheet = new StyleSheet();
                styles.parseCSS(unescape(_styles));

                _textfield = new TextField();
                _textfield.width  = width;
                _textfield.height = height;
                _textfield.autoSize = "none";
                _textfield.wordWrap = true;
                _textfield.multiline = true;
                _textfield.antiAliasType = AntiAliasType.ADVANCED;
                _textfield.selectable = false;
                _textfield.embedFonts = false;
                _textfield.styleSheet = styles;
                _textfield.htmlText = csstext;

                addChild(_textfield);
            }
        }

        [Inspectable (name = "csstext", variable = "csstext", type = "String", defaultValue = "")]
        public function get csstext():String {
            return _text;
        }

        public function set csstext(value:String):void {
            _text = value;
        }

        [Inspectable (name = "styles", variable = "styles", type = "String", defaultValue = "")]
        public function get styles():String {
            return _styles;
        }

        public function set styles(value:String):void {
            _styles = value;
        }
    }
}

Let’s take a look at what we are doing in this class:

At the bottom of the class you can see a couple of component parameters that we expose to be able to add the text to display through csstext and the CSS styles through styles.

This first version of the component uses a basic preview that permits to manipulate the component easily in the Flash authoring tool. We will display a square that delimits the area for our text display. That is done with the method drawSquare.

With the overriden method setSize we can handle the redraw of the square to keep updated the area of the component.

Note that we are using the Event.ENTER_FRAME to create the content of the component. This is done this way to ensure that all the component parameters are available when we build the content.

The last thing to mention about this code is the use of the following code:

var isLivePreview:Boolean = (parent != null && getQualifiedClassName(parent) == “fl.livepreview::LivePreviewParent”);

With this code we can detect if the component is being rendered in the Flash authoring tool or by the Flash Player when we run the movie. We use this check to draw the square only when we are in the Flash tool.

Now we have all we need to install our component!

Open your CSSLabel Flash document and create a MovieClip called CSSLabel. Inside go ahead and create a solid rectangle shape. This step is very important as Flash will use the MovieClip to manipulate the component in the Stage. Use here the size you want for the default size of your component.

We are nearly there! Select the MovieClip in the library and open the Properties of the item. You have to select Export for ActionScript and the Class field will be filled automatically. If you followed all the steps correctly and click the check button, Flash will confirm the class is found.

CSSLabel Properties Panel

Now we need to open the Component Definition of the MovieClip and select the option Display in Components panel. In here you can add the name of your component and we also have the option to specify the minimum requirements to use it.

CSSLabel Component Definitions Panel

Everything is ready to install our new component now. Right click on the MovieClip in the library again and select the option Export SWC file. You will need to navigate to the folder like:

Windows:

C:UsersamendezAppDataLocalAdobeFlash CS5.5en_USConfigurationComponentsMyComponents

Mac:

/Users/amendez/Library/Application/Support/Adobe/Flash/CS5.5/en_US/Configuration/Components/MyComponents

The folder depends on your computer user name, the version of Adobe Flash you have installed and the language. The folder MyComponents will appear in the components panel and will help you to organize all the components you may have available.

If the installation is correct you won’t get any error and you can go ahead and refresh the components panel with the option Reload Components.

Now you can drag and drop your new component to a new Flash ActionScript 3.0 document.

We are going to add the following content to our component:

CSS:

1
2
3
4
5
6
7
8
.title {
    font-size: 24px;
    color:#FF9933;
}
.body {
    font-size: 14px;
    color:#666666;
}

TEXT:

1
2
3
<span class="title">CSSLabel Component example</span>
<br/><br/>
<span class="body">In this simple example we see the component in action displaying <b>HTML</b> text with <b>CSS</b> styles.</span>

Open the Properties Inspector panel with the component selected and you will see the two fields csstext and styles. As the fields are one line we will introduce the same but in one line format.

CSS:

.title { font-size: 24px; color:#FF9933; } .body { font-size: 14px; color:#666666; }

TEXT:

<span class=”title”>CSSLabel Component example</span><br/><br/><span class=”body”>In this simple example we see the component in action displaying <b>HTML</b> text with <b>CSS</b> styles.</span>

If you publish the movie you will see the following result:

You can download the source files and a sample movie in Flash CS5 here.

In the next part of this tutorial we will add a custom panel that will improve the way we add the component parameters to our component.


Stay tuned!

Related tutorials
Part 2
Part 3

Signals in AS3: simplicity and performance overview

July 15th, 2011 | No Comments | Posted in ActionScript3

For those who don’t know about Signals, it’s an open sorce project created by Robert Penner that give us a different approach when working with events in our projects. I have discovered it quite late but I wanted to try it and run some performance tests.
The simplicity and ease of use it’s the first thing we notice with Signals.
Let’s take a quick look at how we can use them.

A basic example comparison:

1
2
var dispatcher = new EventDispatcher();
dispatcher.dispatchEvent(new MyEvt(MyEvt.COMMAND));
1
2
var mySignal = new Signal();
signal.dispatch();

We see here that with Signals we don’t need an EventDispatcher or an event object. But now let’s see how to add the listeners:

1
2
3
4
5
dispatcher.addEventListener(MyEvt.COMMAND, onEventHandler);

function onEventHandler(e:Event):void {
// our handler code
}
1
2
3
4
5
mySignal.add(mySignalHandler);

function mySignalHandler():void {
// our handler code
}

If we need to send arguments with our Signal we can do it easily as in the following example:

1
2
3
4
5
6
7
var mySignal = new Signal(param1:String, param2:int);
mySignal.add(mySignalHandler);
signal.dispatch("test", 23);

function mySignalHandler(param1:String, param2:int):void {
// our handler code
}

Notice the parameters in the constructor. They are optional but it’s handy to use them as we will get an error in case the parameter types don’t match.

Signals provides a nice new method to register a listener but for a single use. As seen in the following example, we can listen for a Signal only once.

1
2
3
4
5
6
7
8
9
var mySignal = new Signal();
mySignal.addOnce(mySignalHandler);
signal.dispatch();
signal.dispatch();
signal.dispatch();

function mySignalHandler():void {
// our handler code
}

No matter how many Signals are dispatched, our listener will be called only for the first Signal. Nice one :)

Next we can see how we can remove listeners in the next comparison:

1
dispatcher.removeEventListener(MyEvt.COMMAND, onEventHandler);
1
mySignal.remove(mySignalHandler);

With Signals we can remove all the listeners at once:

1
mySignal.removeAll(mySignalHandler);

That will cover the basic Signals, but there is more advance things that we can do.

Imagine you want to receive the target of the Signal. In that case we have a new type of Signal called DeluxeSignal.

See below how it’s used:

1
2
3
4
5
6
7
8
9
var myDeluxeSignal = new DeluxeSignal(this);
myDeluxeSignal.add(myDeluxeSignalHandler);

myDeluxeSignal.dispatch(new GenericEvent());

function myDeluxeSignalHandler(e:GenericEvent): void {
// e.target
// e.signal
}

In the constructor we need to set the target and in the dispatch of the Signal we create a GenericEvent object that will be sent to the listener. Through it we will be able to retrive the target and the signal itself.

And finally, when we need to work with native events we find the last type of Signal called NativeSignal. This Signal needs an EventDispatcher in order to dispatch.

Following we can see a comparison for a mouse click event:

1
2
3
4
5
this.addEventListener(MouseEvent.CLICK, onClicked);

function onClicked(e:MouseEvent):void {
// our handler code
}
1
2
3
4
5
6
var clicked:NativeSignal = new NativeSignal(this, MouseEvent.CLICK, MouseEvent);
clicked.add(onClicked);

function onClicked(e:MouseEvent):void {
// our handler code
}

For this Signal we need to send to the constructor the target, the event type we want to broadcast and the event class. For listening this Signal is the same but we will receive the class we specified in the constructor.

As you see it’s simple and easy to work with it but now let’s take a look at the performance:

  • If we dispatch Events without listeners we get Signals are around 20-25% faster than Events.
  • If we dispatch DeluxeSignal instead (it’s closer to a regular event as we can get target and event) we notice Events are 60-65% faster than Signals.
  • If we dispatch events with listeners we get Events are around 10-15% faster than Signals and around 60% faster against DeluxeSignals.

This tests have been done with Flex 4.5.1 dispatching 1000000 events.

As far as I know Signals performed much better than Events, but it seems Events wins the battle so far.

It’s always good trying to find the balance and get the best performance to our projects. Sometimes it’s a combination of different approaches when we get the best results.

If you want to try Signals you can download the project here.


Happy coding!

Bit masking for flag parameters in AS3

June 14th, 2011 | No Comments | Posted in ActionScript3

Sometimes it’s pretty handy the use of bit operations in our daily projects. One of the situations where this solution is very useful is when we need a function that expects an undefined number of flag parameters.

Let’s have a look at the following example:

1
2
3
4
5
6
7
8
9
10
11
12
13
var MY_FIRST_FLAG:int  = 1;
var MY_SECOND_FLAG:int = 2;
var MY_THIRD_FLAG:int  = 4;
var MY_FORTH_FLAG:int  = 8;

function myFunction(flags:int):void {
  if (flags & MY_FIRST_FLAG)  trace("first flag enabled");
  if (flags & MY_SECOND_FLAG) trace("second flag enabled");
  if (flags & MY_THIRD_FLAG)  trace("third flag enabled");
  if (flags & MY_FORTH_FLAG)  trace("forth flag enabled");
}

myFunction(MY_FIRST_FLAG | MY_THIRD_FLAG);

The first thing to notice is how we create the flag values. We need a list of values that don’t overlap in binary. In order to do so we first need to understand how integer values are represented in binary. Following we can see the first four integer values:

1: 0001
2: 0010
3: 0011
4: 0100

What we need is that every bit represents a flag. The bit set as 1 will mean the flag is enabled when 0 will be the flag is disabled.

We cannot use all the integer values as the binary representation may overlap as the following example where value 3 overlaps with the combination of value 1 and value 2:

1: 0001
2: 0010
————
3: 0011

In order to avoid overlapping in binary we have to use a value that doubles the previous one every time. A list that suits that would be: 1, 2, 4, 8, 16, 32, 64, 128, 256 and so on.

Now let’s have a look at what the function does. We receive an integer parameter for the flags. We will need to apply the AND (&) bit operation that will fill with 1 the bit positions when there are two 1 and left 0 otherwise. What this means is that we will get the value of the flag integer after the AND bit operation if the bit mask is 1 or a value of 0 is the bit mask is 0.

See the following example to understand how the AND bit operation works:

1
2
3
4
5
0011 (example flags value)
&
0010 (flag MY_SECOND_FLAG)
------------
0010 (result different of 0: the bit of the flag is 1)

The final step is when we call the function. We will need to use the OR (|) bit operation to add the bit mask to our parameter. Let’s see how the OR bit operation works with an example:

1
2
3
4
5
0001 (flag MY_FIRST_FLAG)
|
0010 (flag MY_SECOND_FLAG)
------------
0011 (result with both bit masks as 1)

In our ActionScript example we send the flags MY_FIRST_FLAG and MY_THIRD_FLAG, and if we run the code we will get in the output the trace messages confirming that these two flags are enabled.

Bit operations can be quite confusing at first as we are not used to work too much with them, but we can simplify functions and make code much more clear avoiding lots of flag parameters in functions.


Happy coding!

Singleton Pattern in ActionScript 3

May 15th, 2011 | No Comments | Posted in ActionScript3

As AS3 does not support the use of private constructors, we have to use a workaround in order to implement the Singleton pattern.

We can find lots of different approaches on the Internet as for example the following:

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
  package  {
 
  public class SingletonClass {

    private static var _instance:SingletonClass;

    public function SingletonClass(enforcer:SingletonEnforcer) {
      if (enforcer == null) {
        throw new Error("SingletonClass is a Singleton class and must be accessed using getInstance()");
      }
    }
   
    public static function getInstance():SingletonClass {
      if (_instance == null) {
        _instance = new SingletonClass(new SingletonEnforcer());
      }
      return _instance;
    }
   
    public function testFunction():void {
      trace("test function");
    }
  }
}

class SingletonEnforcer {}

We use an intenal class called SingletonEnforcer in the constructor. The class is defined outside the package and it will be accessible only from the classes inside the .as file. This way we prevent the instantiation of our Singleton class without the use of the method getInstance().

The next approach is much more neat and looks like the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package  {
 
  public class SingletonClass {
   
    private static var _instance:SingletonClass = new SingletonClass();

    public function SingletonClass() {
      if (_instance) throw new Error("SingletonClass is a Singleton class and must be accessed using getInstance()");
    }
   
    public static function getInstance():SingletonClass {
      return _instance;
    }
   
    public function testFunction():void {
      trace("test function");
    }
  }
}

This implementation looks much better but creates an instance automatically, and sometimes we would prefer to have the class in memory only when we need it.

The last approach I think it’s the best from my point of view:

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
package  {
 
  public class SingletonClass {

    private static var _instance:SingletonClass;
    private static var _allowInstance:Boolean;

    public function SingletonClass() {
      if (!_allowInstance) throw new Error("SingletonClass is a Singleton class and must be accessed using getInstance()");
    }
   
    public static function getInstance():SingletonClass {
      if (_instance == null) {
        _allowInstance = true;
        _instance = new SingletonClass();
        _allowInstance = false;
      }
      return _instance;
    }
   
    public function testFunction():void {
      trace("test function");
    }
  }
}

As I said before, there are multiple ways of implementing this design pattern. In an ideal world we will be able to use private constructors in ActionScript, but meanwhile this happens we can use our customized Singleton classes in AS3!


Cheers.

BlendMode.LAYER, alpha and overlapping child DisplayObjects

May 10th, 2011 | No Comments | Posted in ActionScript3

We need lots of times to change the alpha property of a DisplayObject in our projects. Almost all the times we will be happy with the effect, but we can come across with an unexpected result.

If we apply for instance alpha to a MovieClip that contains overlapping MovieClips, we will see that the container MovieClip will be displayed with an unpleasant effect.

What happens is that Flash Player applies alpha to every child MovieClip inside it’s parent independently.

In order to solve this problem, we can use BlendMode.LAYER that tells Flash Player to apply alpha to a DisplayObject as only one layer getting the result we may need.

You can give it a try and notice the differences with the following example:

This movie requires Flash Player 9
.
Considering our container MovieClip is called myMc, we need the following ActionScript in order to enable this mode:

1
  myMc.blendMode = BlendMode.LAYER;

There are more interesting values in the BlendMode class. You can check them out in the Adobe Flash online documentation clicking here.


Happy coding!