この記事では Pixi.jsを使ってブラウザで動く簡単な2Dゲームを作ってみたいと思います。 爆弾を設置して敵を倒す、某爆弾男ゲームのようなシステムを作ってみようかと。 あくまで簡易的な。
の続きです。
今回でラスト。 ゲームとして完成したわけではなく、正直「遊べる」というレベルには程遠いですが、このシリーズは一旦クローズです。 一通り実装したいことが終わったのと、ここから拡張するには元々の設計に無理があるなと感じたため。
けど、 pixi.js に関してはもちろん、 JavaScriptのオブジェクト指向についても非常に勉強になりました。 以前読んでちんぷんかんぷんだった、オライリーの「オブジェクト指向JavaScriptの原則」が比較的理解できるレベルにまでようやく到達……。 あとは、ゲームのアルゴリズム周りがあまり情報を集めることができなかったので、そこが課題かな。 敵の動かし方、マップの管理方法などなど。 そういうのってどこで学べばいいんでしょ。 教えてほしいです。
vol.5 完了時のコードは下記に。
bomber_maid [Branch: master]
OUTLINE
- 疑似遠近法 PIXI.Display
疑似遠近法 PIXI.Display
ブロックの配置について、若干見せ方を変えました。
樽ブロックや木箱ブロックは真上から見たように完全にそれぞれのグリッド内に収まっている
樽ブロックや木箱ブロックは斜め上から見たように一部が重なってます。オーバーラップによる擬似的な奥行きの演出です。 キャラクターや爆弾も物陰に隠れます。 これを2Dゲームで実現するには、手前にある要素(画面では下の方にある要素)を canvas上で上に描画し、 逆に奥にある要素(画面では上の方にある要素)を canvas上で下に描画する必要があります。
pixi.js における各要素は、階層構造 + 追加順に要素の重なりが決定します。 親要素の上に子要素は来るし、後から追加したものが上に来ます。 この順番を操作するために、 addChildAt(child, index)
メソッド、 setChildIndex(child, index)
メソッドがありますが、面倒です。
マップの描画だけならこれで解決しそうですが、 実際にはキャラクターが動き回るため、その都度親要素への追加順を変更しなくてはなりません。
pixi-display
上記をもっと簡単に操作するために pixi-display を使用します。
要素やコンテナなどの PIXI.Container
要素を、 CSS の z-index のような重なり順を数値で管理できるようになります。
ざっくりとした使い方を以下に。
ルートのコンテナに PIXI.DisplayList
を割り当てます。
rootContainer.displayList = new PIXI.DisplayList();
PIXI.DisplayGroup
を生成します。
第一引数の 0 が DisplayGroup の z-index。 第二引数 DisplayGroup の内部の要素のソート方法。
topLayer = new PIXI.DisplayGroup(0, false);
PIXI.Container
の displayGroup に上記を割り当てます。
this.elm.displayGroup = topLayer;
複数の DisplayGroup がある場合、 第一引数の数値が高いものが上にきます。 ゲームのステージ、 GUI、 カットイン演出、 ダイアログなどの DisplayGroup を生成しておき、それぞれの大元のコンテナに設定すると管理しやすいかもしれません。
今回の擬似的奥行きは、この z-index ではなく、 DisplayGroup の中の要素に重なりを管理する zOrder で制御します。 「 手前にある要素(画面では下の方にある要素)を canvas上で上に描画し、 逆に奥にある要素(画面では上の方にある要素)を canvas上で下に描画する 」、 つまり要素の Y座標 をそのまま zOrder の数値としてあげればよいです。
Block 生成時は、
this.elm.displayGroup = Config.fieldLayer; // this.elm はブロックのスプライト this.elm.zOrder = -this.elm.position.y;
とし、 ブロック要素の zOrder は基本的にこのままです。
画面上を動くキャラクターも生成時にブロック要素と同じ displayGroup を設定。 そして、 zOrder は、
this.elm.zOrder = -this.elm.position.y; // this.elm はプレイヤーのスプライト
というコードを、 キャラクターが動く時に書いておけばOKです。
次は Unity をやってみようかと。 本だけは買ってあるのに、 手付かずです……。 仕事で JavaScript を使う機会はありますが、 C# は未知。
おしまい( ˘⊖˘)