コマンドラインのFlash開発環境を整える

HTML5への流れが加速している昨今ですが、このところ仕事の中でFlashに触る機会が多くなってきました。

せっかくなので、忘れないうちにActionScriptによるFlash開発環境を整える手順をメモしておこうと思います。

前提条件

ポイントは以下の2つ。

さすがに動作確認はブラウザを使ってやりますが、その他の作業は基本的にSSH接続したターミナル上で行います。

サーバは CentOS 5.5 64bit版、クライアントは Windows 7 64bit版です。サーバ機にはGUI環境は入っていません。

Java実行環境の準備

後述するFlex SDKを動作させるために、Java実行環境(JRE)が必要になります。

上記ページから、今回は Linux x64 RPM をダウンロードし、以下のコマンドでインストールします。2010年11月20日現在の最新版は Version 6 Update 22 でした。

$ sudo sh jre-6u22-linux-x64-rpm.bin
...
$ which java
/usr/bin/java
$ java -version
java version "1.6.0_22"
Java(TM) SE Runtime Environment (build 1.6.0_22-b04)
Java HotSpot(TM) 64-Bit Server VM (build 17.1-b03, mixed mode)

コンパイラの準備

コンパイラにはAdobeが公開している Flex SDK を利用します。

Flex SDKには2種類あり、オープンソースプロダクトのみで構成された Open Source Flex SDK と、それにオープンソースでないものを含めた Free Adobe Flex SDK が用意されています。どちらも無料で使うことができます。

今回自分が想定している用途ではオープンソース版で特に不足はないので、ライセンスも馴染みのあるMPLですし、オープンソース版を使わせてもらうことにしました。

上記ページ中の Open Source Flex 4 SDK リンクからダウンロードできます。2010年11月20日現在の最新版は Flex 4.1 Update Release (4.1.0.16076) でした。

ZIPパッケージになっていますので、適当な場所に展開し、中のbinディレクトリにPATHを通しておきます。

$ unzip flex_sdk_4.1.0.16076_mpl.zip -d ~/flex
...
$ echo 'export PATH=$HOME/flex/bin:$PATH' >> ~/.bashrc
$ . ~/.bashrc
$ which mxmlc
~/flex/bin/mxmlc
$ mxmlc -version
Version 4.1.0 build 16076

サンプルプログラムの作成

早速なにか作ってみます。

package {
  import flash.display.Sprite;
  import flash.display.Bitmap;
  import flash.display.BitmapData;
  import flash.text.TextField;
  import flash.text.TextFieldAutoSize;
  import flash.text.TextFormat;
  import flash.events.Event;

  [SWF(width="640", height="480", frameRate="30")]

  public class HelloWorld extends Sprite {
    private var base:Sprite;

    public function HelloWorld():void {
      var txtFld:TextField = new TextField();
      txtFld.autoSize = TextFieldAutoSize.LEFT;
      txtFld.text = 'Hello World!';

      var fmt:TextFormat = new TextFormat();
      fmt.size = 32;
      txtFld.setTextFormat(fmt);

      var bmpData:BitmapData = new BitmapData(txtFld.width, txtFld.height);
      bmpData.draw(txtFld);

      var bmp:Bitmap = new Bitmap(bmpData);
      bmp.smoothing = true;
      bmp.x = -(bmp.width / 2);
      bmp.y = -(bmp.height / 2);

      base = new Sprite();
      base.x = 320;
      base.y = 240;
      base.addChild(bmp);
      addChild(base);

      addEventListener(Event.ENTER_FRAME, onEnterFrame);
    }

    private function onEnterFrame(event:Event):void {
      base.rotationY += 4;
    }
  }
}

上のコードをHelloWorld.asというファイル名で保存し、以下のコマンドでコンパイルします。

$ mxmlc HelloWorld.as

コンパイルが完了すれば、同じディレクトリにHelloWorld.swfというファイルが作成されています。あとはこれをブラウザで読み込むだけです。

せっかくサーバ上で開発しているのですから、コンテナとなるHTMLファイルも一緒に作り*1、そのままApache経由で参照できるようにしてしまうのが楽でしょう。

ちなみに、上記のサンプルは単に "Hello World!" が回転するだけのシンプルなFlashです。

コンパイルオプション

上記のコマンドでコンパイルすると警告メッセージが出ますが、これは -static-link-runtime-shared-libraries オプションを付けることで回避できます。

$ mxmlc -static-link-runtime-shared-libraries HelloWorld.as

コンパイルオプションは、上記のようにコマンドラインから指定する他に、設定ファイルに書いておくこともできます。

設定ファイルには、${FLEX_ROOT}/frameworks/flex-config.xml に配置されている共通設定ファイルと、コンパイル対象ファイルごとのローカル設定ファイルがあります。

ローカル設定ファイルは、コンパイル対象のASファイルと同じディレクトリに -config.xml サフィックスをつけて置いておきます。例えば先程の HelloWorld.as の場合、HelloWorld-config.xml というファイルを同じディレクトリに置いておくと、コンパイル時に特に指定をしなくても読み込んでくれます。

他にも、load-config オプションによって明示的に設定ファイルを指定することもできます。

設定ファイルのフォーマットは、一番単純な形だと以下のようになります。

<?xml version="1.0" encoding="UTF-8"?>
<flex-config>
  <static-link-runtime-shared-libraries>true</static-link-runtime-shared-libraries>
</flex-config>

オプション指定の優先度は「コマンドラインオプション > load-config で指定した設定ファイル > ローカル設定ファイル > flex-config.xml」となっています。

オプションの簡単なリストは以下のコマンドで確認できます。

$ mxmlc -help advanced list details

Makefile

頻繁にコンパイルを行う場合、make や ant などのビルドツールを使うことになるかと思います。自分は使い慣れた make を利用しています。

シンプルなswf生成用Makefileは以下のような形になります。

MXMLC = mxmlc
MXMLCFLAGS =

TARGETS = HelloWorld.swf

all: $(TARGETS)

clean:
        $(RM) $(TARGETS)

.SUFFIXES: .as .swf
.as.swf:
        $(MXMLC) $(MXMLCFLAGS) $<

traceログの出力

デバッグ版の Flash Player では trace() 関数を使ってファイルへのログ出力を行うことができます。

上記ページからデバッグ版プレイヤーをダウンロードしてインストールします。

スタンドアロン版もありますが、Firebugと組み合わせて使えると便利なので、自分は上記ページ中の "Windows Flash Player 10.1 Plugin content debugger (for Netscape-compatible browsers)" をインストールしてFirefoxで動かしています。*2

次に mm.cfg ファイルに以下の設定を加えます。ファイルが無ければ新規作成します。

ErrorReportingEnable=1
TraceOutputFileEnable=1

mm.cfg ファイルと trace() 関数からの出力が記録されるログファイルの場所は以下のページを参照してください。Windows 7 の場合は Windows Vista と同じ場所に配置されています。

trace() 関数によるログ出力を有効にするには、swfをdebugフラグ付きでコンパイルする必要があります。

設定ファイルで指定する場合は以下のようになります。

<?xml version="1.0" encoding="UTF-8"?>
<flex-config>
  <compiler>
    <debug>true</debug>
  </compiler>
  <static-link-runtime-shared-libraries>true</static-link-runtime-shared-libraries>
</flex-config>

JavaScriptコンソールへのログ出力

またはもっと簡単に console.log() を使ってFirebugGoogle ChromeJavaScriptコンソールにメッセージを出力することもできます。

ActionScriptからJavaScriptを呼び出すには ExternalInterface クラスを使います。以下のようなメソッドをどこかに定義しておくと便利かと思います。

  import flash.external.ExternalInterface;
  public function log(message:Object):void {
    ExternalInterface.call('console.log', message.toString());
  }

これで log() メソッドに渡した引数がFirebugGoogle ChromeJavaScriptコンソールに表示されます。

fdbによるリモートデバッグ

もっと本格的なデバッグにはActionScriptのデバッガである fdb が利用できます。fdb は Flex SDK に同梱されています。

開発環境と実行環境が同一ホストであるパターンがもっともシンプルなのですが、今回はfdbをサーバ上で、プレイヤーをクライアント上で動作させた状態でデバッグを行います。

まず、traceログ出力の際に行ったように、debugフラグ付きでswfをコンパイルし、クライアント上のデバッグ版プレイヤーで起動します。

次にサーバ上で以下のコマンドを実行し、fdbを接続待ち受け状態にします。

$ fdb
Adobe fdb (Flash Player Debugger) [ビルド 16076]
Copyright (c) 2004-2007 Adobe, Inc. All rights reserved.
(fdb) run
Player が接続するのを待っています

クライアント上のデバッグ版プレイヤーを右クリックし、メニュー中の「デバッガー」をクリックしてパネルを表示、接続先に「ほかのコンピューター」を選んでサーバのIPアドレスを入力します。

「接続する」を選択すると、デバッグ版プレイヤーが待ち受け状態のfdbに接続し、デバッグセッションが開始され、fdbによるデバッグが可能な状態になります。

なお、この際、サーバはクライアントに対して TCP/7935 のポートを開けておく必要があります。

$ fdb
Adobe fdb (Flash Player Debugger) [ビルド 16076]
Copyright (c) 2004-2007 Adobe, Inc. All rights reserved.
(fdb) run
Player が接続するのを待っています
Player が接続されました。セッションを開始しています。
ブレークポイントを設定して「continue」と入力し、セッションを再開してください。
[SWF] /sample/HelloWorld.swf - 2,287 バイト (解凍後)
(fdb)

処理の最初からデバッグを行ないたい場合、セッションを開始した状態でデバッグ版プレイヤーが動作しているページを再読み込みすればOKです。

fdbによるデバッグの詳細は以下のページが参考になります。

その他

あとはリファレンスやその他資料を参考にしながら開発を進めていきます。リファレンスには様々なパッケージが記載されていますが、Flex SDK で利用可能なのは flash, mx, spark の3つのパッケージだけですので注意してください。

他にFlashを開発していく上で詰まりやすそうなのは、クロスドメインポリシーまわりでしょうか。

Flashでクロスドメインの通信を行う場合、通信先のサーバにクロスドメインポリシーファイル "crossdomain.xml" が設置されており、かつ適切な設定がなされている必要があります。これは URLLoader/URLRequest のような単発リクエストの場合も、Socket/XMLSocket のような持続的接続のような場合も同様です。

Flash開発はまだまだ触り始めたばかりで慣れていませんが、ぼちぼち色々試していこうと思います。

*1:swfファイルを直接読み込んでもいいのですが、後述する ExternalInterface を利用するにはコンテナが必要になります。

*2:ただし結構頻繁にクラッシュする気がします。