CoffeeScript×enchant.js、enchant.jsをCoffeeScriptで書く。

enchant.jsをCoffeeScriptで書直しました。
GitHub - hanachin/enchant.js: HTML5/JavaScript Based Game Engine / MIT or GPL dual license
enchant.coffeeというファイルがあるはずです。
サンプルはexample/action-coffee/とexample/action-coffee2/以下に入っています。

理由

僕はCoffeeScriptにハマっています。CoffeeScriptは美しいからです。
functionを書かなくていいし、全て式なのでreturnを書かなくていいし、後置でifが書けるし、デフォルト引数もあるし、内包表記が凄く便利だし、?オペレータもかなり便利です。

僕はenchant.jsにもハマっています。enchant.jsは素早くゲームが作れるし、スマートフォンでもサクサク動くし、書いていて楽しいから。

enchant.jsがCoffeeScriptで書けたらいいな… そう思ってた時期にHotRubyからenchant.jsを使う記事を読みました。
wise9 › Ruby on enchant.js / RubyでHTML5ゲームを作ってみる

その中にはこう書かれていました。

ならCoffeeScriptで書けばいいじゃん、という意見もあるだろうけど、ここでは聞かなかったことにする。

僕はCoffeeScriptで書けばいいじゃん、と思った。
思ったからには書かねばならない。情熱が覚めないうちに。
まだまだ全然CoffeeScriptらしく書けてませんが公開します。
ちなみにenchant.coffeeの行数は2295行、元のenchant.jsが2685行なので14.5%、390行程度ソースコードの行数が減りました。

メソッドをオーバーライドするだけで動作

9leap : enchant.coffeeサンプル2 by hanachin_ - どこでも遊べる、投稿型ゲームサイト
ソースコードはこんな感じ

enchant()

class Bear extends Sprite
  constructor: (w, h, image) ->
    super 32, 32
    @image = Game.instance.assets[image]
    @x = 0
    @y = 0

  enterframe: (e) ->
    @x = @x + 1

game = new Game(320, 320)
game.fps = 24
game.preload('chara1.gif')

game.onload = ->
  bear = new Bear(32, 32, "chara1.gif")
  game.rootScene.addChild(bear)

game.start()

もちろんenterframeだけでなく他のイベントにも対応しています。

実装について

全体的に

不要なfunctionを置換したりインデントを揃えるので時間がかかった。

メソッドのオーバーライドでイベントドリブン

EventTargetクラスのコンストラクタで

    constructor: ->
      @_listeners = {}
      # Eventクラスで定義されたイベント名と
      # 同じ名前のメソッドを持っていれば呼び出すようにする
      for own prop, ev of enchant.Event
        @addEventListener(ev, ((ev) -> ((e) -> @[ev](e) if @[ev]?))(ev))

enchant.Eventクラスの持つイベント名に対して、それぞれイベントリスナを追加しています。
イベントを受信した際に、クラスがそのイベント名と同じ名前のメソッドを持っていれば、それを実行するようになっています。

現状

これから

バグがあれば直しますので[twitter:@hanachin_]までご報告ください。
なるべくenchant.jsの機能追加等に追従出来るようにしようと考えています。
後は9leapのプラグイン等をCoffeeScriptで書直します。
enchant.coffee自体も整理したいのですが、まずは9leapで実際に使えるようになることを目指します。

質問等

何か質問等ございましたらTwitterで[twitter:@hanachin_]宛にmentionをください。
もしくは以下のアドレスまで連絡をください。
http://services.nexodyne.com/email/icon/5JhEZ.J3qJ4%3D/LFg9q1s%3D/R01haWw%3D/0/image.png
よろしくお願いします。