PIXI.jsで描画を行う(HTML5でブラウザゲームを作る)

  • 5
    いいね
  • 0
    コメント

プラウザゲームを作る上でネックとなるのが描画速度です。
最近のスマホはかなり高性能になってきているので大抵の事なら速度で困ることはおきませんがゲームとなると話が違ってきます。
特に画面に沢山のオブジェクトを表示しなめらかに動かすタイプの物はかなりの負荷をかけてしまいます。

僕が最初にゲーム制作を開始した当時はcreate.jsという描画ライブラリを使用していました。
とても使いやすく日本語マニュアルや日本語書籍などもありかなり敷居の低いものでした。
ですが、ゲームが複雑になるにつれその動作速度に不満が出るようになってきました。
スマホのブラウザ描画でこれ以上の高速化の手段としてはWebGLを使う以外にありません。
create.jsもWebGLに対応してはいるものの現時点ではその対応が不完全で機能も足りないと感じ制作中盤からPixi.jsに乗り換えをしました。
両方使った感想として、スマホゲームを作るという用途ならPixi.jsのほうが遥かに優れていると思います。

PIXI.jsを利用して作成したブラウザゲーム(ハイブリッドアプリ)

リバーシ

Pixi.jsを利用して作成したブラウザゲーム(ハイブリッドアプリ)
https://play.google.com/store/apps/details?id=net.hasemonmon.rev
http://hasemonmon.net/rev/

Reversi
apple-touch-icon-180x180.png
実際にインストールしてプレイ後にストアでレビューしてもらえると嬉しいです。

Pixi.jsの導入

公式サイトからライブラリをダウンロードします。
(自分のサイトに設置せずにCDNを利用するという手もあります)

Pixi.js
http://www.pixijs.com/

HTMLファイルにライブラリへの参照を追加します。

<script src="/(設置したディレクトリ)/pixi.js"></script>

これでPixi.jsを使う準備は整いました。

早速、実際に使用してみましょう。

<script>
    var width = 640;    // 描画エリアのサイズ
    var height = 880;
    var params = {
        backgroundColor: 0xa0a0a0   // 背景色の指定(灰色)
    };
    var renderer = PIXI.autoDetectRenderer(width, height, params);  // レンダラー生成

    // DOM操作にjQueryを使用するので事前に読み込んでおくこと
    $("body").append(renderer.view);    // DOMにレンダラーのビューを追加

    var stage = new PIXI.Container();   // ステージを生成
    renderer.render(stage);     // レンダラーにステージを描画させる
</script>

これで画面に灰色の長方形が描かれます。
この範囲がPixi.jsの描画エリアとなります。

実際にデバッガで動きを確認するとわかりますが、レンダラーのビューはcanvasです。
Pixi.jsのエンジンが描画結果をこのcanvasに反映してくれます。
その描画対象がstageで、描画タイミングが、「renderer.render(stage)」というわけです。

今の時点で、ステージは空のコンテナ(透明)のみなのでステージの背景色の灰色がそのまま表示されている状態となっています。
何かを描画させたいときはこのステージに色々な子要素を追加していく事になります。

少しわかりにくい概念だと感じる方もいらっしゃると思いますが、実際にゲームを作る際はこのあたりをクラスに纏め抽象化を行うことになるとおもうのでこういうレベルのコーディングを行うのは最初だけだと思います。
あとはこれを元に自分が使いやすいように機能に纏めてラッピングしていくだけです。
(僕もこの記事を書くにあたり自分のソースコードを確認して「これってこんな仕組みだったんだ..」と久しぶりに思い出しましたくらいです)

スプライト追加

Pixi.jsで扱えるオフジェクトは複数ありますが、大抵の事はコンテナ(Container)とスプライト(Sprite)の2つだけで事足ります。
それでは実際にスプライトを追加して描画を行ってみましょう。

// テキストスタイル
var style = new PIXI.TextStyle({
    fontSize: 80,
    fontWeight: "bold",
    fill: 0xffffff,
});

// テキストからスプライトを生成
var sprite = new PIXI.Text("Qiita", style);

sprite.anchor.set(0.5);     // 基準点をスプライトの中心にセットする
sprite.x = width / 2;       // スプライトの座標をステージの中心にする
sprite.y = height / 2;

stage.addChild(sprite);     // スプライトをステージに追加

renderer.render(stage);  // ステージ描画

これでステージに文字が追加できました。
Pixi.jsではDOMと違い、明示的に描画を行わないと更新が行われませんので画面に変更がある度にレンダラーのrenderメソッドを呼び出す必要があります。

実行結果サンプル
Screenshot from 2017-09-09 12-45-28.jpg

次に、canvasへの直接描画結果をPixi.jsで扱う方法です。
これも簡単です。canvasをスプライト化するだけです。

// ※cvは描画済みのcanvasオブジェクト

// canvasからスプライトを生成
var sprite = new PIXI.Sprite.from(cv); 
stage.addChild(sprite);

これを追記すると先ほどの文字が消えてしまいます。
理由はPixi.jsのコンテナは特に指定しない限り追加された順に重なっていくからです。
背景などは最初に追加して後から前面のものを追加する必要があります。
順を入れ替えて、ついでに、フォント名も追加し、文字を半透明にしてみましょう。
文字スタイルに「fontFamily: "hm_tb"」を追加し、
文字スプライトに「sprite.alpha = 0.2;」のプロパティを追加します。

実行結果サンプル
Screenshot from 2017-09-09 12-42-42.jpg

この結果だけを見ると、なんでもないただの描画ですが、これは内部的にWebGLを使って描画された結果だということが重要なのです。