Haxe + NME でクロスプラットフォームなゲームを作った

Flash / Adobe AIR / Android / iOS で動くゲームを作った
クロスプラットフォームで動くゲームを作ったので、その辺の話をちょっと書く。


まずは思い出話から。実用的な話はこの辺から。
コンパイル例もあります

思い出話

Haxe という言語がある。
確か2006~2007年頃だったと思うが、少し Flash に興味を持っていて MTASC で何か作ろうかと思い調べていたところ Haxe を見つけて、面白い言語なのでしばらく使っていたことがある。

その当時 Haxe はまだ haXe という表記で、日本語のドキュメントもなく、ほとんど国内ユーザーも居なかったように思う。自分で言うのもなんだけど、自分はそこそこ老舗ユーザーと言えるような気がする(そんなに使い込んではいないけど)。
あの頃はまだ割と ActionScript3 スゲェーっていう時代で、非常にカッチリとした言語構造で面白い新機能盛りだくさんみたいな夢のあるプラットフォームだったと思う。
そんな夢のある機能をそんなに大きくないファイルをダウンロードして簡単に配置して簡単にコンパイルできるという Haxe の手軽さが好きで、mp3 プレイヤーなどを自作してみたりしていた。
(MTASC が活躍した時代とは違い ActionScript3 からは無料での開発環境もある程度整備され始めていて、正直なところ Flash を生成するのが目的ならあまり Haxe を選ぶ理由は恐らくほとんどなかったのだが、色々なものに斜めに構えるのが好きな自分が気まぐれで選んだだけ、という部分は少なからずあったと思う)

Haxe には Flex にあるような便利な GUI パーツなどがなく、Flash の API を駆使して自分で同じような機能を持つパーツを作らなければならなかった。簡単な GUI ライブラリを自分で作り、当時は先進的だった Lingr という、わかりやすいかどうかわからないけど大福チャットの Java アプレットが必要ないバージョンみたいなものがあって、それの Web 用クライアントが作れないかなと思い試行錯誤していた(今気付いたけど大福チャットも Comet 使って生まれ変わろうとしている模様)。
通信周りの挙動が当時はなんか怪しくてうまく接続が維持できないままこの実験は諦めることになるんだけど、それ以来 Haxe を使って作ってみたいと思えるものがこれといって浮かばなくなって、おまけに HTML / JavaScript 関連の話がどんどん面白くなっていくので自然に遠のいてしまった。

Haxe でものを作らなくなってからも情報だけはぼーっと確認しには行っていて、PHP のコードが自動生成できるようになったという話も見かけたし、NekoVM でサーバサイドで動くものを作ったり、デスクトップ上で動く Adobe AIR の簡易版のようなものも一時期あったと思う。
でも俺は Delphi とか C++ とか PHP とかを趣味の範囲内だけど触っていて、まあそれぞれのプラットフォームで作りたいものはあっても共通で作りたいものってなかなかないのよね、ぐらいにしか考えてなかった。
Haxe で md5 計算とかみたいに環境に依存しない部分は Haxe で実装すれば使いまわせるかもしれないけど、共通で作るものは特にないなぁ…という感じで。

それから数年後、JSX という JavaScript に似た言語で書くとコードを最適化しながら JavaScript に落としてくれるという言語が現れて、その話の流れの中で突然また Haxe の話題を見かけるようになった。
「Haxe 知っている人が日本人でまだ居たんだ…」という感じだったのだが、改めて色々思い出しながら調べてみると、ブラウザが進化し、スマートフォンが進化し、タブレットが進化している間に Haxe も着実に面白くなっていっていた。
知らぬ間に NME というクロスプラットフォームで動く Flash みたいなものが出来上がっていた。
まあ Flash も色々なところで動くし Adobe AIR もあるのでポジションはわりと被っている。
しかし相変わらず斜めに構えるのが好きな自分が安易に Adobe AIR を選ぶわけもなく、変なものを触るのが好きな自分はまるで当然のようにまた Haxe を NME を使うために触り始めてしまったのである。

日本語の情報あんまりないし、導入周りの簡単な解説を書いてみる。

NME とは

NME は Windows / Mac / Linux / iOS / Android / Blackberry / webOS / Flash / HTML5 用のアプリケーションが生成可能な Flash API によく似た API を備える Haxe 用の開発用ライブラリ。
ただし確認できている範囲では、HTML5 用のコードで使われる jeash に関してはまだ互換性が低く実用段階とは言い難い(ブラウザ側の対応もまだ追いついていないように思う)。
多くの環境で NME は SDL を利用しつつ C++ や Objective-C 用のコードを生成し、コンパイルすることで各環境向けの実行用ファイルを生成する。
Android では内部的に JNI を使ったりする。

この各プラットフォームで動く Flash API エミュレーションレイヤみたいなものが、わりとよくできている。少なからず問題もあるものの基本的にはよくエミュレーションできていて、Flash との齟齬が発生するケースは思っていたよりも少ない(思ってたよりも…)。

最近の Adobe AIR や Flash は Stage3D での本格的な 3D 表示とかも始まっているけども、NME ではその辺は後追いで最近始めたようでまだ使えず、現状では 2D ゲーム向けのライブラリ、というポジション。

ただどうしてもモバイルプラットフォームにおいては GPU を効率的に使わないとパフォーマンス上の問題が発生しやすく、本格的に画面を派手にしようと思うと少なからず考慮しなければいけない部分がありそうだった。

Haxe と NME のインストール

手元の環境は Windows なので基本的には Windows 向けの説明をするけど、恐らく Mac / Linux 環境でも大きくは変わらないはず。

NME 公式サイトから最新版の NME をインストールする。
全部デフォルト設定のままインストーラを次へ次へと連打するだけでインストールは完了する。
NME のインストーラには Haxe のインストーラも含まれているので、この手順だけで基本的な部分に関しては簡単に準備が完了する。

この時点でコマンドプロンプトから nme というコマンドが使えるようになる。
環境によっては呼べない可能性もあるので、その場合は haxelib run nme で代用できるはず。

ここから更に、使いたいプラットフォーム向けのセットアップをする必要がある。
例えば Adobe AIR の場合は nme setup air を、Android の場合は nme setup android を、Windows の場合は nme setup windows を、という感じ。
Android の場合は途中で Android SDK Manager が立ち上がり、Android API 8 と SDK Platform-tools をインストールしてくれと言われ、その他 JDK のインストールも手動だったり、パスも入力しなければならなかったりする。
Windows 用には Visual Studio C++ Express とかのインストールを要求されたりもする。
ただ基本的には全てウィザード形式でほとんど y 押して Enter を押すとかパス入力とか Enter だけとかで進んでいくので、そんなに難しいことはないはず。

なお Flash 環境に関しては特にセットアップ作業は必要なく、一番動作の完成度も高い。
が、他のプラットフォームと挙動が異なるケースがたまにあるので、手間を惜しんで Flash 版だけで動作チェックし続けるのだけは止めた方がよさげ。
なお Flash 版のデバッグには Projector content debugger をインストールする必要があるので忘れずに。

プロジェクトを作ってみる

簡単なものを作ってみよう。
基本的な流れとしては *.nmml というファイルにアプリケーションで使用するリソースなどを書いて、プロジェクト内でそれを使用するだけの簡単作業。

デモプロジェクトを用意してみた。
コメントも多少書いてあるので少しは参考になると思う。

コンパイルしたらこんな感じのものができる。
コンパイル済みファイル: Flash / Adobe AIR / Android(debug) / Android(AIR) / HTML5

コマンドプロンプトから demo.nmml があるディレクトリまで移動して、
nme test flash で Flash 版、
nme test flash -air で AIR 版、
nme test android で Android 版、
nme test android -air で Android 用の AIR 版のテストができる。
他のバージョンも色々生成できると思うけど今回は試してない。
先にも述べたように HTML5 版は挙動が若干おかしい。

あとはもう書いた通りに大体動く。
色々罠もあるとは思うけど触ってみてはいかがでしょ?

本格的にアプリケーションを作るにあたって

一応ドキュメントはあるもののあまり整備されていないので、
実際にどんなメソッドがあるのかは NME のソースを覗いた方がいいこともある

・import などを書くときに例えば nme.display.Bitmap でなく
flash.display.Bitmap とかを書いてしまうと Android などでコンパイルが通らなくなるので注意
haxe.Timer などのように使えるものもあるので更に注意

・addChild などを使う Flash 風 API は Stage3D の流れでもわかるように GPU と相性がよくない
パフォーマンス出すなら nme.display.Tilesheet を使うのがよさげ
より使いやすくなっている nme-tilelayer というのもある

・最近起こった問題などはフォーラムなどを参照すると何か話題になってるかも

最後に

何となく敷居が高いと感じていたクロスプラットフォーム開発の環境構築が比較的簡単で、パフォーマンスもそこそこ出る Haxe + NME の組み合わせはとても良いと思う。
ライブラリとしての完成度はまだまだ課題は色々あると思うけど、無料でこれだけの環境揃えてる時点でとても素晴らしいし作っていて楽しい。
今後の展開も楽しみ。