Getting started with Haxe/Flash

As3 developers guide


http://www.haxenme.org/developers/documentation/actionscript-developers/

HelloWorld

Developing Flash applications is really easy with Haxe. Let's see our first HelloWorld sample.
This is a very simple example showing most of the toolchain.

Test.hx

Define/create this class in a file named Test.hx

class Test {
    static function main() {
        trace("Hello World !");
    }
}

compile.hxml

Create the file compile.hxml in the same directory with the following content.

-swf test.swf
-main Test

test.swf

To compile, you can simply double-click on the compile.hxml file or run the command haxe compile.hxml. If any errors occur, they will be displayed.

If you get the error "Standard library not found" or "Class not found : Test", make sure Haxe can find both the library files distributed with Haxe (the contents of the std directory) and the Test.hx file itself. By default, Haxe looks in the current directory only, meaning that both Test.hx and the contents of the std directory need to be in the directory from which Haxe is invoked. You can override the search path by setting the HAXE_LIBRARY_PATH environment variable to e.g. /home/mjs/local/lib/haxe/std:. (note the final colon and period).

If you get the error "Invalid class name -swf9 test.swf" change the encoding of the .hxml file to ANSI.

test.html

If everything goes smoothly like it should, this will produce a file named test.swf. Now create an HTML page such as this one and name it test.html:

<html>
<head><title>Haxe Flash</title></head>
<body bgcolor="#dddddd">
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
        width="400"
    height="300"
    id="haxe"
    align="middle">
<param name="movie" value="test.swf"/>
<param name="allowScriptAccess" value="always" />
<param name="quality" value="high" />
<param name="scale" value="noscale" />
<param name="salign" value="lt" />
<param name="bgcolor" value="#ffffff"/>
<embed src="test.swf"
       bgcolor="#ffffff"
       width="400"
       height="300"
       name="haxe"
       quality="high"
       align="middle"
       allowScriptAccess="always"
       type="application/x-shockwave-flash"
       pluginspage="http://www.macromedia.com/go/getflashplayer"
/>
</object>
</body>
</html>

If you open the file test.html with your webbrowser, it should display Hello World with information about the file and the line the trace occured.

Note: This example is using one of the most common ways integrating Flash into a website. Read about why here in this article: Flash Embedding Cage Match.
If you don't like passing arguments multiple times consider using a JS-library:
* the article Flash Embedding Cage Match lists some small libraries
* Howto embed Flash using SWFObject (Getting SWFObject)
for a practical SWFObject example with FlashVars.
* Howto embed Flash using jQuery
* Howto embed Flash using jQuery SWFObject Plugin
* Howto embed Flash using Mootools

Drawing a Square

So far we've been only using pure Haxe, not Flash-specific API. The trace function is implemented by default so that it will trace on the screen. Let's now see how to draw a square on the screen. For that we need to get a drawing context, which is called a MovieClip in Flash. Modify your Test.hx file with the following content :

class Test {
    static function main() {
        var mc:flash.display.MovieClip = flash.Lib.current;
        mc.graphics.beginFill(0xFF0000);
        mc.graphics.moveTo(50,50);
        mc.graphics.lineTo(100,50);
        mc.graphics.lineTo(100,100);
        mc.graphics.lineTo(50,100);
        mc.graphics.endFill();
    }    
}

What this code is doing is getting the current MovieClip and using the Flash drawing API to display a square.

Run the compile.hxml file to compile again and open the test.html to display a red square.

Using the Library

In Flash, you store assets (graphics, sounds, fonts...) inside the Library. Resources can have an identifier called a linkage name. When you create a SWF file from a Library using the Flash IDE or other third party open source tools such as the recommended SwfMill or Sam Haxe, it will contain the resources that can be referenced from Haxe using their linkage names.

For example, let's say you have a SWF named resource.swf containing a MovieClip with linkage name button. Modify your code so that it will display this resource :

Flash 8 code:

class Test {
    static function main() {
         var but = flash.Lib.current.attachMovie("button", "but001", 0);
         but._x = 10;
         but._y = 20;
    }
}

Flash 9 code:

class Test {
    static function main() {
         var but = flash.Lib.attach("button");
         // if symbol class name starts with UpperCase, 
         // you can use SymbolClass directly. like this
         // var but = new Button();
         flash.Lib.current.addChild(but);
         but.x = 10;
         but.y = 20;
    }
}

NOTE: If you got an error like ''Error #1065: variable button undefined', you can change the name 'button' to 'Button' and try to create a class like this:
class Button extends MovieClip {
    public function new() {
        super();
    }
}

This sample will attach a button from the library at depth 0 and with identifer but001 (there can be only one unique object per identifier and depth). It will then place the button at position (10, 20) on the screen.

In order to display the button, we need to tell Haxe to use our resource.swf file to look for resources. Edit the compile.hxml file with the following content :

-swf test.swf
-swf-lib resource.swf
-main Test

You can now run the compile.hxml file to compile the project. The test.swf created this way will include the entire content of the resource.swf as well as the Haxe compiled code. You can test it by opening the test.html file.

Please note that the test.swf will also use the same parameters (width, height, background color, flash version and frames-per-second) as specified the resource.swf while without the resource, it will use Haxe default parameters. However most of these parameters (except the frames-per-second and flash version) can be overridden in the HTML source as you can see inside the test.html file.

Changing SWF properties

The SWF properties can be changed by using the -swf-header commandline flag. Edit your HXML and add the following :

-swf test.swf
-main Test
-swf-header 200:300:40:FF0000

That will set the SWF size to 200x300 pixels at 40 FPS with a red background color. Please note that the size and background are redefined in the HTML properties.

You can also choose to target a specific Flash Player version, by using the -swf-version commandline flag. Haxe will process accordingly :

  • -swf-version 9 : will target Flash Player 9 and use the ActionScript3 API
  • -swf-version 10: will target Flash Player 10 (default for Haxe 2.07+)
  • -swf-version 11: will target Flash Player 11 including the 3D API

Support for older flash players :

  • -swf-version 6 : will generate bytecode for Flash Player 6.0 (slower since it doesn't use registers). The flash API are not disabled with this version so be careful to only use the API classes/methods available for this player version.
  • -swf-version 7 : will generate bytecode for Flash Player 7, while disabling Flash 8 API
  • -swf-version 8 : will generate bytecode for FP8 (same as FP7) but enable Flash 8 new API

Changing the security sandbox

If would like your local swf to access network resources (but not filesystem ones), you can set the security sandbox of the swf file to local-with-network by adding

-D network-sandbox

to your build.hxml or command line.

Receiving passed arguments (flashVars) and display size

How you define them depends on the way you embed your flash.
See Note about how flash can be embedded above.

        var params:Dynamic<String> = flash.Lib.current.loaderInfo.parameters;
        // quick way to trace them all:
        trace("param named name is :" + params.name);
        trace(haxe.Serializer.run(params));

Don't miss this thread:
How to wait for population of flash vars (parameters and size)

See also, which derives from the above thread:
Using FlashVars with the LoaderInfo class

The thread above doesn't show the correct way to wait for loaderInfo . Rather than polling for ready state on timer, listen for Event.ADDED_TO_STAGE on flash.Lib.current, then listen to Event.INIT on flash.Lib.current.stage.loaderinfo. However, these events may not be called if they already occurred, so don't listen to either event if flash.Lib.current.stage != null and Std.is( flash.Lib.current.stage.stageWidth , Int ). The thread above employs the timer polling method, which may be more well tested.

Going Further

Now that you can do such easy things, all you need to go further is to learn the Flash API needed to implement your application. Haxe is conservative about the API so you can read the Adobe Livedocs for Flash 6-8 (see the "ActionScript Language Reference") or the Adobe Livedocs for Flash 9-11 in order to get full help about it.

There are some minor differences between Haxe Flash API and ActionScript 2 Flash API, which are listed here :

  • the standard classes such as Date, Array, String can have some changes in Haxe since they are common to all Haxe platforms. Watch the Haxe API documentation for more details.
  • the XML and XMLNode classes are merged into one single Xml class, and provides and extended API.
  • all the core Flash classes MovieClip, TextField... are in the flash package. You need then to use flash.MovieClip instead of MovieClip, or add an import flash.MovieClip; statement at the beginning of your class.
  • use flash.Lib._root instead of _root, flash.Lib._global instead of _global and flash.Lib.current to access the local root (different from _root if the Haxe code SWF was loaded), for things like stage and getTimer().

Apart from these minor differences, you can easily use all of the existing Flash API if you know it already.

version #15818, modified 2012-12-26 09:32:35 by coldfog