Saturday, February 07, 2009

ActionScript 2.0 to ActionScrip3.0 Migration

Livedocs


The following table describes the differences between ActionScript 2.0 and 3.0.
http://livedocs.adobe.com/flex/201/langref/index.html?migration.html&all-classes.html

Conversion Tool

PHP
A great PHP set of class and stand alone windows exe will do few automated translation for you.

Features include:

* Updates createTextField to new TextField() syntax. Sets x, y, width and height if they are not the default (0). Uses addChildAt unless getNextHighestDepth() is used for argument 2, in which case addChild is used. Parses the first parameter and uses it as the variable name unless it is not a simple string, in which case a temp name is used, and the original name is shown in a comment on top of the block. Pretty sweet.
* Updates getURL to new URLRequest syntax. Works as above.
* Updates var, function and class to public var, public function and public class to remove warnings as requested by my childhood hero Robert Penner. Parses the class to recognize block depth to not affect local vars and inline functions.
* Smarter class and package name recognition.
* Removes unnecessary imports in the same package as the current class.
* Should properly recognize various line endings (crossing fingers).

The zip now includes a command-line executable called convertas2as3 for those Windows users who don’t feel like installing PHP. The zip is pretty big because it includes the php libraries for Windows users. On other platforms you can run the command-line utility in src/convert.php by typing php convert.php at the command line.

Try it here, download it here


JAVA
A Java JAR package and command line batch available here
http://jobemakar.blogspot.com/2007/05/convert-actionscript-2-to-actionscript.html
It automatically creates the package syntax, converts Void to void, recursively walks subdirectories, and outputs to a new location. In addition to those things it allows you to use two simple but powerful tags to do custom replacement of specific lines of code during upconversion. For instance:
//@replace var numShots:int = 10;
var numShots:Number = 10;

comes out as:
var numShots:int = 10;

Installation/usage instructions are included in the zip.
http://www.electrotank.com/junk/jobe/AS2_to_AS3.zip


SOME BASIC AS2 TO AS3 CONVERSION SAMPLE

Color
Old version:

First up, the old setRGB method of the legacy Color class.In the old days of ActionScript 1.0 and 2.0, you would create a Color object with a movieclip instance as an argument in the constructor, then apply the setRGB method on this Color instance. It was a bit weird, as you never really directly “talked to” the MovieClip whose colour you wanted to change.

var col:Color = new Color(some_mc);
col.setRGB(0x123456);

New Code

This has changed with AS3. The Color class is something else entirely, and in its place as a colour manipulator, we have this: ColorTransform.

import flash.geom.ColorTransform;
import flash.geom.ColorTransform;// create a new ColorTransform object
var colTrans:ColorTransform = new ColorTransform();
colTrans.color = 0xFF9900;
colTrans.alphaMultiplier = 0;
some_mc.transform.colorTransform = colTrans;

So this would set the colour of the object, but also set its alpha to 0.

Movie Clip Loader

Old Code

this.mcPreview.alpha = 0;
this.mcPreview.mcLoader = new MovieClipLoader();
this.mcPreview.mcLoaderListener = new Object();
this.mcPreview.mcLoaderListener.onLoadInit = Proxy.create(this, previewImageLoaded);
this.mcPreview.mcLoader.addListener(this.mcPreview.mcLoaderListener);
this.mcPreview.mcLoader.loadClip(pPath, this.mcPreview);

public class Proxy
{
public static function create(oTarget : Object, fFunction : Function,... arguments) : Function
{
/* Create an array of the extra parameters passed to the method. Loop
through every element of the arguments array starting with index 2,
and add the element to the aParameters array.*/
var aParameters : Array = new Array();
for(var i : Number = 2;i < arguments.length; i++)
{
aParameters[i - 2] = arguments[i];
}

// Create a new function that will be the proxy function.
var fProxy : Function = function():void
{
/* The actual parameters to pass along to the method called by proxy
should be a concatenation of the arguments array of this function
and the aParameters array.*/
var aActualParameters : Array = arguments.concat(aParameters);

/* When the proxy function is called, use the apply( ) method to call
the method that is supposed to get called by proxy. The apply( )
method allows you to specify a different scope (oTarget) and pass
the parameters as an array.*/

fFunction.apply(oTarget, aActualParameters);
};

// Return the proxy function.
return fProxy;
}
}
}
addChild(loader);

New Code

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

var url:String = http://www.yourfullyqualidieddomain.com/yourswftoload.swf?cachebusters='+new Date().getTime();
var loader:Loader=new Loader();
loader.contentLoaderInfo.addEventListener(Event.OPEN,loadinit); loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS,loading);
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,completes);
loader.load(new URLRequest(url));




TWEEN

OLD CODE

the migration of onMotionFinished an event triggered on completion of the old mx.transitions.Tween class. There is a new class:TweenEvent (fl.transitions.TweenEvent) It looked like this in AS2:

import mx.transitions.Tween;
import mx.transitions.easing.Regular;

class SlidingClass extends MovieClip {var xTween:Tween
// class constructor etc. not shown
function slideTo(xTarget:Number, frames:Number, callbackObj:Object, callbackFunc:Function) : Void {
xTween = new Tween (this, "_x", Regular.easeOut, this._x, xTarget, frames, false)
xTween.onMotionFinished = function() {callbackFunc.call(callbackObj);
};};


New Code

no need to pass the target object anymore - that is inherent in the function argument:

import fl.transitions.Tween;
import fl.transitions.TweenEvent;
import fl.transitions.easing.Regular;
var xTween:Tween;

function slideTo(xTarget:Number, frames:Number, func:Function) {
xTween = new Tween(this, "x", Regular.easeOut, this.x, xTarget, frames, false);
xTween.addEventListener(TweenEvent.MOTION_FINISH, func);};


Because of AS3 Event handling, a reference to the Tween is automatically passed to the target function as an Event datatype, via the “target” property.


OnPress

//code in AS 2
cornerplus1.onPress = function () {

startDrag(this);

}


Warning: 1090: Migration issue: The onPress event handler is not triggered automatically by Flash Player at run time in ActionScript 3.0. You must first register this handler for the event using addEventListener ( 'mouseDown', callback_handler).

NEW

// in AS 3 becomes

cornerplus1.addEventListener(MouseEvent.MOUSE_DOWN, dragFn);
function dragFn(event:MouseEvent){
event.target.startDrag();
};


LoadVars


OLD

var msg:LoadVars = new LoadVars();
var msgSent:LoadVars = new LoadVars();
msg.var1 = "one";
msg.var2 = "two";
msgSent.onLoad = function($success:Boolean):Void
{
if ($success)
{
trace("Message sent.");
}
else
{
trace("Message failed.");
}
};
msg.sendAndLoad("http://www.yourfullyqualifieddomain.com/script.php", msgSent);

NEW

var scriptRequest:URLRequest = new URLRequest("http://www.yourfullyqualifieddomain.com/script.php");

var scriptLoader:URLLoader = new URLLoader();
var scriptVars:URLVariables = new URLVariables();
scriptLoader.addEventListener(Event.COMPLETE, handleLoadSuccessful);
scriptLoader.addEventListener(IOErrorEvent.IO_ERROR, handleLoadError);
scriptVars.var1 = "one";
scriptVars.var2 = "two";
scriptRequest.method = URLRequestMethod.POST;
scriptRequest.data = scriptVars;
scriptLoader.load(scriptRequest);
function handleLoadSuccessful($evt:Event):void
{
trace("Message sent.");
}
function handleLoadError($evt:IOErrorEvent):void
{
trace("Message failed.");
}

http://www.yourfullyqualifieddomain.com/script.php?var1=one&var2=two


MovieClip

Creating new instances of a class has been greatly simplified in ActionScript 3.0. In previous versions of ActionScript, you needed to call createEmptyMovieClip() or createTextField() if you wanted to create a new MovieClip or TextField. Now, in ActionScript 3.0, you can simply call new MovieClip() or new TextField() directly, as shown in the following examples:

OLD

// AS2
this.createEmptyMovieClip("mc", this.getNextHighestDepth());
mc.beginFill(0xFF0000);
mc.moveTo(0, 0);
mc.lineTo(100, 0);
mc.lineTo(100, 80);
mc.lineTo(0, 80);
mc.lineTo(0, 0);
mc.endFill();
mc._x = 80;
mc._y = 60;

The previous code creates a new movie clip instance, draws a red rectangle which is 100x80 pixels, and moves the instance to 80,60 on the Stage. Compare that to the following code which does the exact same thing, although using the new drawRect() method instead of having to use the moveTo() and lineTo() methods:

NEW

// AS3
var mc:MovieClip = new MovieClip();
mc.graphics.beginFill(0xFF0000);
mc.graphics.drawRect(0, 0, 100, 80);
mc.graphics.endFill();
mc.x = 80;
mc.y = 60;
addChild(mc);

MovieClip

OLD

ReferenceError: Error #1056: Caused by Declaring Stage Instances Private
If you declare a stage instance private you get the message: "ReferenceError #1056 Cannot create property my_mc on StageIntanceDeclarationsClass"

This error occurs when you uncheck the "Declare Stage Instances Automatically" checkbox in the "ActionScript 3.0 Settings" dialogbox and proceed to declare stage instances as private variables in the class associated with the containing MovieClip.

A Note on Inheritances and Declaring Stage Instances:
You cannot choose to simply always declare stage instances automatically without forcing the use of inheritance in classes linked to MovieClip Symbols. If you have a class APrime which is derived from class A and APrime is linked to a MovieClip Symbol, all stage instances used in the base class A must be manually declared in class A. "Declare Stage Instances Automatically" only declares instances in the class linked to the MovieClip Symbol and does NOT make those references available to any base classes.

Example:
Assume that the class StageIntanceDeclarations is set as the class associated with a MovieClip which c0ntains the MovieClip my_mc. Then the following code will cause ReferenceError #1056 at runtime.



package
{
import flash.display.MovieClip;
public class StageIntanceDeclarations extends MovieClip
{
//Private Causes ReferenceError #1056
private var my_mc:MovieClip;
function StageIntanceDeclarations()
{
}
}
}



The output is as follows:
ReferenceError: Error #1056: Cannot create property my_mc on StageIntanceDeclarations.
at flash.display::Sprite/flash.display:Sprite::constructChildren()
at flash.display::Sprite$iinit()
at flash.display::MovieClip$iinit()
at TestStageIntanceDeclarationsBase$iinit()
at flash.display::Sprite/flash.display:Sprite::constructChildren()
at flash.display::Sprite$iinit()
at flash.display::MovieClip$iinit()

NEW

To avoid this error simply declare my_mc as public:
public var my_mc:MovieClip;


XML

OLD
NEW

undefined null Nan

OLD
NEW

No comments: