This blog post explains how to create a Flash movie completely automatically, without using a GUI, just by writing a program in the language ActionScript 3 (AS3). The post gives instructions for Linux, but they should work with minor modifications on other operating systems as well since the compilers to be used are either written in Java or they are available for multiple systems.
ActionScript is a language similar to JavaScript, with some differences and incompatibilities. The most important difference is that you can declare types of variables (strongly recommended in ActionScript 3), and it has class-based inheritance, so classes are declared and use differently from JavaScript, more similarly to Java. To get a quick introduction to ActionScript, read
http://en.wikipedia.org/wiki/ActionScript. The reference manual is hosted by Adobe, at
http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/. The filename extension is
.as.
ActionScript has two major versions in used today: ActionScript 2 (AS2) is supported by Flash Player 7, 8, 9 and 10. ActionScript 3 (AS3) is supported by Flash Player 9 and 10. ActionScript 2 is about 3.5 times (or even more) slower than the JavaScript interpreter in Firefox 3.0 (SpiderMonkey). ActionScript 3, as implemented in Flash Player 9, has just about the same speed as Firefox 3.0 JavaScript. ActionScript 3, as implemented in Flash Player 10, can be up to 4 times faster than FireFox 3.0 JavaScript if
int is used instead of
Number for integer computations, and
Vector.<int> is used instead of
Vector. Both Flash Players 9 and 10 have a JIT engine that compiles ActionScript to native code, but this doesn't seem to become faster than Firefox 3.0 JavaScript in some number-crunching applications.
It is possible to call a JavaScript function from ActionScript and vice versa, using the
ExternalInterface ActionScript class (
flash.external.ExternalInterface). Please note that
ExternalInterface doesn't work for the file:/// protocol due to security reasons (as documented by Adobe
here) – you have to upload both your
.swf and
.html files to the same web server to make use of
ExternalInterface.
To compile ActionScript 2 to an SWF file, the free
MTASC compiler is recommended, which is very fast, works at the command line, and is said to be safer than the compilers written by Adobe. An example ActionScript2 script:
// Tuto2.as, an example ActionScript 2 script
import flash.external.ExternalInterface;
class Tuto2 {
static var app : Tuto2;
function Tuto2() {
_root.createTextField("tf",0,0,0,800,200);
_root.tf.mutliline = true;
_root.tf.text = "first";
var myformat = new TextFormat();
myformat.color = 0x00000;
myformat.underline = true;
myformat.size = 30;
// Set this, because the default font, "Times New Roman" may not be available on Linux.
myformat.font = "serif";
_root.tf.setTextFormat(myformat);
_root.tf.text = ExternalInterface.call + "\nHello";
// Call this again after changing the text, otherwise the formatting is lost.
_root.tf.setTextFormat(myformat);
}
static function main(mc) { // Entry point.
app = new Tuto2();
}
}
To compile it, download MTASM first:
$ wget http://www.mtasc.org/zip/mtasc-1.12-linux.tgz
$ mkdir mtasc
$ cd mtasc
$ tar xzvf ../mtasc-1.12-linux.tgz
$ cp .../Tuto2.as .
Then compile with:
$ ./mtasc -version 8 -swf tuto2.swf -main -header 800:200:20 Tuto2.as
The corresponding HTML would look like this for Firefox:
<embed src="tuto2.swf"
quality="high" bgcolor="#eeeeee" fgcolor="#000000" width="800" height="2
name="tuto" id="tuto" align="middle" allowScriptAccess="always"
allowFullScreen="true" type="application/x-shockwave-flash"
pluginspage="http://www.macromedia.com/go/getflashplayer" />
To make it cross-browser, use
SWFObject to embed it. Once created, load the HTML in your browser to view the Flash animation you've just created.
From now on we focus on ActionScript 3 and Flash Player 10. Adobe provides the Flex SDK, which contains a compiler (called
mxmlc, or
mxmlc.exe on Windows) which can compie ActionScript 3
.as source files to
.swf. The Flex SDK is free to use and is partially open source, and it is implemented in Java. Download version 3.4 (which is the most recent stable version at the time of writing this blog post, and is about 120 MB compressed) from
http://opensource.adobe.com/wiki/display/flexsdk/Downloads. Also make sure you have Java (at least a JRE) installed. Here are the corresponding download command-lines:
$ wget http://fpdownload.adobe.com/pub/flex/sdk/builds/flex3/flex_sdk_3.4.0.9271.zip
$ mkdir flex
$ cd flex
$ unzip ../flex_sdk_3.4.0.9271.zip
$ bin/mxmlc -help
Here is a sample ActionScript 3 program:
// Tuto3.as, a sample ActionScript3 program
package {
import flash.display.Sprite;
import flash.events.Event;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.utils.getTimer;
import flash.external.ExternalInterface;
public class Tuto3 extends Sprite {
function Tuto3() : void {
var circle : Sprite = new Sprite();
circle.graphics.beginFill(0xFF7744);
circle.graphics.drawCircle(0, 0, 30);
circle.graphics.endFill();
addChild(circle);
//myInit();
//addEventListener(Event.ADDED_TO_STAGE, myInit);
ExternalInterface.addCallback("myFunction", myInit);
}
public function myInit(e : Event = null) : String {
var startTime : Number = getTimer();
var tField : TextField = new TextField();
var tFormat : TextFormat = new TextFormat();
tFormat.size = 20;
// Set this, because the default font, "Times New Roman" may not be available on Linux.
tFormat.font = "serif";
tField.autoSize = "left";
tField.background = true;
tField.border = true;
tField.multiline = true;
tField.x = 20;
tField.y = 40;
tField.text = "hello1";
tField.setTextFormat(tFormat);
var endTime : Number = getTimer();
trace('hello2 ' + startTime + ' ' + (endTime - startTime));
tField.text = 'ms=' + (endTime - startTime);
// Call this again after changing the text, otherwise the formatting is lost.
tField.setTextFormat(tFormat);
addChild(tField);
}
}
}
Here is how to compile it (creates
Tuto3.swf):
$ ./bin/mxmlc -target-player 10 -default-size 800 200 -optimize Tuto3.as
Here is the corresponding HTML:
<html><head><script type="text/javascript">
function myonload() {
// document.tuto for Firefox, window.tuto for Internet Explorer
var tuto = document.tuto || window.tuto || document.getElementById("tuto");
if (tuto && tuto.myFunction)
document.getElementById("result").innerHTML = tuto.myFunction();
}
</script></head><body onload="myonload()">
<embed src="Tuto3.swf"
quality="high" bgcolor="#eeeeee" fgcolor="#000000" width="800" height="200"
name="tuto" id="tuto" align="middle" allowScriptAccess="always"
allowFullScreen="true" type="application/x-shockwave-flash"
pluginspage="http://www.macromedia.com/go/getflashplayer" />
<div id="result">no result yet</div>
</body></html>
The HTML above also demonstrates calling an ActionScript method form JavaScript. To call a JavaScript function from ActionScript, do
ExternalInterface.call("JavaScriptFunctionName", arg1, ...)
Don't forget to copy the
.html and the
.swf to a http:// location, otherwise
ExternalInterface won't work because the security limitations imposed by the Flash Player.
Please note that according to Adobe, AVM2, the virtual machine in Flash Player 9 and 10 for ActionScript 3 execution does a JIT for all functions and methods except for constructors. So don't put performance-critical code to the constructor. I couldn't measure any speed difference in the constructor and other methods. The last statement that the constructor is not JITted I could find is from 2007 (
http://blog.pixelbreaker.com/flash/as30-jit-vs-interpreted/).