OpenFL アプリの画面をPhotoshopとFlash Professionalで作る
Flashで作ったswfファイルを画面として取り込んで、表示することができます。
これだけだとAdobe AIRと変わらないですが、OpenFLはswfをインプットにしてコンパイルの段階で 各プラットフォーム用のプログラムを生成しているみたいです。これにより、AIRと比較した場合により高速に動作するし、ランタイムも必要ないのでプログラムのファイルサイズが小さくてすみます。
各パーツはSpriteやMovieClipとして取得してイベントや設定の変更を適宜実行することができます。
ということを試すためにサンプルでクイズアプリを作ってみました。デザインはご愛嬌。機能もペラペラです。
工程はこんな感じで進めることができます。
- PhotoShopで画面をデザインし、PSDファイルを作る
- PSDファイルをFlash Professionalで取り込んで、各パーツをシンボル化し、リンケージとインスタンス名を設定
- Flash ProfessionalでパブリッシュしたSWFファイルをOpenFLのプロジェクトに取り込む
- Haxeでコードを書いて開発していく
とてもよいのはPhotoshopで画面デザインができるということ。PhotoShopの成果をほぼそのままダイレクトにアプリまでもっていけます。 1をデザイナーさんにやってもらって、それ以降の工程をプログラマとかエンジニアとかがやっていけばOK。
このデザイナーさんとの協業の部分がヘタすると従来のFlashベースの開発よりもとてもシームレスにできそうな予感。
あとは製品リリースレベルの複雑なデザインがきた場合に 果たしてこの工程がそのまま使えて、OpenFLが耐えられるかどうか。これは実際にやってみないとわからないですね。
プロジェクト的には swfとlayoutというライブラリを使います。 project.xmlに次のように設定しましょう。
<haxelib name="openfl" />
<haxelib name="actuate" />
<haxelib name="swf" />
<haxelib name="layout" />
あとは自分で作ったswfファイルもライブラリとして指定しておきます。
<library path="Assets/ui.swf" />
アプリのソース内ではswfのファイル名とリンケージを指定してswfファイルにアクセスします。 今回はLayoutというリンケージをflaファイル内で指定しています。その配下のインスタンスはgetChildName関数で名前を指定すれば取得できて、そこから先はプログラミングの世界です。
Assets.loadLibrary ("ui", function (_) {
var layout = Assets.getMovieClip ("ui:Layout");
addChild (layout);
layoutManager = new LayoutManager (640, 960);
layoutManager.addItem (new LayoutItem (layout.getChildByName ("Button1"), LayoutType.STRETCH, LayoutType.STRETCH, false, false));
layoutManager.addItem (new LayoutItem (layout.getChildByName ("Button2"), LayoutType.STRETCH, LayoutType.STRETCH, false, false));
layoutManager.addItem (new LayoutItem (layout.getChildByName ("Button3"), LayoutType.STRETCH, LayoutType.STRETCH, false, false));
layoutManager.resize (stage.stageWidth, stage.stageHeight);
stage.addEventListener (Event.RESIZE, stage_onResize);
_button1 = cast(layout.getChildByName ("Button1"),Sprite);
_button1.addEventListener(MouseEvent.CLICK,function(event:MouseEvent):Void { checkAnswer(0); });
ソースコード全体はこちら。psdとflaファイルも付いてるよ。
z-ohnami/OpenFLQuizSample · GitHub
swfを更新した場合はlimeでビルドする際に-cleanオプションを使ったほうがいいみたい。 じゃないと、更新が反映されないことがあるようです。これでしばらくハマっていた・・・
OpenFLのプログラムをiOSの実機で動かす
androidのときのようにsetupコマンドを最初にやるのかと思ったらそうではないみたい。
YouもXcode入れるかい?みたいな質問がでてきてそれで終わっちゃう。
//これはやっても意味なし!!
$ lime setup ios
手順
Xcodeは普通にAppStoreからダウンロードしてインストールすればOKです。
その後、開発用の証明書を作成して project.xml に次のように設定を入れておきます。
この例だとios_dev.p12が証明書のファイル名で、一緒にパスワードも書いておけます。
<certificate path="ios_dev.p12" password="abcdef" if="ios"/>
iOS実機の場合はさらにプロビジョニングプロファイルをiTunes経由で先に仕込んでおきます。 私はこれに気が付かなくて小一時間悩みました。
あとは他のプラットフォームと同じようにlime test ios で動作すると思います。
$ lime test ios
Androidと違ってシュミレーターの起動速度が速いので、デバッグ時はこちらを使うのがいいかもしれません。 ある程度出来上がったら、実機で確認というパターンでしょうか。
$ lime test ios -simulator
OpenFL XMLのデータを読み取る
次のような流れでやってみます。
XMLは天気情報をXMLで提供してくれているところから取得してみます。
var requestUrl:String = "http://www.drk7.jp/weather/xml/13.xml";
XMLはHaxeのhaxe.xml.Fastを使うと楽です。
var fastXml = new haxe.xml.Fast(xml);
Fastが大分サポートしてくれるけれども、それでも、for文とif文の連発になってしまう・・ このあたりはActionScriptのほうがもっと簡単に書けるなぁ。属性でフィルタリングしたりできたし。
Android向けにビルドする場合はproject.xml に パーミッションを設定しておきます。
<android permission="android.permission.INTERNET"/>
OpenFL 日本語のフォントを使う
TextFormatでフォントファイルを設定します。
まずは、projet.xmlのリソースファイルでフォントの場所を指定しておきます。
<assets path="assets/font" rename="font" />
で、コードの中では Assets.getFontでフォントを取得して
var font = Assets.getFont ("font/misaki_mincho.ttf");
TextFormatでフォントを指定し
format.font = font.fontName;
TextFieldでformatを紐付け。これでOK。改行は'\n'でいけそう。
_text.text = 'z.ohnamiです。\nIs there any problem ?';
_text.setTextFormat(format);
またはdefaultTextFormatを使う。 text.defaultTextFormat = format; text.text = 'z.ohnamiです。\nIs there any problem ?';
重要なのは順番でtextプロパティを設定した後にsetTextFormatしないとフォントなどTextFormatに指定した内容が反映されないです。 逆にdefaultTextFormatはtextプロパティ設定の前に指定しておきます。
フォントはこちらのファイルを使わせていただきました。謝。
OpenFL サーバーのAPIを実行して値を取得する
OpenFL サーバーから画像を取得する
ローカルではなくて、サーバーから動的に画像を取得して表示したい。 とてもよくあることです。
Loaderクラスを使ってみましょう。 読み込み完了時に発動する関数をセットして、その後に画像表示処理を書いていきます。
var requestUrl:String = "http://192.168.24.24/img/hana.jpg";
var loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onLoadError);
loader.load(new URLRequest(requestUrl));
で、lime test flashだと画像が表示されない・・ html5でビルドすると普通に表示された。なぜ?
最初、セキュリティ設定がproject.xml にあって、外との通信を弾いているのかと思ったけどそうでもないっぽい。 これは実機で動作するか確認したほうがいいっすね。
オフィシャルのAPI一覧を見るとLoaderクラスは「Available on all platforms」とあるが・・
OpenFL イベント発生時にデータも送る
DataEvent というのがあって、それを使います。
データは文字列に変換しておきます。 最初、cast(value,String) というのがいいのかと思ったら、 コンパイルエラーが出たので使ってないです。
_rect.dispatchEvent(new DataEvent(MyRect.EVENT_MOVE,false,false,Std.string(getNextColor())));
受ける側はこのように。コールバック関数の引数の中に入ってやってきます。
private function onReceiveEvent(event:DataEvent):Void
{
trace(event.data);
x += 10;
y += 10;
drawRect(Std.parseInt(event.data));
}