HaxeでGoogle Earth APIを使ってみた

3D自動車シミュレーター on Google Earthというものを作りました。以前からどうしてGoogle Earth使わないんだとしょっちゅう言われてたんですが、やっと肩の荷がひとつ下りた感じです。

なかなか作らなかったのは、やはりJavaScriptが大変なのと、車体挙動部分など、ActionScriptと同じものをJavaScriptでも書いて両方ともメンテするのは億劫というのがあったんですが、Haxeがどちらもすっきり解決してくれました。コードの量としては今のところ40クラス5000行程度ですが、言語的な安心感もあって余裕たっぷりなので、どんどん増築・流用して行けそうです。コンパイラのトラブル等もまったくなかったです。

あと、先のエントリで、Haxeの弱点としてJavaScriptライブラリの利用の手間を挙げましたが、実のところ、externがなくても呼び出しに支障はないですし、どうせ外部との連携部分は局所化してしまってそこがラッパーとして機能するので、あまり問題ではなさそうに思いました。少なくともGoogle Earth APIを使った限りではそんな感じでした。

また、エンジン音はFlashの動的サウンド機能で簡単なソフトシンセのようなものを作って鳴らしているのですが、これもHaxeで書いています。JavaScript側を書くのと同じ感覚でFlash側もスムーズに書くことができました。しかも、今後もしWeb Audio APIが普及すれば(IEどうなるんでしょう……)コードそのままですぐ切り替えが可能です。

今のブラウザで使えるものを最大限かつシームレスに活用できるということで、ますますHaxeいいよHaxeという感じですね。

車体挙動は、Box2Dの助けを借りた2Dベースのものに、3Dのフレーバーを乗せている感じです。一応、タイヤ横力にPacejka(読みはパセイカ?)の式とか使ってます。エンジン、ホイール、サス等未実装箇所だらけなのでゆっくり改良していきたいです。というか、そっち方面の本やウェブページを読みつつ勉強中です。ぶっちゃけ、数学や物理は苦手なんです。最近、車が曲がるときに何が起こっているのかやっとイメージできるようになってきた気がします(今更)。

あとは、今回ChromeのGamepad APIを使ってみました。ジョイスティックで操作できますので試してみてください。最初にボタンを押して認識させる必要があります。APIのセキュリティ上の制限のようです(ジョイスティックでユーザーを識別できてしまうのを避けるため)。

プログラム以外の点について。自車の3Dモデルは一応自作です。Blenderでちまちまポリゴンを張って作りました。タイヤ除く、内装込みで2500△くらいです。

最初は、CG DATA BANKさんが販売している実車3Dモデルをローポリ化したものを使うつもりだったんですが、リトポ作業をしているうちに自分で作ってみたくなったのと、権利面で完全にクリアな自動車モデルを持っておくと後々都合がいいのではと思ったので方針転換しました。Blenderの練習も兼ねてます。不慣れなこともあって50時間くらいかかってしまいましたけど、その価値はあったと思います(ドラクエX遊ぶのとどっちが良かったかとかは考えないw)。実車のような何かをモデリングするのは、ここにこんな制約がとか、ここは構造上スペースがないとおかしいとか、気づかされたことがいろいろとあって面白かったです。本物の自動車の設計などはもっとずっと考え抜かれているんでしょうね。

CG DATA BANKさんには、問い合わせに親切なお返事をいただいて、モデルを使わせてもらうような話をしておりましたのに申し訳ないです。また別の機会に実車モデルでやってみたいです。

2012年9月4日

Sublime Text 2:カーソル下のURLをブラウザで開くプラグイン

巷で評判のコードエディタSublime Text 2を使いはじめました。Windows、Mac、Linuxで同じように動いて、見た目やアニメーションがかっこいい今風のエディタです。さらに、Pythonでプラグインを書けるのが嬉しいです。BlenderもPythonですし、スクリプトはできるだけPythonで統一すると楽かなと思ってたので。

弱点としては、日本語の扱いに難があって、Shift_JISに対応していなかったり、WindowsでIMEのインライン変換ができなかったりします。ウィッシュリストの下の2つにvoteしておくとよさそうです。一応、ConvertToUTF8というパッケージでShift_JISのファイルは開けます。

ということで本題ですが、タイトルの機能がないようだったので作ってみました。

Tools > New Plugin...で上のコードをコピペしてopen_url.pyで保存、Preferences > Key Bindings - User

    { "keys": ["alt+w"], "command": "open_url" }

を追加するとAlt+WでURLをブラウザで開くようになります。URLの切り出しや判定がいい加減ですが、気になるようなら直してやってください。

2012年8月31日

HaxeいいよHaxe

このところ話題になっているHaxe(ヘックス)を使ってます。

Haxeの概要についてはWikipedia日本語版の記事が詳しいのですが、Nicolas Cannasse氏を中心に開発されているオープンソースのプログラミング言語です。C#、ActionScript 3あるいは幻のECMAScript 4に似た言語で、JavaScript、ActionScript、C++、C#、Java、PHPと多数の言語に変換して動かすことが可能であり、またそもそもそのために作られているという特徴があります。

Haxeという名前は"has a X inside"から来ているそうです。何か凄いものを持ってる、というニュアンスでいいんでしょうか? これからHaxe Foundationを立ち上げるつもりだとか、かなり気合いが入ってるようです。

で、ここ2ヶ月ほどHaxe漬けなんですが、たしかにこれは良いものだという確信が強くなってきたので、ひとつどこがいいのか書き出してみようと思いました。ユーザーが増えるといいな、という思惑で。

言語縛りから逃れられる(かも)

プラットフォーム論争というのがありますよね。PCブラウザだとこれからはHTML5一択でしょとか、Flashそう簡単に死なないよとか。スマートフォンでも、ネイティブ、ウェブ、ハイブリッド、AIR等々、あれがいい、これは駄目だと喧々諤々の議論が絶えません。

Haxeが面白いのは、これらすべてをターゲットに開発ができることです。

昨今たくさんのプラットフォームが生まれたり消えたりします。頭が痛いのは、多くのプラットフォームにプログラミング言語の縛りがあることです。あるプラットフォームを対象に書いたコードは他のプラットフォームでは動きませんし、プラットフォームが駄目になると、書いたコードが無価値になったりします。これでは、どの言語でコードを書くか、どこで頑張るかを考えるだけでも一種のギャンブルになってしまいます。後で移植する苦労を想像しながらだとキーボードを打つ手が止まってしまいます。

また、いろんな言語を書き分けていると、言語をスイッチするたびに言語仕様やごく基本的なAPI(たとえば文字列のサーチや、現在時刻の取得のような)をど忘れしていたりして、そのたびに本やノートをひっくり返したり、Google先生に質問攻めしたりするはめになって、なかなかしんどいです。

Haxeを使えば、あるいはこうしたことを解決・軽減できるかもしれません。必ずしもアプリ全体とまではいかないかもしれませんが、同一ロジックを好きな実行環境で使えます。

それどころか、PHPやNode.jsなどサーバーサイドまでHaxeで書けてしまいそうに見えます。

恐ろしいことに独自のシェーダ言語まで作っているようです。

心配になるほどの全方位作戦っぷりで、こんな試みが本当に上手くいくのか、中途半端な代物になるんじゃないかという疑問も湧いてくるのですが、意外とそうでもなく――

JavaScriptターゲットがとても実用的

最近は猫も杓子もHTML5ですが、その最大の弱点はやはりJavaScriptだと思います。この"The Trouble with JavaScript"というページがよくまとまっています。いくらThe Good Partsを読み、バッドノウハウの数々を駆使しても、素のJavaScriptで大きめのアプリケーションを作るのはきついよねということで、実際、他の言語からJavaScriptに変換するものが無数に開発されています。

が、Dart、Jangaroo、JSILその他片っ端から試してまわったんですが、CoffeeScriptのような最初からその目的で作られたものを除いて、ほとんどのトランスレータは、巨大なランタイムコードやライブラリコードを生成したり、パフォーマンス上の問題や機能制限があったりして、なかなか使いづらいです。

Haxeならそういったことはありません。最新のHaxe 2.10では、強力なデッドコード削除最適化(--dead-code-eliminationオプション)によって、ものすごくクリーンなJavaScriptコードを吐きます。Hello Worldの変換結果がたった5行です。

Haxe(Main.hx)

class Main
{
    public static function main()
    {
        trace("Hello, World!");
    }
}

実行コマンド

haxe -main Main -js output.js --dead-code-elimination

JavaScript(output.js)

var Main = function() { }
Main.main = function() {
	console.log("Hello, World!");
}
Main.main();

もっと込み入ったものになっても、出力されるのは人間が書いたものに近い(バッドノウハウ混じりですが)とても素直なJavaScriptコードです。Closure Compilerなどを使ってさらに圧縮・最適化もできますし、これならモバイルでも何の不安もありません。クラスつきのJavaScript、あるいは静的型のCoffeeScriptのようなものとして普通に使えます。

ちなみに--js-modernオプションをつけるとグローバル名前空間を汚染しないようにできます。その上で、メタデータでクラスやstatic関数を外部に露出すれば、JavaScriptで使えるライブラリを作るのにも使えます。

@:keep
@:expose("com.example.MyLib.Cat")
class Cat { ... }

また、外部のJavaScriptライブラリも呼べます。基本的には静的型付けの言語ですのでexternクラスで型情報を与えたほうがいいのですが、動的型がありますので、なくてもどうにかなります。

さらにソースマップにもすでに対応しています。ブラウザ上でHaxeコードのステップ実行が可能です。

このように、JavaScriptとの親和性が高いです。クロスプラットフォームという特徴を除外して、単にJavaScript開発を楽にするためだけに使ってもHaxeは有力な選択肢だと思います。今すぐ使えます。

良い開発環境がある

HaxeはActionScriptに似た言語なので、主だったActionScriptのIDEがHaxeにも対応しています。フリーソフトで有名なのはFlashDevelopですが、Haxeでもさくさくコードを補完してくれます。WebStormでJavaScript/CoffeeScriptを書くのと比べても断然いいです。

また、IDEとは関係ないですが、静的型付けなのでコンパイル時点で多数のエラーを指摘してくれて、実行時のハマりが少ないです。素のJavaScriptの開発速度を1、CoffeeScriptが3とすれば、Haxeは5かそれ以上の感覚でしょうか(あくまで僕の場合です。個人差がありますw)。

身も蓋もないですが、要はActionScriptと同じ感覚でJavaScriptが書けます。

クラスプラットフォーム性能は本物っぽい

Box2DのHaxe版(をちょっと改造したもの)で試してみたんですが、HTML5 CanvasとFlashでほぼ同一のコードがそっくり動いています。この程度の複雑さのものが同じように動くなら心配ないんじゃないでしょうか。

*

弱点、あるいは気になる点にも触れます。

JavaScriptライブラリの利用

Haxeは静的型付けのおかげでコード補完はバリバリ効くし、エラーも迅速に指摘してくれるのですが、外部ライブラリについてその恩恵を受けるにはexternを用意する必要があります。作るのは結構しんどいです。実際、Three.jsのexternなどいろいろ作られてはいるのですが、メンテナンスが大変なのでしょう、大抵バージョンが古いです。

ただ、Dynamic型やuntypedでどうにかなるという面はあります。試しにCocos2d-html5をHaxeで無理やり使ってみました。先々月に公開されたばかりのライブラリですが、動いているようです。

この問題は静的型付けのメリットとのトレードオフで、ある意味仕方がないです。ユーザーが増えれば解決するかもしれません。

また、Haxeを実際に制作に使ってみたところ、どうせJavaScriptとの連携部分は局所化してしまうので、あまり困ることはないのではとも思いました。

Flashターゲット

Flashをターゲットにする際にはActionScriptのAPIがほぼそのまま使えるのですが、やはりAdobe純正の言語ではありませんので、つまずくところがいろいろあります。大きなものとしては、SWCのライブラリをそのまま使えなかったりします。でも、Away3DStarlingなど普通に使えるようですし、頑張ればなんとかなるのだとは思います。どのくらい頑張る必要があるのかはやってみないと分かりませんが((追記)Starlingはライブラリで簡単に使用できるようです。コマンドラインから「haxelib install starling」で入ります)。

Away3Dのフォーラムで、後々WebGLに移植しやすそうなのでHaxeを使ってるという話を見かけて、気になっています。サポートしているOSやブラウザ、ビデオカードのドライバの範囲を考えると、しばらくはWebGLよりもStage3Dのほうが動く環境多そうですし。

クロスプラットフォームは基本的にゲーム用途

アプリケーション全体をクロスプラットフォームで制作するにはNMEというライブラリを使いますが、このライブラリは2Dゲーム用途です。

ただ、JavaScriptターゲットについては完全にJavaScriptの代わりになりますので、何にでも使えます。試していませんが、おそらくPhoneGapなりTitaniumなりも普通に使えるんじゃないかと思います。Titaniumのexternなども見かけたんですが、やっぱりちょっと古そうですかね?

ちなみに、こちらでNMEで作られたゲームが紹介されています。

NMEはネイティブ・モバイルターゲットではSDL+OpenGLベースで動作するとのことで、結構パフォーマンス高いみたいです。"haxe NME vs The World"というスライドには、C++やObjective-Cは大変、スクリプト言語はとっつきやすいがスケールしない、クロスコンパイルがスイートスポットだ、という主張があって興味深いです。

C#/Javaターゲットは実験的でまだこなれていない

試しに出力してみると、うわっと思うはずです(笑)。こちらのスライドを見ると、今後最適化していくようなので期待です。UnityPlayStation Mobileなどにも同じコードを持っていけるようになるとすごく面白そうなんですが。

普通のfor文がない

for (i in 0...10) {}

で単純なインクリメントはできるのですが、逆方向のループやステップの変更などができません。whileを使うようにとのことです(ちなみに「...」はIntIterを作る演算子です)。やっぱり普通のfor文要るんじゃない? という話になっていたりするので、そのうちつくのかもしれません。

演算子オーバーロードがない

個人的な趣味です。ゲームで多用するベクトルや行列などを扱うには欲しいなあと……でもいろいろ難しそうですね(関連:Dartの演算子オーバーロードを使ってみる)。

日本語の情報が少ない

仕方ないですねー。このエントリでほんのちょっとだけ増えたでしょうか。

(追記)terurouさんがJavaScript開発向けのチュートリアルを現在執筆されています。力作です。

*

というところで、使い込むと細かな問題がもっと出てくるのでしょうが、全体としてかなり好感触な言語環境です。あまりにできることが多くて、まだ全容がまったく見えないのですが。

ここしばらく、HTML5で楽にゲーム作るにはどうするんだとあれこれ不毛な試行錯誤を続けていたんですが、少なくとも言語面ではHaxeがひとつの有力な落ちつき先になりそうです。ここに自作ライブラリを構築していこうという気分になっています。JavaScript出力言語として非常に良好な上に、ネイティブやFlash、サーバーサイドまでターゲットにできるなら隙がなさそうじゃないですか? FalconJSも気になるんですが、今年中には出てこない雰囲気のようで……。

独断と偏見ですが、Unity(ゲームエンジンのほうの)とHaxeは当代2大チート技術だと思います。haxe.orgのはてブコメントに「オーバーテクノロジー過ぎて逆にあまり評価されてない」とあって面白いなと思いました。自分も名前だけは耳にしていましたし、FlashDevelopの新規プロジェクト作成ウィザードにHaxeのプロジェクト群が並んでるのをずっと見ていたはずなんですが、こんなものが着々と作られていようとは思いませんでした。

そんなわけで、ざっくりとHaxe凄いよ面白いよという話でした。おすすめです。

2012年7月22日

Unity:Wheel Colliderで車を組み立ててみる

UnityのWheel Colliderコンポーネントを使って車を組み立ててみる実験をしました。公式のCar Tutorialの車は動きが不自然で、実際、スクリプトを見ると妙なことをしているように見えたので(笑)自分で中身を把握できるものを作っておこうという感じで。まだToDoをたくさん残したまま間が開いてしまっていて、ちょっと投げっぱなしなんですが……。

Wheel Colliderは、タイヤのスリップに対する摩擦力と、サスペンションをシミュレートしてくれます。なら、車体に4つタイヤをつけてWheel Colliderくっつければとりあえず完成? と思ってしまうのですが、それだけでは駄目で、旋回すると遠心力でタイヤが浮いてすぐ横転してしまいます。重心をいじったり、ダウンフォースを与えてみたりとしばらく悩んだのですが、車体のロールを抑えるためにスタビライザーを組み込むのがポイントのようです。車に必要不可欠なパーツだったんですね。こうしたことを体験・実感できるのは、物理エンジンに触れる面白さのひとつだと思います。まあ、重要なヒントをもらったところでやっぱり調整は難しいんですけど。

ちなみにいろいろ調べているうちに知ったのですが、本格的な自動車のシミュレーションのアセットがあったりします。CPUカーのAIのアセットもあるようです。

Unityは、せっかく頑張っても「それアセットでできるよ」となって不貞寝してしまうようなことが結構……。

バックミラーの左右反転描画はこんな感じで投影行列とポリゴンを反転してます。

using UnityEngine;

public class MirrorCamera : MonoBehaviour
{
	void Start()
	{
		camera.projectionMatrix *= Matrix4x4.Scale(new Vector3(-1, 1, 1));
	}
	
	void OnPreRender()
	{
		GL.SetRevertBackfacing(true);
	}
	
	void OnPostRender()
	{
		GL.SetRevertBackfacing(false);
	}
}

コースの生成にはEasyRoads3Dを使用しています。Terrain上に引いたスプラインパスから道路や縁石、ガードレールなどのメッシュを生成し、Terrainをそれに合うようにならしてくれます。便利ですが、UIなどやや癖のあるアセットです。

道路とTerrainがZファイティングを起こすのを回避するため、EasyRoads3D付属の道路描画用のシェーダにはOffsetの設定が入っています。が、調整が難しいのでオフにして、手っ取り早く道路の高さを7.5cmほど上げて対処しています。そのため、段差で車体が跳ねてしまってたり……。

まだいろいろと課題が多そうですが、Unityのおかげでこういったことをわりと手軽に試せるようになったのは嬉しいですね。

2012年5月16日

CSS3でゲームっぽいメニューを作ってみる

UnityのNGUIというGUIツールキットのアセットがおすすめだそうなので試していたのですが、その中のかっこいいサンプルのひとつを見て、CSS 3D TransformsとCSS Transitionsで同じようなことがやれるのではと思ったので真似してみました(思いっきり脱線……)。iPadでも動きます。IEとOperaでは動作しません。

HTMLでゲームのUIを作るのは流行りっぽいんでしょうか。ブラウザをゲームのUI用に組み込んでいる話など聞きますし、UnityでもHTMLでUIを作ったとか、WebViewのプラグインが公開されるとか。十分にパフォーマンスが出るようなら便利そうです。

HTML5のブラウザゲームでも、例えばメッセージウィンドウなどは頑張ってCanvasで描画するよりもDOMエレメントをオーバーレイするほうが適材適所かもしれません。jQueryのプラグインなども利用できると思いますし。要は通常のウェブページを作るノリでUIが作れるわけですからね。

ブラウザだと互換性の問題が大変ですけど。こんなシンプルなものでも片っ端からPCや端末を立ち上げて確認してまわらないといけなくて(Flashならまず大丈夫なのに、なんてつい思ってしまいます)。特にAndroidは個人で検証するのは不可能に近いような……。

とりあえずベンダープリフィックスだけでもなんとかして欲しいです(笑)。

2012年4月17日

トップページ
プロフィール

はてなブックマーク
wonderfl