Haxe + NME: First Steps

I'm currently looking for a smart way to carry all my practice and experience with ActionScript over to other platforms. Haxe, a powerful language able to cross compile into several languages and even mobile platforms seems to be just that. The syntax is similar to ActionScript but with lots of sugar on top. It also supports the main targets I'm interessted in: Flash, Android and HTML/JS/PHP. 

At first I thought I would be able to use the same API for all languages, but with Haxe alone you need to use quite a lot of language specific packages in order to compile to your target correctly. I also hoped I would be able to generate and manipulate HTML directly, but unfortunatly it does not provide a convenient way to do so ... unless you use it with NME.

The example below is my first attempt to cross compile to as many platforms as possible and it is
working for C++/Windows, HTML/JS, AS3 and C++/Android - at least on my setup.

package at.dotpoint.test;

import nme.events.Event;
import nme.display.Sprite;
import nme.display.Shape;
import nme.Lib;

class Main extends Sprite
    private var circle:Shape;
    private var frameX:Float;
    private var frameY:Float;

    // --------------------------------- //
    // --------------------------------- //
    static function main()
        Lib.current.stage.addChild( new Main() );

    public function new() 
        this.frameX = 0;
        this.frameY = 0;
        this.addEventListener(Event.ENTER_FRAME, this.onEnterFrame, false, 0, false);
    // --------------------------------- //
    // --------------------------------- //
    private function createCircle():Void
        this.circle = new Shape();
        this.circle.graphics.drawCircle(50, 50, 25);

    private function onEnterFrame(event:Event):Void
        this.frameX += 0.01;
        this.frameY += 0.02;
        this.circle.x = 200 + Math.cos( this.frameX ) * 100;
        this.circle.y = 150 + Math.sin( this.frameY ) * 100;

The program does nothing but moving a red dot in circles but I'm happy about it anyway. The JS/HTML version performs a bit slower than the other ones and the C++/Windows version does not have AntiAliasing (at least by default). I didn't bother to investigate any of those issues, its just a "hello world" anyway.

The problems I encountered so far were all in all pretty harmless and I was able to google most of them but I'm going to list the ones I can remember anyway:
  • HTML compiler requires a constructor in the main document. Anything you put into main() gets pretty much ignored and you are better off starting your program within new()
  • The ENTER_FRAME listener got garbage collected on Android when set as a weak listener, although it worked in Flash and HTML. (that one was tricky to spot, because I'm used to set them as weak)
  • The path to the DocumentClass in the application manifest (*.nmml) had to be changed to <app main="at.dotpoint.test.Main" file="dotpoint" path="bin" />
  • trace() may not work (although it should), however Lib.trace() worked
  • I had to set the "Path" Enviroment Variable for Java, the Android SDK and NME
  • NME requires the Android API8 in addition to the latest one
  • In order to debug on my Android I had to install the USB drivers manually and pipe the debug output of my phone to a textfile

I'm not too happy about the way I have to debug any other target besides flash, especially because I'm never sure if its supposed to work like that or not (like the weak listener that got garbage collected). I'm also not sure how much I like to work with FlashDevelop again. It is a great IDE for small projects but I got used to the smooth versioning integration and multi project support of other development enviroments, not to mention all the refactoring features.

The next step would be to throw more fanzy stuff at it and see what breaks. I already encountered some security problems loading files in JS/HTML and I can imagine that Android is going to require a bunch of platform specific code.

No comments:

Post a Comment