Usando Haxe com Flash 9
Você pode usar a linguagem Haxe e construir SWF para Flash 9. Para fazer isso, simplesmente compile usando -swf-version 9 e o compilador Haxe irá gerar um SWF compatível com o Flash Player 9.
Exemplo - Test.hx:
class Test { static function main() { // cria um TextField var tf = new flash.text.TextField(); tf.text = "Hello World !"; // adiciona ele a lista de exibição flash.Lib.current.addChild(tf); } }
Compile usando o seguinte arquivo HXML - compile.hxml :
-main Test -swf-version 9 -swf test.swf
When you compile a project for Flash9, you will have to use the new ActionScript3/Flash9 API instead of the old ActionScript2/Flash8 ones. You can find these described in the Haxe API (click on flash9 to unroll the menu). This API is exactly the same as that available from AS3 and it contains additional undocumented methods.
This API is documented on the Adobe livedocs
Although there might be some bugs left, the Haxe Flash9 code generator is working correctly and in some cases generates faster code than the official Flex compiler. Try it yourself and report your findings on the Haxe mailing list.
You can add debug information to your Flash9 swf by compiling with -debug. This will enable you to see Haxe source file names and line numbers when a runtime exception occurs.
Using the Library
If you have graphical resources that were created by the Flash IDE (either MX 2004 or CS3) or SwfMill, you can use them from your Flash9 code by doing the following :
- with Flash MX / SwfMill : use an Identifier (linkage name) for your resource, as you would do normally for an
attachMovie - with Flash CS3 : use a AS3 class name as you would normally do for AS3
- statically link your library in your output SWF by using
-swf-lib
Attaching By-Name
Haxe will automatically create a Flash9 class for MovieClips that have a linkage name, if there is not already one available. You can then directly use flash.Lib.attach("myname") that will create an instance of this movieclip. For example :
class Test { static function main() { var s = flash.Lib.attach("Shape"); flash.Lib.current.addChild(s); } }
This assumes that you have a clip with either a linkage or a class name "Shape".
In case one of your graphics is a linkage identifier but no class is defined, you can catch the exception thrown by flash.Lib.attach or by using the Flash9 Debug Player.
Class binding
If on the other hand you want to redefine/extend the behavior of the MovieClip, then you can simply define a class in Haxe with the same name :
// Test.hx class Shape extends flash.display.MovieClip { public function move() { x += 2; y += 2; } } class Test { static function main() { var s = new Shape(); flash.Lib.current.addChild(s); s.move(); } }
Compile it using the following HXML :
-main Test -swf-lib lib.swf -swf-version 9 -swf test.swf
This will create a SWF that will, once opened, display the graphics named Shape and move it a little bit. In the case one of your graphics is a linkage identifier but no class is defined, the Flash Debug Player 9 should give you an error when loading it.
Embedding a font
If you want to embed a font, make a resource.xml file like this:
<?xml version="1.0" encoding="iso-8859-1" ?>
<movie version="9">
<background color="#555555"/>
<frame>
<library>
<font name="Symbols" import="font/dejavusans.ttf"
glyphs="★☆☓☠✓✔✕✖✗✘❤"/>
</library>
</frame>
</movie>
Use swfmill simple resource.xml resource.swf to build resource.swf with the font. Add the following somewhere:
class Symbols extends flash.text.Font {}
Next, use -swf-lib resource.swf to link resource.swf into the final .swf, and use your font using the name Symbols. Be sure to set embedFonts = true.
Additonal Note:
for glyphs you can use letters ie: 'abcdefghijklmnopqrstuvwxyz' but since its xml some characters can not be written in this way, here is a useful method to help you encode characters, there maybe more optimal method but this works fine.
private function buildAscii( s_:String ):String { var ascii: String = ''; var i: Int = 0; while( i < s_.length ) { ascii += '&#' + s_.charCodeAt( i ) + ';'; i++; } return ascii; }
Incompatibilities
Some specific features will fail to compile or run on Flash9 :
- having a
try/catchblock inside an expression, such as the following sample :
var x = try f() catch( e : Dynamic ) null; - having a class
implementinganother class (accepted in Haxe but not in Flash9) - there is no equivalent of the Flash Error class in haxe, you can throw any object so you don't need to inherit from Error. It is a good practice in AS3 to throw objects of classes that inherit the Error class but it is not mandatory.
- there are some issues with nullness of Int, UInt, Float and Bool (see below)
Everything else should work perfectly and provide the same result on all the supported platforms.
Nullness of Basic types
In Flash9, the basic types Int, Float and Bool can't be assigned or compared with the null value. Int variable default value is 0, Float is NaN and Bool is false.
If you want to be able to store null values in these basic types, please use the types Null<Int> , Null<Float> and Null<Bool> instead. This will work the same as basic types, except that at runtime a Dynamic (Object in AS3) type will be used, enabling the null value to be stored.
For optional arguments, the Null<...> type is automatically used.
Using Null instead of the basic type will degrade performance a bit, but there is no reason to worry unless it's used for speed critical methods (in that case don't use optional arguments or Null types).
This can also have some undesirable side effects. For example the following method will return null when called without arguments.
function foo( ?x : Int ) : Null<Int> { return x; }
While the following will return 0 since null is converted to Int when returned :
function foo( ?x : Int ) : Int { return x; }
The same problem can occur with Arrays :
var a = new Array<Int>(); trace(a[999]); // 0 , since it's Int default value var b = new Array<Null<Int>>(); trace(b[999]); // null : it works this time
As a conclusion, while basic types are really faster, be careful when using them.
Attaching events to the stage
When your main class is created you can attach stage events by calling your init function after adding the application to the stage.
import flash.display.Sprite;
import flash.events.KeyboardEvent;
class Application extends Sprite {
public static function main() {
var app : Application = new Application();
flash.Lib.current.addChild(app);
app.init();
}
function init() {
stage.addEventListener( KeyboardEvent.KEY_DOWN, onKeyPress);
}
function onKeyPress(e : KeyboardEvent) {
trace("Key Code: " + e.keyCode);
}
}
Compile it with the following command:
haxe -main Application -swf9 movie.swf
Another way of doing this is using the ADDED_TO_STAGE event.