Accessing Classes
Toplevel Flash classes have been moved in the "flash" package, in order to separate Flash-specific classes from Javascript or Server-specific ones. To use these toplevel classes in Haxe, you need to use an import statement, or preface their names with "flash."
Note: There are some Flash 8 classes which you should already be used to referencing this way (e.g. flash.display.BitmapData).
Here are the classes that you will have to import to use.
flash.Accessibility; flash.Camera; flash.Color; flash.Key; flash.LoadVars; flash.LocalConnection; flash.Microphone; flash.Mouse; flash.MovieClip; flash.MovieClipLoader; flash.PrintJob; flash.Selection; flash.SharedObject; flash.Sound; flash.Stage; flash.System; flash.TextField; flash.TextFormat; flash.TextSnapshot; flash.Video; flash.system.Capabilities; //note the capitalization flash.system.Security; //note the capitalization
Flash Types
The following Flash types are slightly different in Haxe.
- Array
- Boolean
- Function
- Number
- Object
Array
Arrays are strictly typed in Haxe. You need to specify the type of the array content by using < and >.
//ActionScript var a:Array=["a","b","c"];
//haxe var a:Array<String>=["a","b","c"];
Boolean
Booleans are implemented in Haxe with an enum called Bool.
//ActionScript var b:Boolean=true;
//Haxe var b:Bool=true;
Booleans are not objects in Haxe, they are abstract values.
Function
There is no function class, but there is a function type, which Haxe will infer for you.
//ActionScript var fun:Function = function (){ ... }
//Haxe var fun = function (){ ... }
You can also specify the function type explicitly :
var fun : Void -> Bool = function() { return false; }
Number
Numbers in Haxe are either Float (decimal point numbers) or Int (integers).
//ActionScript var i:Number=42; var j:Number=1.618034;
//Haxe var i:Int=42; var j:Float=1.618034;
Int and Float types are compiled to the more suitable primitive types depending on the plaform. Do not assume that they are objects.
Object
In Haxe, use Dynamic instead of Object when you want to signify that a variable can be of any type.
//ActionScript var obj1:Object=7; var obj2:Object="a string";
//Haxe var obj1:Dynamic=7; var obj2:Dynamic="a string";
Dynamic is actually like the ActionScript2 "untyped" variable. You can use it in any way you want.
Expressions
Some expressions have differences between ActionScript and Haxe.
In particular, control structures in ActionScript are statements, and do not return a value. In Haxe, control structures are expressions, and return the value of their last evaluated subexpression.
Control structures include: while, do while, switch, if, if else
break Statements
In Haxe, "break;" statements are not recognized inside switch statements, but are implied before each case/default statement.
This will prevent a very common error (leaving them out).
//ActionScript switch(val){ case val: doSomething(); break; default: doSomethingElse(); break; }
//Haxe switch(val){ case val: doSomething(); default: doSomethingElse(); }
(As a side effect, some more advanced uses of the switch statement will have to be restructured.)
for loops
The most common for loop has a simpler syntax in haxe.
//ActionScript for(var i=0;i<num;i++){ doSomething(); }
//Haxe for(i in 0...num){ //note: no var doSomething(); }
Other, less common for loops can be implemented using Iterators, or expanded to while loop syntax.
var i=0; while(i<num){ ... i++; }
for in loops
In Haxe, an array is iterable, meaning you can loop through its members directly with a for..in loop.
//ActionScript for(var i in arr){ //i is the index into arr doSomething(arr[i]); }
//Haxe for(x in arr){ //x is the next member of arr doSomething(x); }
To get the array indexes instead, use
arr.indexes
, or an int iterator.
//Haxe for(i in 0...arr.length) doSomethingTricky(arr[i],i*2+3);
By contrast, objects in Haxe are not iterable. So, while in ActionScript you can do this:
//ActionScript var obj:Object; ... for(var i in obj) trace("obj."+i+" is "+obj[i]);
In Haxe you would use a special class called Reflect to access the properties of a Dynamic object.
//Haxe var obj:Dynamic; ... for(i in Reflect.fields(obj)) trace("obj."+i+" is "+Reflect.field(obj,i));
A common use of 'for in' loops in AS2 is to find all the MovieClips in a MovieClip, this is not really a good approach and in Haxe you should keep a reference to any you create and store them in an array or similar, but obviously with any timeline MovieClips this does not help. So an alternative is to loop through all the depths.
//haxe var i: Int = _movie.getNextHighestDepth();// not supported in flash 6 var mc: Dynamic; while( --i != -16385 ) { mc = _movie.getInstanceAtDepth( i ); if( Std.is( mc, MovieClip ) ) { trace( cast( mc, MovieClip )._name ); } }
Properties
The Reflect Haxe class is used for all manipulation of dynamic properties. It's a complete Refection API (also called introspection).
String access
//ActionScript var prop:String="width"; if( obj[prop] == null ) { obj[prop]=100; trace(obj[prop]); }
//Haxe var prop:String="width"; if(Reflect.hasField(obj,prop)){ Reflect.setField(obj,prop,100); trace(Reflect.field(obj,prop)); }
If the field is not found in Reflect.field
, an exception will be thrown.
Delete
//ActionScript var prop:String="width"; delete obj[prop];
//Haxe var prop:String="width"; Reflect.deleteField(obj,prop);
arguments
In ActionScript you can use the arguments object in functions to accept optional arguments, and access a reference to the current function, or the calling function.
//ActionScript var arr:Array=arguments; var fun1:Function=arguments.callee; var fun2:Function=arguments.caller;
Haxe provides a way to access these properties, but their use is not recommended since they are only available for Flash. See Haxe Magic
untyped{ arr=__arguments__; fun=__arguments__.callee; fun=__arguments__.caller; num=__arguments__.length; }
Please note that Haxe can declare functions with Optional Typed Arguments.
Classes and Instances
packages
In ActionScript, you designate the package of a class in the class definition.
class pkg.ClassName { }
Haxe handles packages more like Java does, with a package declaration that applies to the file as a whole.
package pkg; class ClassName { }
See Packages and Imports
constructors
In ActionScript constructors have the same name as the class.
class Something{ function Something(){ } }
In Haxe the constructor is always given the name 'new'. This way if you rename your class you don't have to rename the constructor.
class Something{ function new(){ } }
naming
In ActionScript it is standard practices to begin class names with uppercase letters, and parts of the package name with lowercase letters. In Haxe this standard is enforced by the compiler.
//unusually styled ActionScript class pkg.ClassName { }
//Haxe package pkg; class ClassName { }
prototype, etc.
ActionScript provides the prototype and constructor properties for inspecting class definitions and hierarchy.
obj.__proto__; obj.prototype; obj.constructor;
In Haxe you can use the Reflect API to get the object Class :
var c : Class = Reflect.getClass(obj); trace(c.__name__); trace(c.prototype); ...
This doesn't work with native/extern classes such as Array or flash.MovieClip for example.
instanceof and casting
//ActionScript if(obj instanceof MovieClip){ var mc:MovieClip= MovieClip(obj); }
//Haxe if(Std.is(obj, MovieClip)){ var mc:MovieClip= cast(obj,MovieClip); }
NOTE: Also, when inspecting primitive types, Haxe's instanceof behaves more the way you would expect than ActionScript's instanceof.
//ActionScript trace(("hello") instanceof String); //false trace((true) instanceof Boolean); //false trace((5) instanceof Number); //false
//Haxe trace(Std.is("hello", String)); //true trace(Std.is(true, Bool)); //true trace(Std.is(5, Int)); //true trace(Std.is(5, Float)); //true trace(Std.is(5.1, Int)); //false
Flash TopLevel
Some ActionScript things you may be wondering how to find in Haxe...
_root
//ActionScript _level0;/*the global root*/ _root; /*the global root, or in a loadMovie() swf, the local root (if the loaded swf sets _lockroot=true) */
//Haxe flash.Lib._root;/*the global root (_level0)*/ flash.Lib.current;/*the root of the current swf (even in loadMovie() swfs)*/
_global
In Haxe, you can access the _global object as flash.Lib._global.
//Haxe flash.Lib._global;
These functions are used for integrating swfs into macromedia authoring environments, they are stored inside _global :
//ActionScript FWEndCommand() FWJavascript() MMEndCommand() MMExecute() MMSave() profile() //Macromedia Flex Debug Tool
others
There is no top-level functions in Haxe, so all ActionScript toplevel functions are stored in objects API, see Std and Lib where most of these functions are available.
For trace
, Haxe adds more information and displays the result on the screen. You can use Flash old trace instead, accessible throughflash.Lib.trace
.
Other changes :
escape //Haxe: StringTools.urlEncode unescape //Haxe: StringTools.urlDecode getVersion(); //Haxe: system.Capabilities.version
Haxe does not plan to provide equivalents for these functions:
nextScene(); prevScene(); loadMovieNum(); loadVariablesNum(); printAsBitmap(); printNum(); printNumAsBitmap();
Flash API
Most of the methods and properties of the Flash classes are exactly the same in Haxe. However, there are a few things that are different, either because the rules of the Haxe language required a change (for example, capitalizing the Capabilities object), or because Haxe adopted an API that can be used across platforms (for example, the Xml class instead of XMLNode).
Array Class
(coming soon)
Button Class
//ActionScript var btn:Button;
//Haxe var btn:MovieClip;
You don't need buttons anymore. How long have you been coding?
Date Class
(coming soon)
Function Class
The Function object's call() and apply() are replaced in Haxe by Reflect.callMethod
//ActionScript func.apply(scopeObj,[arg1,arg2,arg3]);
//Haxe Reflect.callMethod(scopeObj,func,[arg1,arg2,arg3]);
Math Class
Some properties of the Math class have no Haxe equivalents yet.
//ActionScript Math.E; Math.LN10; Math.LN2; Math.LOG10E; Math.LOG2E; Math.SQRT1_2; Math.SQRT2;
PI is available.
Number Class
Equivalents to some usages :
Number.NaN; // Haxe: Math.NaN Number.NEGATIVE_INFINITY; // Haxe : Math.NEGATIVE_INFINITY Number.POSITIVE_INFINITY; // Haxe : Math.POSITIVE_INFINITY num=Number(val); // Haxe : Std.parseInt or Std.parseFloat
Some properties of the Number class have no Haxe equivalents yet.
//ActionScript Number.MAX_VALUE; Number.MIN_VALUE; num.toString(2);// binary num.toString(36);// base 36
Object Class
Instead of Object.registerClass, you can use flash.Lib.registerClass.
The following methods of Object are not yet available in Haxe.
//ActionScript obj.unwatch(); obj.watch(); obj.addProperty();
String Class
Because the String class is the same for all Haxe platforms, there are a few differences from the ActionScript String class.
//ActionScript var str:String = String(val); str.slice(0,4);
//Haxe var str:String = Std.string(val); //str.slice(0,4); //use substr or substring instead
XML Class
The Haxe Xml class replaces ActionScript's XMLNode class, and is available for all 3 Haxe platforms. This follow the W3C DOM recommendation.
//ActionScript var xml:XML = new XML("<tag attr='val'></tag>"); var node:XMLNode = xml.childNodes[0]; trace(node.attributes.attr);
//Haxe var xml:Xml = Xml.parse("<tag attr='val'></tag>"); var node:Xml = xml.firstChild(); trace(node.get("attr"));
To load external text/xml files in Haxe you must use LoadVars to get a raw string, and
Xml.parse
to parse it.
//Haxe var lv=new flash.LoadVars(); lv.onData=function(str:String){ var node:Xml=Xml.parse(str); } lv.load('file.xml');