AIR+FlashDevelopでブラウザ・PC・Android・iPhone一挙開発


そもそもAIRって何なんでしょうか?(芸術以外で)
Adobeのページを読むと、Adobe Integrated Runtimeの略称で、”a cross-operating system runtime”などと書いてあるんですが、どうやら最近のAdobeの方針として、Flash等で作ったものがアプリケーションとしてどこでも動く、いわゆるWrite Once, Run Anywhereな実行環境を整備しようとしているようです。そのためのランタイムがAIRという理解でいいのかなと。自分の印象だと、どうもFlash自体がJavaに近い方向に向かってるみたいですね。
ちなみにAdobeはゲーム方面にも力を入れはじめているようで、Flash 11以降で、GPUを用いた3D描画や、ゲームコントローラのサポートが予定されているようです。
さて、AIRでは、以下のようなアプリケーションを開発できます。
- iOS(iPhone, iPod touch, iPad)アプリ
- Androidアプリ
- WindowsやMacにインストールするアプリケーション
ActionScriptで書いたプログラムが、ブラウザで表示するFlashとしてだけでなく、各プラットフォームのアプリケーションとして配布できるのはすごくお得そうに見えます。あちらではAndroid SDKでJava、こちらではiOS SDKでObjective-Cというのは大変ですから。JavaScriptは? というのはちょっと今回は置いといて(笑)。
要は、FlashでiPhoneアプリだろうがPCゲームだろうが作れるよ!ってことです。
AIRアプリケーションは、Adobeが無料で配布しているFlex SDKとAIR SDKを使って作成できます。今回の趣旨ですが、フリーのActionScript用統合開発環境であるFlashDevelopと、ちょっとしたバッチファイル群を使って、ひとつのソースコード群から各プラットフォームのアプリケーションを手軽にビルドできないものかと試行錯誤してみました。
前置きが長くなりました。動くものをということで、こちらが今回のサンプルです。まだ癖が強い環境ですので、いろんなAPIを軽くテストするような感じになっています。
さしあたって、Flash版をクリックして見ていただくのがいいかと思います。この気楽さがウェブアプリのいいところですね。
iOS版については、配布するにはApp Storeに登録するしかなく、こんなテスト用プログラムでは審査を通りませんので公開できません。代わりにiPhone 4で動かしている様子を撮影しましたのでご覧ください。
FlashDevelopプロジェクトはこちらです。
FlashDevelopは4.0.0以降を使用します。2011-06現在、4.0.0はまだベータ版なのですが、3.3.4では駄目なので……不具合など不安な場合は正式版になるまで待ってください。ベータ版はこちらで配布されています。また、iOS版のパッケージングにはiOS Developer Programへの加入が必要です(ここを読むと、もしかしてMacがなくてもなんとかなるんでしょうか?)。
プロジェクトの簡単な説明と、そのあとAIRの所感にも触れたいと思いますが、その前に回り道になる人が出ないよう2点ほど。
ここではフリーソフトのFlashDevelopを使っていますが、AdobeのFlash Professional CS 5.5やFlash Builder 4.5では正式にマルチプラットフォーム書き出しができます。高価ですが、なにしろ公式サポートなのでずっと楽です。Flash Builderの体験版を試してみたところ、インストールして数分でiPhoneとAndroid実機での実行までできました。
ADC MEETUP ROUND 01 発表資料「Flashによるマルチデバイスアプリ開発ワークフロー」 | ClockMaker Blog
また、iOSやAndroidのパッケージングについて、すでにエントリを書いている方々がいらっしゃいます。Adobe公式のドキュメントなども非常に詳しいです。まずこちらで基本的な手順を確認したほうがいいかもしれません。
AIR2.7でAIR for iOSを試してみた | ton-up blog – とんぶろ
FlashDevelop4ビルド版でAIR for Android(ver 2.7)のセットアップメモ | alt
Adobe AIR * Adobe AIR® アプリケーションの構築
Adobe AIR * モバイルデバイス向けの AIR アプリケーションの開発
iPhone/iPadアプリ開発の扉を開くAdobe AIR 2.6とは(1/3) – @IT
*
というところで、ようやくプロジェクトファイルについてです。通常のFlashDevelopプロジェクトにいくらか手を加えてあります。使いかたとしては、
- FlashDevelop上でSWFファイルをビルドする
- 証明書などを用意
- build.batまたはbuild.bat debugを実行してAIRアプリケーションとしてパッケージング(ipa、apk、air、exeファイルの作成)
となります。なお、Androidプロジェクトでは、FlashDevelopのビルドで実機での実行・デバッグまでできるようにしてあります。それぞれ詳しい手順については、README.txtをご覧ください。
ソースコードの共有
FlashDevelopでは通常ひとつしかないプロジェクトファイル(*.as3proj)ですが、複数用意することで、ひとつのソースコードからそれぞれのプラットフォーム向けのビルドを行っています。プロジェクトは、Projectパネルでas3projファイルをダブルクリックして簡単に切り替えられます。当然ですが、プロジェクトのプロパティやライブラリの登録などはそれぞれ独立していますので、変更した場合に忘れないよう注意が必要です。as3projファイルはXMLファイルですので、どんな情報を保持するファイルなのか、テキストエディタなどで見ておいたほうがいいでしょう。
条件付きコンパイル
プラットフォームによってコンパイルされるソースコード内容を変更するために、ActionScriptの条件付きコンパイルを用いています。
ActionScript 3.0 の条件付きコンパイル – akihiro kamijo
FlashDevelopでコンパイル定数を設定するには、プロジェクトのプロパティ、Compiler OptionsタブのCompiler Constantsを開きます。MY_CONFIG::PLATFORMとMY_CONFIG::AIRを設定し、以下のようにビルド・実行するコードを変更しています。
config namespace MY_CONFIG;
MY_CONFIG::AIR {
...
}
if (MY_CONFIG::PLATFORM == "iOS") {
...
}
条件付きコンパイルではなく、Capabilitiesなどの参照でなんとかなることも多いかもしれません。
アプリケーション記述ファイル
Adobe AIR * AIR アプリケーションプロパティの設定
Adobe AIR * モバイルアプリケーションプロパティの設定
AIRアプリケーションをパッケージングするときに必要な設定ファイルです。プロジェクトのルートにapplication.xmlを配置するとFlashDevelopのProjectパネルのボタンから設定ウィンドウを開けるので、ここに配置して全部のプラットフォームで共有しています。
アプリケーションアイコンについては、全部のプラットフォームで使用するサイズのアイコンをまとめて設定してしまっています。
<icon> <image16x16>icon16.png</image16x16> <image32x32>icon32.png</image32x32> <image36x36>icon36.png</image36x36> <image48x48>icon48.png</image48x48> <image72x72>icon72.png</image72x72> <image57x57>icon57.png</image57x57> <image114x114>icon114.png</image114x114> <image128x128>icon128.png</image128x128> </icon>
こうすると、使用されないアイコンまでパッケージに含まれ、パッケージの容量がやや増えてしまいますが、まあ気にしないでいいのではないかと(富豪的パッケージング)。各サイズのアイコンは、バッチファイルでImageMagickを使用してひとつのicon.pngからまとめて作成しています。
*
モバイル版AIRを試してみて気づいたことです。
解像度
スマートフォンのディスプレイ解像度は多種多様です。が、デフォルトでは、Flashがアスペクト比を保ったまま画面の内側からフィットするようにステージをスケーリングしてくれますので、ゲームなどではこれに任せて、物理的な解像度についてはあまり気にしなくてもいいのかなと思います。Flashが元来ベクターグラフィックスに強いのも幸いしています。ただし、ディスプレイのアスペクト比の違いが問題になります。たとえば、iPhone向けにステージサイズを640×960に設定したSWFを、Galaxy Sの480×800の画面で表示すると、ステージの上下が余分に表示されてしまいます。
この対策は3つ考えられると思います。
- DisplayObject.maskでステージ内のみ描画するようマスクを設定する
- ステージの外部をオブジェクトで覆い隠す
- アスペクト比にあわせて表示要素を外にずらす
マスクを使うのが楽なのですが、やはり描画にマスク判定が入ると重いのか、端末や描画モードによってはパフォーマンスがかなり落ちてしまいます。iOSのCPUモードではフレームレートが半減することもありました。2番目、3番目の組みあわせになるでしょうか。
なお、StageScaleMode.NO_SCALEを設定すると、物理解像度の座標系で描画できるようになります。詳しくはこちらのページに解説があります。
複数の画面サイズ向けのモバイルFlashコンテンツのオーサリング | デベロッパーセンター
StageScaleMode.NO_BORDERというものもあります。こちらは外側から画面にフィットしてくれます。
CPUモードとGPUモード
モバイル版AIRには、CPUモードとGPUモードの2つの描画モードがあり、アプリケーション記述ファイルのrenderModeでどちらを使用するか指定します。GPUモードのほうが速そうに思えますが、端末や描画内容によってまちまちで、正直よくわかりません。AIR 2.6と2.7で特性が大きく変わったりもしているようですし、各種ベンチマークをまとめて取るプログラムを作る必要があるかもしれません。サンプルではAndroid版はGPUモード、iOS版はCPUモードでパッケージしています。
GPUモードではDisplayObjectのフィルタが使えない等いろいろな制限があります。制限事項がこちらのページにあります。
ちなみに今後、モバイル版AIRでもMolehillのハードウェア3D APIが使えるようになるそうですので、そうなるとGPUモードを重用するようになってくるのかなと思います。
あと、このエントリを書いている最中に、AndroidのGPUモードに不具合らしいものを見つけました。cacheAsBitmapをtrueにすると、アプリを中断して復帰するときに表示が化けるようです。フィルタを設定しただけでもtrueになるので要注意です。
互換性と実行速度
実際、ActionScriptコードがどれくらい動いてくれるのかですが、こいつ、動くぞ!って感じです(笑)。SiONでMMLが演奏できたり、Away3D Liteで3Dモデルが表示されたりするほどですから、大抵の処理は問題ないんじゃないでしょうか。つまり、ActionScriptの豊富なコード資産がそのまま使えるということです。
ただ、パフォーマンスについてはスマートフォンのCPUパワーなりです。サンプルの「Sound (SiON)」でLoad Complex MMLで呼び出せる曲(超手前味噌ですみません……)がGalaxy Sではほぼ正常に鳴ってますが、iPhone 4では処理が追いつきませんでした。上の動画で音が途切れている様子がわかりますのでご覧ください。
また、描画についてはかなり軽い描画内容でしか高フレームレートが維持されず、すぐ30fps以下になってしまいます。個人的には60fps大好き人間なのでつらいところですが、このあたりについてはランタイムの最適化が進むか、あるいは時間が解決するというやつで、今後数年でスマートフォンの性能が上がれば大丈夫なんじゃないでしょうか。
あと、細かな制限があるようで、例えばiOSではActionScriptを含んだSWFをLoaderやEmbedで読み込めないようです。ipa-debugターゲットで読み込もうとすると、”Uncompiled ActionScript”というエラーメッセージが出ます。
また、ipa-app-storeターゲットでは何も表示されず、以後の読み込みがすべて失敗します。うっかりActionScript入りSWFを読み込んでしまうことは多そうですから、割と地雷の予感……。
それからGalaxy SでMP3の再生開始に間があります。「Sound (MP3)」でSEボタンを押して確認できますが、ゲームの効果音の再生に支障がありそうです。iOSでは瞬時に鳴ります。
タッチパネルの判定
スマートフォンの小さい画面にウェブページと同じサイズでボタンを表示すると、なかなかタップできないことがあります。ボタンを大きくしてもいいですが、当たり判定だけを大きくする方法もあります。実際、サンプルではBackボタンの反応が悪かったので、タッチパネルの場合だけひとまわり大きい透明な矩形をaddChildして判定を広げてみました。このテクニックは使いでがあるんじゃないかと思いました。
// タッチパネルなら当たり判定を広げる
if (Capabilities.touchscreenType == TouchscreenType.FINGER) {
var rect:Rectangle = backButton.getBounds(backButton);
rect.inflate(10, 10);
var touchArea:Shape = new Shape();
var g:Graphics = touchArea.graphics;
g.beginFill(0xFF0000, 0);
g.drawRect(rect.x, rect.y, rect.width, rect.height);
g.endFill();
backButton.addChild(touchArea);
}
リモートデバッグ
最初、実機でのデバッグのやり方がわからなかったのですが、
- SWFをDebugビルド
- Androidではapplication.xmlでandroid.permission.INTERNET権限を許可しておく
- adtでパッケージングするときに -connect [FlashDevelopが動いているPCのIPアドレス] オプションをつける
- FlashDevelopのデバッガを Debug > Start Remote Session で待機させてから
- 実機でアプリを起動
というようにすればいいようです。iPhone、AndroidともにFlashDevelopのデバッガでステップ実行が可能です。
iOSでのテストが手間
iOSのパッケージングがとにかく遅いです。SandyBridgeのCore-i5 2500K機で、今回のサンプルのパッケージングに1分30秒かかっています。また、パッケージしたアプリを実機に転送するのにiTunesを使うのですが、「同期」ボタンを押して、転送が完了するまでさらに1分30秒近くかかります。ビルドの間にラーメンができます。パッケージングのほうは、最適化をしないipa-debug-interpreterターゲットを使えば数秒で終わるんですが(実行速度がだいぶ遅くなります)、実機への転送はiOSがクローズドなため改善されるとも思えず、困ったものです。Flash Builderでもipaファイルを自分で転送するように指示する表示が出ます。
Androidならパッケージング、転送、起動全部込みで10秒かかりませんので、Androidでのテストが基本になりそうです。
それと、アプリケーション記述ファイルのversionNumberを変更しなければiTunesでアプリを更新できません。どうしても変更を忘れてしまうので、versionNumberを0.0.1増やすPerlスクリプトを作ってパッケージングの際に自動的に呼び出すようにしています。
Flexフレームワーク
まだFlashDevelopでは試していないのですが、モバイル版のFlexフレームワークを使えば、一般的なスマートフォンのアプリケーションのようなユーザーインターフェースを作成できるようです。TitaniumやjQuery Mobileみたいな感じですかね。
Flash Builder 4.5でAndroidアプリを作ってみた – @IT
Android女子部が初体験 Flash Builder 4.5で作るAIR for Androidアプリ(1/4):CodeZine
View and ViewNavigator – Flex SDK – Adobe Open Source
Understanding Flex Mobile View and ViewNavigator : Mihai Corlan
制限事項
AIRの制限ですが、現状ではスマートフォン固有のAPIにアクセスできないため、アプリ内課金や、iOSのGameCenterなどが使えません。といっても、この辺は公式フォーラムでどうにかしてと言ってる人が大勢いるので、すぐになんとかなるんじゃないかと思います(笑)。現時点でも、かなりトリッキーな方法で実現している方もいるようですが。
こちらのエントリで、AIR for Android/iOSでできないことが簡単にまとめられています。
hi-posi Blog Archive AIR for Androidでできない事。
Androidへのインストール


AndroidでのAIRアプリケーションの実行にはランタイムが必要です。
AIRアプリケーションを初めてダウンロードして起動するとき、ランタイムがないということで上のようなダイアログが出て、「インストール」をタップするとマーケットのAIRダウンロードページにジャンプします。このとき最初のAIRアプリケーションは終了してしまいますので、AIRをインストールしてから再度起動する必要があります。一度入れれば問題ないのですが、ちょっとしょっぱいなーと思います。
そして、「250,000超件のダウンロード」ということで、これがAIR for Androidの現在の利用状況ということですかね?
パッケージの正体
パッケージングして完成したairファイル、ipaファイル、apkファイルは、実はどれもZIPアーカイブです。拡張子をzipに変更すれば展開できますので、最終的にいったいどういうファイルが作られたのか、のぞいてみるといいかもしれません。

いまさら情報かもしれませんが、バイナリの先頭に「PK」が見えたらたぶんZIPです。
コード署名証明書
WindowsにAIRアプリケーションをインストールしようとすると出てくるおなじみの警告ダイアログ。最近はネイティブアプリケーションへの風当たりが厳しいですね。

発行元不明をなんとかしたければ、自己署名ではなく、ちゃんとしたコード署名証明書が必要です。国内で個人を対象に発行してもらえるのはグローバルサインだけのようですが、高すぎるんですがどうにかなりませんか……。ちなみにインストールするときだけでなく、「プログラムのアンインストールまたは変更」でも発行元がUNKNOWNになってしまって結構目立ちます。
困ったら
やはりまだまだ発展途上の環境なので、謎の現象がいろいろ起きます。特にスマートフォンで疑わしい挙動に出くわしたら、Adobeのフォーラムやバグデータベースに当たるといいのではと思います。
まとめ
さて、下準備にだいぶ手間がかかりましたし、今のところ人柱度も相当高めですが、これで一応、ブラウザだろうがデスクトップだろうがiPhoneだろうがAndroidだろうが、APIを調べまわったりせず、同じ手順で何かを動かせるわけです。自分としてはかなり気が楽になったなと思います。必要が生じればネイティブなSDKに切り替えればいいわけですしね。タッチパネルで何か実験しようと思ったらすぐActionScriptで書けますし、比較的パフォーマンス要求のないアプリなら、全プラットフォームで同時リリースなんてこともできるかもしれません。
これからのFlashのアップデート、特にゲームコントローラのサポートにも夢が膨らみます。最近はJavaScriptがトレンドですが、個人的にはFlashとももう少し長いつきあいになりそうな気がしています。
今後の課題としては、どうすればモバイルで描画パフォーマンスが出るか、あと今回はAndroid MarketやApp Storeでリリースするところまで行ってませんので、そのためのアプリを何か考えないといけないなと。
そうそう、デスクトップ版AIRで、簡単に透明ウィンドウにできるのも面白いです。application.xmlのtransparent周りを変更してみてください。
久しぶりのエントリが思いもかけず長くなりました。日頃ウェブの情報にお世話になりっぱなしですし、こういうアウトプットもしておかないとということで。ひとまず置いて実制作に戻りたいなと思います。


7月 4th, 2011 at 13:35
[...] AIR+FlashDevelopでブラウザ・PC・Android・iPhone一挙開発 – GEOQUAKE Backstage [...]
7月 5th, 2011 at 07:32
[...] AIR+FlashDevelopでブラウザ・PC・Android・iPhone一挙開発 – GEOQUAKE Backstage [...]
7月 19th, 2011 at 15:38
[...] FlashでTLFテキストを使い埋め込んだFontをFlashBuilderで利用する方法。 AIR+FlashDevelopでブラウザ・PC・Android・iPhone一挙開発 – GEOQUAKE Backstage AIRでマルチプラットフォーム開発するざっくりした話。 [...]