If you are in a hurry, skip to Gotchas.
There are a variety of reasons to still use AS2. Some of the more realistic are:
- Supporting legacy content
- Awaiting a larger corporation to sign off on AS3 development
- Having to work with a client-side API written in AS2 by a third party
Even with “as3” and “es” set to false when using the mxmlc compiler, you still aren’t capable of using Flex Builder 2 or 3 as a serious solution to doing ActionScript 2 development. Furthermore, Flash the IDE (CS3 in this case) isn’t a serious development environment either. While Flash CS3 did add some minor code editing features, it’s pretty clear form that release that Adobe has no intention of improving AS2 development in Flash.
If you are maintaining a sizable code base, or simply converting it, whether to support a 3rd party API or merely to keep your sanity, having a good tool and some advice on how to quickly get past the gotchas can really make a difference.
AS2 really jump started the open source industry for Flash. There are a plethora of options out there. Unfortunately, when this industry was ramping up, I jumped ship to Flex. You can investigate yourself over at OSFlash.org. I have no clue what is good for Mac, however…
…for PC, I recommend FlashDevelop. No, not FDT (Flash Develop Tool), just FD. If you see a forum, you know you’ve reached the right place. That’s correct, it doesn’t even have a proper web page. I use Google to actually find the download page on their site for the software ( flashdevelop download site:flashdevelop.org ) It’s just that good. Steven Sacks took me through a Breezo of this program almost a year and a half ago. It’s written in .NET (but suggests Java 1.6???), hence, I lug both my Mac AND my 14.5 lb PC laptop to work JUST so I can use that one piece of software. That’s right, a $2,600 former gaming laptop just to use an a piece of open source software. I say again, it’s just that good. Speaking of Alienware, they like DoubleClick, can go diaf together. Anyway, imagine Flex Builder, only for AS2. Code hinting, code completion, etc. Yes, for your own classes, not just Adobe’s.
I’ve converted to mostly Mac for full time Flex & Flash Development. However, I own a copy of CrossOver to use just one piece of software: BeyondCompare. This works just as well for AS2 as it does for AS3. It’s code diffing software, and I use it to sync my local copy with Subversion’s.
While you technically only need Flash MX 2004, Flash 8 runs more predictably, and Flash CS3 has both 8’s stability, with some minor compiler & code editing changes that make it bearable to be in the 5 minutes of your day you just have to use it instead of FlashDevelop. If you can get a copy, do so. Keep in mind, if you wish to use Flash Player 8’s new Garbage Collector and filters, you’ll need Flash 8, and if you wish to compile to Flash Player 9 for use of full screen functionality, you’ll need Flash CS3.
If you are maintaining a Flex 1.5 code base, my heart goes out to you. In a box. Stabbed with a rusty knife. Send the box to your boss, maybe he’ll fire you, and you won’t have to maintain a Flex 1.5 code base.
This assumes pure AS, and doesn’t take into account components.
If you are converting from AS3 to AS2, do a find and replace on the following:
- void to Void
- int and uint to Number
- const to var
- :* to :Object
- protected to private
- remove all “override”
- public class to class
- :Shape to :MovieClip
- someMovieClip.graphics to someMovieClip
- remove :void from constructors since in AS2 they cannot return a value
I haven’t found an easy way to manage converting your package path back to prefixing on the class name, so have been doing this as well as deleting unsupported imports by hand.
If you use the Graphics.drawRect, you’ll have to write a wrapper function that emulates what it does. There is some good AS1 code on Adobe’s site to write a quick Utility class for drawing.
Your creation methods and addChild/removeChild is really where a lot of your work is. Converting them to attachMovie factory method is correct, however, making a method that checks for types is a little better to at least ensure your variable casting is good to go. Know, however, that MTASC in FlashDevelop, and the Flash IDE expect different things in different places. Casting in AS2 doesn’t always work, nor is it always consistent like AS3. You don’t have the as keyword, and as such, you can only cast to things that don’t have constructors that do magical things, like Array that actually makes an array vs. casting to an Array.
If you want addChild/removeChild features, use _visible = false, _visible = true instead.
Watch your default values with magic numbers. Changing your scaleX to _xscale is not enough; remember, it’s:
AS3: scaleX = 1
AS2: _xscale = 100
Big difference. Same goes for alpha values.
While try / catch blocks are supported, they do something uncool in my opinion. In Flash Player 9 using AS3, you get an exception window in the debug player. In AS2, you do not. You’re code magically stops and you have no idea where. All exceptions are usually automatically caught and handled internally in AS2 and below, so if you check a null value, the next line of code is still run, and your app goes on it’s merry, albeit wrong state of mind, way. This made bug hunting in AS3 a lot easier than in AS2. It also made try catches actually useful vs. something to make the Java devs feel comfortable in ActionScript. However, try catch blocks in Flash Player 8 and below actually abort ALL code in the stack; this can be viewed as a good or bad thing. Good because if nothing happens, you can blame it on a try catch block. Bad in that it can be really hard to see the ramifications of the bad code. This makes it really hard to debug other parts of your application using breakpoints in the Flash IDE because if the try catch aborts a stack that would of caused your other code to run, you’ll never get there.
Interfaces do not work very well in ActionScript 2. Furthermore, you cannot have getter / setters in an AS2 interface. While extending works, the implementations can be really tricky. If you spend more than hour fighting your code to accept the interface, go with convention, and just trash the interface… or use a psuedo base class. If you can’t use a base class, use a mixin (a class/function that adds methods to a Class’s prototype at runtime or simply just decorates an instance).
A note about using mixin methods; those too also don’t always work with interfaces. For example, this:
function removeEventListener(target:String, listener:Object):Void;
In your interface doesn’t think this is a valid implementation:
public var removeEventListener:Function;
While it’s technically correct, what it doesn’t know is that at runtime, with the mixin, it WILL be. There is where tools & languages haven’t matured enough to support prototype classes. Therefore, just re-define the method the correct way to match the signature, but don’t have it do anything. Yes, it uses slightly more RAM and resources, but oh well.
Don’t expect your initialization order to be correct in static methods. Meaning, if ClassB uses ClassA, one would expect the compiler to see that, and initialize ClassA first, and then ClassB. This was a problem that surfaced in Flash 5, was fixed via hardcoding the initialization order in Flash 6, and eventually done by the compiler in Flash 7. It doesn’t, however, work that great at least in some static methods that do class constructing things while the application is initialized. You may be able to hack it by writing your own class initialization stuff inside a MovieClip with an #initclip 0, but in my quick test, like zee goggles, it do nothing.
If you don’t know what a Delegate is, don’t worry about it. Just change this:
something.addEventListener("eventName", mx.utils.Delegate.create(this, functionHandler));
Keep in mind the MTASC compiler uses a stricter set of rules (yes, even with strict mode turned off) and doesn’t work natively with the mx components unless you explicitly tell it to ignore them. FlashDevelop has GUI options for this vs. writing command line compiler options. The one thing that can cause issues is intrinsic files; files used to represent classes native to the Flash Player, but still needed for compile time checking. This are AS2 classes that have method & property signatures, but they don’t actually do anything. This can cause problems when they differ.
For example, NetConnection has a method called connect. Depending on what documentation you read, it can return different values. Flash Communication Server (now known as Flash Media Server) says it returns nothing; newer docs say Void, whereas MX 2004 says Boolean. The Flash AS2 compiler assumes Boolean as well, but MTASC’s intrinsic says Void. You’ll get this neat error message in FlashDevelop saying “Void should be Boolean”, yet it points the error being in the intrinsic. So, you can either edit the intrinsic, or just add that one particular file to an exclude list, and move on knowing it’ll compile just fine in Flash.
That’s all the major stuff. Good luck!