ActionScriptやJavaScript、C++など、さまざまな言語向けにコンパイルできることがウリのHaxe (http://haxe.org/)と、Haxe向けゲームライブラリのNME (http://www.haxenme.org/)を使えば、一つのソースコードを書くだけで、Flash、HTML5、Widnowsネイティブで動くゲームを作ることができるらしいので、作ってみた。
- benchstg (http://abagames.sakura.ne.jp/nme/benchstg/)
確かにできる。一つのコードから複数の環境向けバイナリが作れるのは素晴らしい。近代的なSDL (http://www.libsdl.org/)という感じ。
ただ、何も考えずにHaxeのコードを書いていればなんでもクロスプラットフォームになる、とまではいかない印象。最初はFlash向けに作っていて、いざHTML5向けにビルドしようと思ったら、出来上がったJavaScriptがまともに動かない。いろいろと試行錯誤して、やっとHTML5版ができたと思って、次にWindows版を作ったら、また動かない。ちょい直し。という感じ。
上の作業をやっていて気付いた、クロスプラットフォームなHaxe+NMEを書く際の注意点を書いておく。
- 変数をちゃんと初期化する。ActionScriptだと宣言して放っておいてもintは0に、Booleanはfalseになってくれたりするが、環境によってはその保証がない
- クラスインスタンスをDynamic型で扱うとき、サブクラスに定義されている関数が呼び出される可能性を検知し損なうように見える。余分なコードを排除する'--dead-code-elimination'オプションを付けた時に、必要なコードまで削られることがある。親クラスに関数定義してoverrideすると安全
- Haxeの型推論をそこそこ信用して使う。型を全然書かないで使っていると、たまに訳分からんエラーを吐くことがある
- UIntを使わない。環境によってはNMEがUIntを扱えない
- Lib.stage.stageWidthとかが確定するタイミングは環境によって微妙に異なるので、可能な限り後の方で取得する
- アルファブレンド付きのBitmapData.copyPixelsをしない。HTML5環境でうまく動かない
- SpriteをBitmapData.drawするのもHTML5でうまく動いてない感じが
- Windowsネイティブ上のデバッグは面倒だが、'nme test foo.nmml windows -debug'とすれば、Haxeコード上のどの行で落ちたか教えてくれるので便利
予想されたことだが、環境ごとにパフォーマンスはまちまち。手元のPCだと、Windowsネイティブがもちろん最速だがFlashも十分速くて、HTML5はChrome21だとまだなんとかなるけど、Firefox15は相当厳しい、IE9は動くのがすごいがひどいパフォーマンス、という感じ。WebGLを使った描画ができればだいぶ違うと思うのだが、NMEはまだ対応していない。
NMEはiOSやAndroid向けにもビルドできるみたいなので、クロスプラットフォーム萌えの人にはとてもよい環境だと思う。Haxe自体も強力な型推論のおかげで、少ない労力で強力なエラーチェックが行える、よい言語だ。
あとは3Dのクロスプラットフォームライブラリがあればより良いのだが。Away3Dとかthree.jsとかを薄くラップした、Haxe向け3Dライブラリが欲しいところだ。