undefined

bokuweb.me

Mithril.jsでBMSを実装してみた話

概要

以前cocos2d-JSで作ったbmsjsDOMベースでmithril.jsで実装してみました。 以下で遊べます。降ってくるのは全部div要素です。

デモ

http://bokuweb.github.io/bmsjs-ithildin

キーは白鍵が左からZ,X,C,Vが、黒鍵が左からS,D,FがターンテーブルにはBがアサインされてます。

ソース

github.com

なんでわざわざDOMで・・。

当然パフォーマンスを考えればWebGL使えって話しなんですが、以下の理由により試してみました。

  • すべてをcssでスタイリングしたかった
  • 勉強のため、また、どれだけ動くか試したかった

すべてをcssでスタイリングしたかった

もともとユーザにテーマを作ってもらいたいと思い、cocos2d-JS版の時もjsonで設定できるようにスタイル部分を切り出そうとしていたんだけど、これがかなり辛かった。すべてがcssでスタイリングできるようになればテーマ作ってもらえるんじゃないかと思い着手した。また、cocos2d-JSはテキスト入力やリスト、ラジオボタンなどを用意するのが大変で、この辺りをreactmithrilでやりたかったのも理由のひとつ。

適当な空のdivでも予備で複数配置しとけば、backgroundとかz-indexとか使って自由にオブジェクトを配置できるしかなり利便性もよさそうだった。問題としては、頻繁にリペイントされる要素に複雑なスタイル (box-shadowなど)を当てられるとリペイント時間が増大するんじゃないかってのがあった。

勉強のため、また、どれだけ動くか試したかった

結構動いた。デモも基本的には60FPS出てると思う。(実はreact版(bokuweb/bmsjs-ithildin at rewite_with_react · GitHub)やfastDOM版(https://github.com/bokuweb/bmsjs-ithildin/tree/use_fastdom)も作ったんだけどカクつきが一番少ないのはMithril版だった。この辺りもっと定量的に評価したい。)

ただ、少し踏み外すとカクつきが頻発したりしており、まだまだエフェクトなどを追加する必要があるので自分のスキルではこれ以上はきついんじゃないかと判断した。

じゃあどうすれば

自分の今のスキルと今回の要件を鑑みると、ハイブリッドがいいのではないかと考えている。動きが多く、アニメーションなどを必要とする箇所を必要最低限ピックアップしWebGLを使用、その他スコアや動いのないオブジェクトなどはDOMのレイヤーを被せて構成する。これならばパフォーマンスも確保できつつテーマをcssでスタイリングできる。はず。

  • react-pixi
  • react + cocos2d-JS
  • react + phaser

前回使用しているのでreact + cocos2d-JSが一番とっつきやすいかも。

今回活躍したツール

f:id:bokuweb:20151212220005g:plain

ChromeのEnable paint flashing

今まで知らなかったんですが、描画があった箇所をハイライト(画像の緑枠)してくれる機能です。DevTools の下のペインの「Rendering」タブを選択するとあります。こいつを使うとmithril版の場合、差分の発生していないはずのDOM(鍵盤のイメージなど)も頻繁にペイントされていることがわかり、{subtree: "retain"}を返すようにし対策しました。react版ではそのようなことはなかった。

ChromeのFPSビュワー

Enable paint flashing同様、「Rendering」タブを選択するとあります。こいつをイネーブルにすると画像右上のようにFPSが確認できます。常時60FPSが保てるようこいつで確認しました。

これから

bmsjsはサーバ側にも多くの課題を抱えているので本格運用はまだまだ先になりそう・・。これからまたcocos2d-JSを触るとなるとちょっとモチベーション保てなさそうなので、積み残しているtwitterクライントとかElixirの勉強とか(本当はサーバー再度もPhoenixでやりたい)リフレッシュしてから再開する予定。