CreateJSでゲームを作った感想(EaselJS編)

先日CreateJSで作成したサンプルゲームのコーディングを踏まえて現状の使用感をつらつらとメモです。
EaselJSのバージョンは0.4.1です。

まず、個人的に気にしていた部分としては、

  • canvasの拡縮対応が容易に行えるか
  • 拡縮が発生した際にタッチイベントが正常に取得できるか
  • それなりに階層の深い表示オブジェクトの座標計算にバグは無いか
  • クラスやメソッドの使い勝手は良いか
  • モバイル向けコンテンツにも使えるか

  • この辺りについて気になっていました。
    それでは雑感ですが順に書いて行いきたいと思います。

    canvasの拡縮対応が容易に行えるか

    前回の記事でも少し触れましたがモバイルでの使用を前提とする場合、
    この対応が容易に行えるかどうかは重要ですよね。

    canvasを使用したブラウザゲームを見ると、
    固定サイズのcanvasを使用したものが非常に多いです。

    PCのディスプレイの様に大きな画面であれば
    それはあまり問題ではないのかも知れませんがスマートフォンの場合そうはいきません。

    物理的に画面サイズが小さい為ゲームを作るとなると出来るだけ画面いっぱいに広げる必要があります。
    しかしスマートフォンの解像度は一番小さいものと大きいものでは2倍以上違いがあります。
    またパフォーマンス的な意味でも安直にcanvasのサイズを大きくすることは出来ません。

    これらの差異を吸収するにはcanvasを拡縮する必要が出てきますが、
    現状のEaselJSにはそれらをラップしてくれる様な便利メソッドはありませんでした。
    この問題についてはブラウザのウィンドウサイズに対して
    任意の比率で拡縮する様な機能を自前で作る必要出てきます。

    後述しますがこの辺りの機能がライブラリとして提供されていない場合
    モバイル向けのインタラクティブコンテンツを制作する上では致命的な問題が出てきます。

    拡縮が発生した際にタッチイベントが正常に取得できるか

    前の話の延長になりますが解像度の差異を吸収するにはcanvasを拡縮する訳ですが、
    EaselJSは拡縮に対して考慮されていない作りとなっている為、
    当然タッチイベントの座標もこれらを考慮した値になっていません。(Arcticでも同様)

    例えばw200*h200でcanvasを作成しcanvasをx, y共に2倍にスケーリング(表示上w400*h400)
    している状態でディスプレイ上のx200, y200をタッチした場合、
    実装者としては内部は200*200として表示オブジェクトをレイアウトしている為
    イベントもそれらを考慮した値(つまりx100, y100)として受け取る事を期待しますが、
    実際はそのままx200, y200として受け取る事になります。

    それもそのはずでwindowオブジェクト、もしくはdocumentオブジェクトに対して
    直接マウス(タップ)イベントを監視しているのでcavasのスケールがどうなっていようと、
    常にブラウザ基準での座標を送ってきます。
    個人的にはcanvasがリサイズされることも考慮した作りになっていたら感動したのですが少し残念です。

    問題を解決するにはこれらのイベントハンドラに対して
    canvasのスケールを考慮した座標補正処理をフックする必要がありますね。

    TouchクラスやDisplayObjectのMouseEventの初期化部分のソースを見ると
    引数を使用していないメソッド等がある為まだまだ開発段階というステータスなのかもしれません。

    それなりに階層の深い表示オブジェクトの座標計算にバグは無いか

    この部分についてはサンプルでも表示オブジェクトの変形を行っていないので調べられていません。
    行列を使って当たり判定や描画位置を割り出しているところを見ると問題なさそうに思いますが、
    Arcticではこの部分で結構つまずいたので。
    最低でも変形時にも表示がおかしくならないという事さえ確認出来れば・・・と言う感じです。

    クラスやメソッドの使い勝手は良いか

    この部分は好みの問題だと思うので流し読みでお願いしますm(_ _)m

    良いと思った点

    メンバ、メソッド
    表示系クラスのメンバ操作についてはasのそれと比較しても類似メソッドやメンバが多数存在し
    非常にFlashライクな作りとなっていてasユーザーとしてはとっつきやすくて良かったです。

    アクセサ
    javascriptではアクセサを作ることが出来ないのでライブラリによっては、
    get○○○()、set○○○()といった冗長的な書き方を強いられるものも存在しますが、
    EaselJSではこの辺りを直接読み書き出来るのでコーディングもスムーズに行えて良いですね。

    残念と思った点

    パッケージ
    クラス定義をwindowオブジェクトに直接追加しているのは賛成できませんでした。
    確かにnewする時はクラス名を直接書けば生成できるので楽なのですが、
    何かと競合した場合そっちのコストの方が高そうなので最低限の配慮として、
    パッケージオブジェクトを一番上にしてwindowオブジェクトには
    そのオブジェクトのみを追加すると言うような考慮がされてても良いのかなと思いました。

    表示オブジェクトのサイズ取得
    リファレンスを見ると分かりますが基本的に表示オブジェクトにwidth, heightメンバ変数が存在しません。
    恐らく子に対して変形や孫の追加が行われると親のメンバ変数にまで影響を与える為、
    インスタンスが静的に保持しておくとバグの原因になりかねないから存在しないのかなと考えています。

    しかしDisplayObjectと言う抽象的なクラスが存在しているにも関わらず
    そのオブジェクトのサイズを取得する統一的な手段が無いという点ではちょっと厄介だと思いました。

    イベント
    EaselJSでは各クラス内にメンバとしてon○○○等を持っていてそのメンバに関数を与え、
    適切なタイミングでハンドラ処理を実行しています。
    非常にシンプルで良いとも思うのですが同一イベントに対して複数のハンドラを追加したかった場合、
    ハンドラとして追加したい関数の上にそれらをコントロールする為の処理を含める必要が出てきて冗長的になってしまいます。
    Flashライクと言うならEventDispatcherクラスは欲しかったと言う感じです。

    しかしEaselJS内のクラスを見てみるとユーティリティー的な扱いのクラスは本当に少ないので、
    あまりその辺りにまで手を伸ばしたくないのかな?ともかんぐってしまいました。

    モバイル向けコンテンツにも使えるか

    広告やアニメーションバナーには現段階でも十分に使えるのではないかと思います。
    しかしcanvas内の描画オブジェクトをマウスやタップで操作するとなると一手間二手間必要になりそうです。

    と、全体的に後ろ向きな内容になってしまっていますが、それを考慮してもcanvasの描画周りの作りは凄く良く出来ているし、
    githubのリポジトリからも活発に活動している事が伺えるので今後のバージョンアップにも期待ですね!

    ※この記事で書いた内容はざっくりテストした結果です。
     それと僕は英語が読める訳ではないのでドキュメントの英文が理解できない箇所は実際にソースを追った結果の感想です。
     なので指摘した内容はドキュメントの何処かに何かしらの注意書きとして記載されているかもしれません。

     
    他のモジュール(PreloadJS, SoundJS, TweenJS)についてはまた追々


    CreateJSでゲームを作った感想(EaselJS編)” への1件のフィードバック

    1. はじめまして.

      ゲームプログラマをやっております phi と申します.
      突然すいません.

      こちらのエントリーを読みメールさせて頂きました.
      http://coremind.jp/blog/archives/44

      エントリーを見る限り, かなり JavaScript に関して精通されているよう
      お見受けしました.

      もしよろしければ私が制作したライブラリ『tmlib.js』も
      使ってみて頂けないでしょうか?
      https://github.com/phi1618/tmlib.js

      CreateJS の問題点として挙げられている

      ・Canvas 要素の拡縮
      ・拡縮後のタッチ位置取得

      にも対応しています.

      よろしくお願いします.

    コメントを残す

    メールアドレスが公開されることはありません。 * が付いている欄は必須項目です