phina.jsをES Modules対応+αしてみた

公開:2020/10/10
更新:2020/10/10
2 min読了の目安(約2000字IDEAアイデア記事

はじめに

phina.jsはフレームワークに近いゲーム開発用ライブラリですが、各クラスをバラで使うutilsライブラリ的な使い方もできます。
例えばphina.accessory.Tweenerクラスだけを使ってpixi.jsのオブジェクトにtweenerアニメーションを付与することができます。

例:pixi.jsでphina.jsのTweenerクラスだけを使ってみる

これはpixi.jsの例で言えば、描画に強いけどゲーム開発に便利な機能があまり無い点をカバーできます。

しかし、この使い方はちょっとした問題をはらんでます。

不要なクラスまでグローバルに展開してしまう

phina.jsはライブラリ読み込み時に全てのクラスをグローバルに展開します。中には当然使わないクラスなどもありますが、これらの読み込みは制御できません。
基本的にはphina.なんたらかんたら.クラス名という形で展開されるので、意図せず変な動作を起こしてしまうことはないと思いますが…。

使わなかったクラスはTree shakingしてファイルサイズを節約したい

phina.jsはCommonJSに簡易対応してるのでwebpackなどでも読み込めますが、cjsではtree-shaking等の恩恵は受けられません。これはより実害が分かりやすく、バンドル後のファイルサイズが大きくなってしまうという問題があります。
(といっても元々それほど大きくなく、minify+gzip化すると大したサイズにはならないですが...。モバイルだとやや気になる程度?)

以上を解決するにはES modulesへの対応が必要です。

prototype拡張が悪さをする可能性がある

開発利便性向上のため、phina.jsはArrayなどのビルトインオブジェクトを拡張します。
これはphina.js単品で使う分にはまず問題ないですが、ほかのライブラリと組み合わせた場合、そのライブラリに悪影響を及ぼす可能性があります。
実際、riot.js v4との組み合わせで簡易レベルデザイナーを作ろうとした際、phina側の拡張が原因でエラーになった経験があります。(polyfill系の拡張メソッドが良くなかった)

(個人的)独自クラスが時代に合わなくなってきてしまった

これは実害などではないですが・・・。
phina.jsは独自クラス機能を備えていてphina.createClassやphina.defineを使ってクラス定義します。
これはES2015 classが一般的でなかった頃は有効でしたが、今はES classで書いたほうが何かと便利です(IDEの入力支援が受けられたり、accessorが定義しやすいなど…)
(ただ今でもnew演算子なしでインスタンス化できるのは魅力があると思います)

そういうわけで

ES Modules対応

  • (デフォルトでは)プロトタイプ拡張をしない
  • phina独自クラスをES2015 classに変換

したバンドルを作りました。

https://github.com/pentamania/phina.js/releases/tag/esm-alpha.1

使い方については上のリリースノートに書いてますので割愛しますが、

  • インスタンス化の際にnew演算子を省けない
  • es2015 classの作法に則ってクラス定義
  • MainScene等の既存Sceneの書き換えはwindowオブジェクトから生やすといったことが必要

に加えていくつか違いがある以外、基本的には一緒(のはず)です。

ちなみにスクリプトで機械的に書き換えようとしましたが、どうもいい感じにならず、結局手作業で各ファイルを書き直すということをしてます。。。

使用例

単体の具体的なゲームはまだ作ってないですが、今の所、pxb-editorというツールでインタラクション処理などに活用しています。

一応、対応するphina.jsブランチのリンクを張っておきます:https://github.com/pentamania/phina.js/tree/pxb-core

【余談】本家へのPR?

一応は本家に取り込められることになっても対応できるようにしていますが、そこまで需要がなさそうだったり、中身を結構大胆に変更してたり、まだ従来のphina.jsのようにブラウザ読み込みで使えるバンドルができてない(ES Classからphinaのclassに相当するオブジェクトへの変換が必要ですが、その方法がイマイチ分からない)ので、難しいかもな~という印象です。