Skip to content

Rubyでenchant.jsを使える可能性(実験編)

JavaScriptは素晴らしい言語だ。
けれども限界もある。特にクラス定義にはちょっとクセがある。これが気持ち悪いという人も多い。
enchant.jsのClass.createを使うとかなり軽減されるけど、やっぱりちょっと変だ。

でも日本には素晴らしい言語がある。
言うまでもなくRubyだ。

enchant.jsはとても快適だけど、Rubyから使えたらもっと楽しいんじゃないか。
そんなことをふと考えてみた。

ブラウザでRubyを使う方法として、JSRubyHotRubyというものがあるらしい。もちろんJavaで実装されたJRubyを使ってアプレットとして実現する方法もあるけど、これはスマートフォンでは使えない。

どちらもプロトタイプ実装の域を出ていないみたいだけど、JSRubyの方はRubyインタプリタをJavaScriptで実現しようとしたみたいで、HotRubyはRuby1.9から登場したYARVというRuby仮想マシンのみをJavaScriptで実現し、Rubyからのコンパイルはサーバで行う方式だ。

JSRubyはまだ実装が不十分でクラスの定義などができなくてRubyの良さが活きない。
そこで今回はHotRubyを使ってenchant.jsを無理矢理動かせないか実験してみた。

まず、HotRubyをサーバにインストールする。
HotRubyのためにRuby 1.9.0をインストールしなくてはならない。1.9.0でないとダメだ。VM: InstructionSequenceが使えなくなってしまっている。

これがYARVコンパイラをRubyから呼び出す重要なクラスなのだ。
あとはお決まりのやり方で、WebサーバにHotRubyをインストールするだけ。

さて、次は実際のRubyコードとのつなぎ込みだ。
これが実はけっこう難しい。

HotRubyの場合、Rubyコードを一旦サーバに送り、コンパイルしてYARVの中間コードを受け取る。
今回はまだ実験の段階なので、enchant.jsの基本的な初期化はJavaScript側でやることにしてみた。

enchant(); //enchant.jsを初期化

window.onload=function(){
    game = new Game(320,320);
    game.preload("andy.gif"); //アンドロイドの画像をロード
    game.onload = function(){
        andy = new Sprite(16,16); //とりあえずアンドロイドのスプライトを作ってみる
        andy.image = game.assets["andy.gif"];
        andy.setXY = function(x,y){this.x=x;this.y=y;} //Rubyから呼び出しやすいようにsetterを作る
        game.rootScene.addChild(andy);

        ruby = new HotRuby(); // HotRubyを初期化
        ruby.runFromScriptTag('http://shi3z.yier.in/compileRuby.cgi'); //サーバに設置したYARVコンパイラを呼ぶ
        setTimeout(function(){ //コンパイルが終わった頃に実行される
            game.rootScene.addEventListener('enterframe',function(){
                // コンパイルした中間コードのオブジェクトを直接呼び出してみる
                ruby.invokeMethod(ruby.topSF.localVars[2], "enterFrame",
                                 [], ruby.topSF, "VM_CALL_ARGS_SPLAT_BIT" , false);
            });
        },1000);
    }
    game.start();
}

この実験コードを実行するとき、実際のRubyコードは以下のようになっている。

 <script type="text/ruby">
class Andy
 def initialize
    @x = 100
 end
 def enterFrame
    @x = @x+1
    $native.andy.setXY @x,100;
 end
end

andy = Andy.new
</script>

これを実行すると、ひとまずこんな画面になるところまでは行った。

アンドロイドのアイコンが、時間経過に従って右へ移動する。
JavaScript側のgame.rootScene.addEventListener(‘enter frame’….)の中から、Ruby側のandyオブジェクトのenterFrameメソッドが呼び出されているのだ。

ちなみにこのHotRubyは、Rubyの仮想マシンを理解する上でも非常に面白い。

Safariのコンソールでrubyを表示させると、YARVのデータが内部でどんな構造になっているかビジュアル的に理解できる。

たとえば、作成したクラスは全てruby.classesに格納される。
それぞれのクラスをさらに調べると、親クラスを内部に保存している。

ただ、ネイティブアクセスのための$nativeというグローバル変数を経由してJavaScript側のオブジェクトにアクセスができる。

けれどもenchant.jsの魅力はコールバックによるイベントモデルだ。
コールバックをちゃんとやろうとすると、HotRuby.jsに手を加えないと難しそうだ。

Ruby側で「このオブジェクトのこのメソッドをこのイベントに割り当ててくれ」という指定をして、それをきちんとJavaScript側からキックする仕組みを作る必要がある。

ただ、これができるように改造すれば、Rubyでenchant.jsを使うのは比較的簡単そうだ。
誰か挑戦しないかな・・・

このエントリーをはてなブックマークに追加
はてなブックマーク - Rubyでenchant.jsを使える可能性(実験編)
Post to Google Buzz
Share on GREE

Related posts:

  1. enchant.jsのサウンド機能で、ゲームをさらにカッコよく!
  2. enchant.js + node.jsで作る非同期型ネットゲームのプロトタイプ
  3. enchant.jsでTwitter連携ゲームを作ろう! (その1 プラグイン解説編)
  4. enchant.jsが進化!新機能でプチ・ネットゲームを作っちゃおう!
  5. Canvasで3Dワイヤーフレームに挑戦!

Facebook comments:

Post a Comment

Your email is never published nor shared. Required fields are marked *
*
*