This website uses cookies to improve user experience. By using our website you consent to all cookies in accordance with our Cookie Policy. X

5 reasons why ActionScript2 is still useful

ActionScript3 is without a doubt more advanced language than ActionScript2 and each day more and more programmers move to work with it, however this doesn't mean ActionScript2 should stop existing - I mean, there must be a reason why Adobe haven't kill it yet. Here are 5 reasons why ActionScript2 can still be useful:

5. Easier to learn.
For people only just started their journey with Flash and have not decided yet about their language of choice, AS2 is a great introduction into programming. Not only does it avoid complex programming concepts (for example, type casting), it also does everything in its power to keep the application running.

4. Focused purpose.
With ActionScript3 you can achieve much more than with ActionScript2, but this in exchange requires more involvement from the programmer, sometimes even requiring knowledge outside of the standard documentation (Socket communication, hardware acceleration, 3D graphics). ActionScript does less, but usually it is enough.

3. In basic usage the speed is not a problem.
This has to be the most popular argument in the "AS2 vs AS3" debate, however the truth is, the fastest way to encumber the application is to use complex graphics, rather than the older code. If you aren't sure that you need the speed, chances are you don't.

2. The basic stuff requires less time to create.
Lets say we want to create a simple button that will open a desired website.
In ActionScript2 this will be enough:
on(press) {
	getURL("http://4as.pl");
}
ActionScript3 requires a bit more:
import flash.events.MouseEvent;
import flash.net.navigateToURL;
import flash.net.URLRequest;
buttonMode = true;
addEventListener(MouseEvent.CLICK,onMouseClick);
function onMouseClick(e:MouseEvent):void {
	navigateToURL(new URLRequest("http://4as.pl"));
}
And not to mention stuff like MovieClip duplication

1. Better compatibility
Often it is easy to forget that Flash isn't exclusive to the PCs - With ActionScript2 there is a bigger potential for wider audience, especially with mobile devices where working with newer versions of Flash Player might be a bit... troublesome.

But all in all ActionScript3 is without a doubt a superior language and is ‘a must’ if we are serious about programming in Flash, especially in more advanced topics like game design.

Communication between AS2 and AS3[basic]

As soon as ActionScript3 saw the light of the day Adobe instantly pointed out that the virtual machine behind it is completely different than the one used in AS2, which in turn means there is no direct way of communicating between those two languages. Right now someone might think that if that is the case, then there is no point in trying, topic closed. But wait a second, no direct connection doesn't equal to no possible connection at all. Let me put it this way: lets take MySQL for example, Flash doesn't come packed with any means to connect to it directly, yet it doesn't stop us anyway, thanks to PHP (or other methods). Which brings us to the heart of the matter: indirect connection. In case of AS3 and AS2 it is even simpler than using PHP, because both of them include a class for communication between local SWF files - LocalConnection is its name.
Main purpose of LocalConnection is to communicate between two Flash applications running on the same computer, however since its implementation did not change at all in AS3, we can also use it to establish a connection between AS2 and AS3.
Creating a LocalConnection is very easy and almost identical for both languages. For ActionScript2 it will be:
var connectionAS2:LocalConnection = new LocalConnection();
connectionAS2.connect("LocalConnectionTestAS2");
And for ActionScript3:
var connectionAS3:LocalConnection = new LocalConnection();
connectionAS3.client = this;
connectionAS3.connect("LocalConnectionTestAS3");
connectionAS3.addEventListener(StatusEvent.STATUS,onStatus);
function onStatus(e:Event):void { }
AS2 version is quite trivial, however AS3 one requires some explanation. First of all, the line that says connectionAS3.client = this; is very important as it points to object that will handle the incoming function calls, without it the application will simply not work. StatusEvent is added to the LocalConnection only to stop Flash from throwing any errors before the connection is established.
Oh and texts put into the connect() functions are different to allow for bidirectional communication.
Okay, now that we have AS2 and AS3 ready to exchange commands, it is time to create function that will send them. Also, to get a better feedback on the whole process we will include TextFields to display the information. For ActionScript3 it will be:
var tf:TextField = new TextField();
tf.text = "No Messages";
addChild(tf);

function messageFromAS2(msg:String,nx:Number,ny:Number):void {
	tf.text = msg+" "+nx+" "+ny;
	tf.x = nx;
	tf.y = ny;
}
While for ActionScript2 it will be:
this.createTextField("textMsg",this.getNextHighestDepth(),0,0,200,25);
var tf:TextField = this.textMsg;
tf.text = "No Messages";

connectionAS2.messageFromAS3 = function(msg:String,nx:Number,ny:Number):Void {
	tf.text = msg+" "+nx+" "+ny;
	tf._x = nx;
	tf._y = ny;
}
One last thing remaining now is to fire up those functions - Mouse Events will do the trick. For ActionScript3:
stage.addEventListener(MouseEvent.MOUSE_MOVE,onMove);
function onMove(e:MouseEvent):void {
	try {
		connectionAS3.send("LocalConnectionTestAS2","messageFromAS3","AS3 MouseEvent",e.stageX,e.stageY);
	} catch(e:Error) {
		return;
	}
}
For ActionScript2:
this.onMouseMove = function():Void {
	try {
		connectionAS2.send("LocalConnectionTestAS3","messageFromAS2","AS2 Mouse Event",_root._xmouse,_root._ymouse);
	} catch(e) {
		return;
	}
}
In both cases try-catch is used to stop Flash from throwing errors before the connection is established.
In action, the whole thing will look like this:
Source code: localcon.zip

By the way, if you ever find yourself in a situation where you need to access an AS2 file that does not support LocalConnections and can't be modified, I suggest creating a separate SWF file in ActionScript2, then loading (loadMovie() function) the target file to read all the necessary information and send them further down the line wherever you like using LocalConnection.

From AS2 to AS3: duplicateMovieClip() in ActionScript 3 [advanced]

Programmers that decide to switch to AS3 from AS2 will find sooner or later that the latest ActionScript iteration lacks duplicateMovieClip() function equivalent. It might seem odd, since it is hard to imagine Adobe having problems with implementation of such function. My guess is they are trying to kill wrong AS habits. In any case, sometimes you just have to duplicate a MovieClip and that is why I compiled a list of most common solutions:

1. Custom class.
I think around 90% of people looking for the duplicateMovieClip() alternative should find this solution sufficient. In brief: it is about creating a MovieClip's sub-class and then linking it graphics we want to duplicate. So for example, if we were to create an application with falling stars in the background we of course would start by creating a single MovieClip star and then copying it multiple times. To do this open the properties of that MovieClip star and in advanced settings check "Export for ActionScript".
Export for ActionScript
From now on "Star" class contains the star graphics and can be duplicated by writing:

var mc:MovieClip = new Star();
addChild(mc);
That is it.

2. Using the loadBytes() function within the Loader class.
Well sure, #1 method is pretty nice but what if we want to make copy of externally loaded file? In this case lets start by looking how to load the graphics from outside:

import flash.display.Loader;
import flash.events.Event;
import flash.net.URLRequest;

lLoad = new Loader();
lLoad.contentLoaderInfo.addEventListener(Event.COMPLETE,onLoaded);
lLoad.load(new URLRequest("your_file.swf"));

function onLoaded(e:Event):void {
	addChild(lLoad.content);
}
Okay, so at first glance Loader doesn’t seem to have that many functions we could use after loading an external SWF file - we could pretty much either unload it or load different file. The second options is out of the question (except if user has local caching enabled Flash will actually load the content from there rather than connecting to the server again) unless we use loadBytes(). The trick here is that loadBytes() can load any file-type supported by load() but does the reading from a ByteArray. The questions now is: where do we get that ByteArray of a loaded MovieClip from? The answer is actually very simple:
function onLoaded(e:Event):void {
	addChild(lLoad.content);
	lLoad.loadBytes(lLoad.content.loaderInfo.bytes);
}
The lLoad.content.loaderInfo.bytes property holds the loaded animation as ByteArray, so it is only a matter of putting it into the loadBytes() and then again catching the onLoaded event resulting in another MovieClip copy without actually establishing any outside connections.
However there is one problem, onLoaded event won't be called instantly... which means we will get our duplicated MovieClip only after few or more milliseconds (depends on FPS value).

3. Using the constructor property for objects loaded with Loader.
Alternative way to duplicate externally loaded SWF is by using the constructor property available for every object created in Flash. Lets just go ahead and see how it works:

function onLoaded(e:Event):void {
	var d:DisplayObject = new lLoad.content["constructor"]();
	addChild(d);
}
(Because constructor property is dynamic this is the only way to access it. Also, don't forget the keyword new!)
Unfortunately it is not a perfect solution. The code will work only when the loaded movie has a custom "Document Class" (it can be anything as long as "Document Class" is not empty), which basically means you have to be the author of the target file.

To save some work in future I've implemented all those solution into a single class - should have no problem with duplication of any MovieClips (and not only): foras_clone.zip
It is used in the following way:

import foras.utils.ForCloner;
import flash.display.DisplayObject;
if(stage==null) return;
var fas_Clone:ForCloner = new ForCloner();
var d:DisplayObject = fas_Clone.cloneMovie(my_mc,onClone);
if(d!=null) {
	d.x = stage.stageWidth*Math.random();
	d.y = stage.stageHeight*Math.random();
	addChild(d);
}

function onClone(d:DisplayObject):void {
	d.x = stage.stageWidth*Math.random();
	d.y = stage.stageHeight*Math.random();
	addChild(d);
}
Because ForCloner class uses the loadBytes() method (mentioned as second solution on the list) cloneMovie() requires a callback function to take over the duplicated MovieClip. Of course it is entirely possible it won't be need and cloneMovie will instantly return a copy. However in most cases it will result in the null value, which is where the callback function is used (onClone in the example above) - it will be given the copy of target MovieClip.
One last thing, if(stage==null) return; line stops the code for executing twice - if everything else fails whole application will be duplicated along with its source code (but at the end only target MovieClip will remain, everything else is deleted).

From AS2 to AS3: _global equivalent in AS3 [basic]

I once was asked is there a way to access variables that were set on _root or _global. The problem comes from how strict the ActionScript3 is - in AS2 you would just write _global.myVar = 5 and then access it from anywhere, but AS3 just doesn't tolerate dynamic variables (and also there is no _global keyword).
There are two ways to work around it:

1. Use syntax meant for dynamic variables.

root["myVar"] = 5;
It is almost the same thing as in AS2, but since you are using dynamic variables you might find yourself with an extremely slow application (when used excessively). If that is the case you should consider the second option.

2. Use static keyword.
This is probably the most proper way to do it, but requires some additional work. Before you do anything create a "Document Class", which you will find in the properties tab.

Type in any name you want for you class (e.g. "MyClass"), confirm it with enter key (at this point a warning should pop-up saying the class doesn't exist - ignore it) and then click the pencil icon on the side.
If done correctly, new class file should be created in a separate window looking something like this:

package  {
	import flash.display.MovieClip;
	
	public class MyClass extends MovieClip {
		
		public function MyClass() {
			// constructor code
		}
	}
	
}
Now just before the public function MyClass() line, type in:
public static var myVar:Number = 5;
That is pretty much it. From anywhere in your project you can now access this variable through class identifier, for example:
import MyClass;
trace(MyClass.myVar);
Also, since you document class is used as "root" object, you can now access it through root field of each MovieClip. It needs to be casted to your class beforehand though:
import MyClass;
trace((root as MyClass).myVar);