読者です 読者をやめる 読者になる 読者になる

以下斜め読んだ内容

pseudo translation of useful posts, book reviews, remarks,etc. twitter: feeddict

Josh Tynjala「GridshockをFlashからHTML5へ移植してみた」

斜め読み

josh tynjalaブログ2011.1.11のブログエントリ

Flash to HTML5: Gridshock Remade « Josh Talks Flash

  • actionscriptハッカーjosh tynjalaが自分のflashゲームをhtml5に移植してみたよ、な記事
  • 色々困ったこととかハックとかをつらつら書いてて面白い
  • 昔YUI使う機会あってからはASでもクロージャー使いまくってるよとか
  • HTML5 Audioの実装はどのブラウザも現時点で使いものにならないとか
  • 検討したライブラリ・使ってみたライブラリにも寸評が入ったり
以下斜め読んだ内容
  • Gridshock
    • flashアプリ。これのHTML5ver.作った
    • Gridshock
    • flash/AIRでの開発は楽しいしこれからも続ける
  • flashに新しい視点をもちたいと思ってやってみた
  • python勉強してpygameで移植しよかと思ったが時間かかりすぎるのでやめた
  • html5/jsにした。asとjsはescmascriptのサブセットだし、いい選択だったと思う
  • ゲーム開発用のjsライブラリ探してみた
  • Craftyみつけた
    • 2〜3時間api眺めただけでだいたい把握できた
    • ver.0.1なので荒削り
  • たいていのjsゲームエンジンはまだ日が浅い
    • ie9でのcanvasサポートから今後活発になると思う
  • あのGrant SkinnerがEaselJSリリースしてた
    • flashのdisplay listのようにcanvasを操作できる
    • flashゲームやるならdisplay listは定石
  • easelは使わずcraftyでやることにした
    • flashコミュニティの外側の視点や知識を吸収したかった
    • またhtml5ゲーム作る機会があれは自分はeaselを最有力候補にする
  • Playtomic
    • 先進的。flashだけじゃなくhtml5 apiも提供してる
    • 見つけた時は結構感動した
    • これ見つけてなかったらゲームのハイスコア情報をローカルに保存する以外方法がなかった
      • インフラエンジニアじゃないし自分でサーバー立てる気はゼロだったから
    • 単発利用なら無料。従量課金もリーズナブル
  • zachleat/Humane-Dates - GitHub
    • 軽量ライブラリ。日付情報を「2 hours ago」のように人間が読みやすい形式に変換してくれる
    • Playtonicはこの手の日付情報を一応提供してるけど。
    • ゲームしてる人のローカルに保存されるハイスコア情報を保存して表示させるのに使った
    • 日付のデータ形式がPlaytonicとHumane-Datesで違うのとPlaytonicが返す値が不正確
    • この辺の不具合は時間があればforkしてHumane-Datesを修正する
  • GTween - Tweening Engine for ActionScript 3 Developers
    • flash開発で使ってるトゥイーンライブラリ
    • これのjs版を書いた。誰か書いててくれたら助かったが
    • gtween.js on Github
  • Modernizr
    • 各ブラウザのサポートしてる機能の詳細の検知と
    • 非サポート時に代替要素を提供してる
    • HTML5版Gridshockが対応していないブラウザでのアクセスがあったときはFlash版への誘導とかできた
    • 自分が開発で必要な機能をサポートしてるかどうかとかすぐわかって楽々
    • 例えばES5のObject.defineProperty())とか
      • これはjs版のゲッター/セッター
  • もちろんjsとasは別物でした
  • as使いが恩恵を受けてる、クラス、強い型付け、IDEでの自動コンパイル(Flash Builder)はjsにはない
    • jsはエレガントで楽しめる言語。jsの緩さとかクロージャーとかを自分は結構お気に入り
  • クロージャーは前からasでも使ってる
    • 数年前に自作のFlashベースのChartにYUIからアクセスできるようなライブラリを書いたことがある。
    • この経験以来、AS書いてるときもクロージャー使いまくるようになった
  • クロージャーに慣れ親しんだことが今回のhtml5/js開発にかんたんにダイブできたことの要因の1つ
  • craftyの仕組み
    • entityと呼ばれるmix-in機能をサポートしたオブジェクトをコンポーネントにしてる
    • 2Dのコンポーネントと追加する場合
      • entityはx,y(描画エリアの左上からx,y座標)w,h(オブジェクトのサイズ)プロパティを持つ。あとメソッドをもつ
    • canvasコンポーネントを追加するとき
      • craftyのstageに描画される
    • DOMコンポーネントを追加するとき
      • canvasの上部、ページのDOMへ画像が追加される
  • craftyにコンポーネントを追加するとことから開発開始
  • alphaオブジェクト
    • fade in/out的なものを操作する
  • autozオブジェクト
    • オブジェクトの深さを管理する
    • craftyではこの辺をうまく管理する機能がないので追加した
    • 描画されてる要素の重なり方がカオスなことにならないようにするのに必要
  • 追加した機能とcraftyのapiを組み合わせたコーディングは楽しかった
  • jsの継承は自分の過去の経験からすると大変な印象だったけど、思ってたよりも快適にできる
  • html5の機能で使ったのはcanvas、local storage、audioの3つ
  • canvas
    • 直接canvas要素をコーディングすることはほとんどなかった
    • たいていcrafty経由
    • 1〜2個バグあったけど、解決できたし大変じゃなかった
    • クロスブラウザ対応では大変な思いしなかった。
    • craftyの現在の実装はいいスタートを切ってるが、もっと最適化できる
    • テスト中にlaptopのファンがよく回りまくった
    • craftyはspriteの描画が多すぎる
    • 描画を無効化する仕組みがcraftyにはない
    • craftyはflashのenterframeに似たものを実装してる
    • あるオブジェクトの位置を横方向に移動したらすぐに描画、縦に移動したらまたすぐに描画
    • この挙動はGridshockのようなカジュアルゲームではまあ問題にならないが、改善した方がいいと思う
  • local storage
    • テストしたブラウザでは挙動は良好
    • flashのSharedObjectにlocal storageは似てるがlocal storageの方がプリミティブ
    • local storageでは全てstringとして保存される
    • 複雑なオブジェクトはJSON.encode()必要。これはブラウザ間で違いなし
    • プレーヤーのハイスコアを保存するのに使った
    • クロスブラウザ対応で困ったのはDateオブジェクトのJSONへのエンコードが若干挙動が違った
      • 解決は簡単にすんだ。UTC date string使って解決。new Date(utcString);
  • audio
    • 結論としては使えるレベルにない
    • クロスブラウザ対応が超ハード
    • 実装のレベルが荒削り
    • craftyではHTML5 AudioのAPIをラップするAPIを提供
    • 一見整合的に動いてるみたいだけど、自分のニーズを満たしてないことがわかった
    • クリック連打のたびにエフェクト再生ではまった
      • プレーヤーが光のグリッドをクリックするたびにサウンドエフェクトを再生させたかった
      • オーディオインスタンス1つをクリックすると再生される。次の再生に移るにはこの再生が終わるまで待たないといけない。
    • グリッドを連打するたびにエフェクト再生を実装するために、複数のオーディオインスタンスを生成し、クリックイベントに対応するためにその時点で再生されていないインスタンスをチェックして割り当てる作必要
    • これはasから来た人には「まあ楽勝」といえるかも
    • 更に問題
      • Chromeでは突如再生できなくなる時間帯が発生する
      • 暫く問題なく再生できてるのに突然音が鳴らなくなる
      • 複数のサウンドが再生されてるときは、あるサウンドだけ突然再生できなくなったりする
      • Operaだとサウンド再生の最後に大音量のクリック音が発生
      • Firefoxは連続再生しない
        • Firefoxの挙動を見て、html5/js版ではサウンドをカットした
      • IEだとオーディオインスタンスが適切な仕方で生成と再生できない
      • ブラウザによってはクリックしても再生されない
      • サウンドの遅延とかも発生したり
    • 2日頑張った。魔法ような解決はあるのかも。しかし見つけれなかった。
  • 他にも苦労したところはいくつかある
  • 画像の先読み。flashだと簡単
    • swfは1ファイルで提供
    • 残りすべてのフレームがロードされるまで最初のフレームを表示させるとか。
    • html/jsの世界だとjsのローディング順番をコントロールしないといけない
    • craftyはこの辺をサポートしてないのでこの機能をサポートするコード書いた
  • UI Controls
    • 大変
    • craftyと整合的に機能拡張するのが大変
    • ボタンとトグルの自作機能をcraftyに追加
      • craftyの機能だけだとハイスコア表示中のスクロールでちらつきがあった
      • スクロールできるdivを透明なtableでラップしてからDOMコンポーネントに置くことで解決。アドホックなやり方になった
      • 他の機能をcraftyに追加したときはcraftyのアーキテクチャとよくフィットしてたがこれはそうならなかった
      • 時間があればもっとエレガントな解決できる
  • 今後もasでゲーム開発するけど、今回のhtml5/jsの経験は自分に新しい視点を開発にもたらしてくれた
  • 将来きっとまたhtml5/js開発に戻るのは確実だとおもう。
    • 今興味があるのは、モバイル向けのAIRゲームのhtml5ベースへの移植
    • モバイル版AIRでは無料だが広告の入るバージョンを作ることができない
    • AIRランタイムと提携する広告プロバイダがないため
    • この状況は自分にはストレス
  • html5/jsでの開発はもう少し待った方がいいという段階
  • まずはAudio APIの実装をきちんとしないと。ゲームではサウンドは超大事
  • ゲームの通常のユーザは普通の人でIEを使ってる。彼らがIE9を使うようになるとhtml5ベースのゲームにダイブしてもよくなる
  • html5ベースのゲームは配布がflashと比べると面倒
  • swf1ファイルのような手軽さがない。あちこちに必要ファイルが散在した状態になる
  • 巨大なスプライト画像などをData URI使ってhtml内に書けるようになれば、配布の手間もswfのように楽になるかも