🧚

PixiJS入門編

2021/06/16に公開

PixiJS 入門の記事です。
読者の皆さんが入門するための記事ではなく、僕が入門する様子を書いた記事なんですけどねっ!

適宜、公式サイトのAPIリファレンス にクラスなどリンクしていきます。

PixiJSとは

PixiJS は JavaScript の 2D描画ライブラリです。Pixi.js と書かれることも多いですが、公式には現在 PixiJS で統一されているみたいです。
特徴はブラウザ上で GPU(いわゆるグラボ) を使って3Dグラフィックを高速に描画する WebGL 技術を応用して、2Dグラフィック描画を高速に行うことです。
3Dを高速に扱えるんなら2Dに使ったら爆速じゃね? という発想ですね。その発想は正しく、実際 PixiJS は爆速です。
ちなみに3DをJSでやるのは Three.js というライブラリが有名です。

さて、WebGL は JavaScript から使えるように API(要はJSのメソッド)を持っています。
なのでライブラリを使わなくても通常の JSから直接使うこともできます。
ただしJSだけでなく、GLSL(OpenGL Shading Language) という言語も使う必要があります。
GLSL は割と C言語に近い文法ですが、GPU を効率的に動かすためにパイプライン実行の考え方をする必要があったり、デバッグが難しかったりします。
JSで使えるとはいえ、そこそこハードルが高い環境と言えますし、ゲームでキャラを動かしたいみたいな需要からするとかなり遠回りです。
フラクタル大好き!マンデルブロ図形を描画したい!!とかでしたら、むしろ近道ですが。

まそれはともかく、そんなわけで登場するのが MITライセンスのオープンソースで使い勝手のいい PixiJS というわけです。

PixiJSの応用例

僕の場合は『RPGツクールMZ』(およびその前作『RPGツクールMV』)で使われていたので、興味を持ちました。
ツクールのコマンドじゃなくて、直接 PixiJS を使えば応用範囲も広がるし爆速じゃね?という感じで。

PixiJSの公式サイトを見ると有名企業のロゴがいっぱい流れていて、それらのサイトのコンテンツ制作に採用されているみたいです。
シャニマスこと『アイドルマスターシャイニーカラーズ』でも使われてるらしいです。今はちがうかもしれませんが。

PixiJS は他のライブラリと共存して使いやすい仕組みもあって、エフェクトの Effekseer とか、2Dアニメの SpineLive2D なんかと一緒に使えるらしいです。
このへんは、まだ全然調べてないので「らしい」って話ですが。

PixiJSの実行環境を整えよう

Webを調べていると 初心者による超初心者のためのPixiJS入門 (以後『PixiJS入門』)という記事を見つけました。
この記事、はちゃめちゃに分かりやすいので、とりあえず読むといいです!

あと、この記事を書きかけている状態で見つけたので内容がもろかぶりしてますが、僕は気にしません!!
自分の中でしっくり来るまで、似たような内容の記事を何回でも読めばいいと思います。

ローカルファイルが読めないのですが

PixiJS のコードを書いてブラウザで動かそうとしたらエラーが出て止まっちゃうんですよー。
正確にいうとJSでローカルの画像ファイルを読んで、いざ処理しようとすると止まっちゃう。

最近(でもないか)のブラウザは、ローカルのファイル読み込みに対する制限がかなり厳しくなってます。
ローカルのファイル読み放題だったら、個人情報抜かれまくりですから、しょーがないです。

とは言え、自分で作ったプログラムを自分のローカル環境で動かしてるのにファイル読めないとか許せんですよね。
『PixiJS入門』では、VS Codeのプラグインで簡易サーバを作ってます。
もちろん、ふつーにローカルサーバを立ててもいいです。
ただ「ローカルサーバ立てるのがふつー」などと思っている人は、この記事読まなくてもスイスイ PixiJS 使えるんじゃないでしょうか(笑)

他にはブラウザの起動オプションでローカルファイル読めるようにする、という方法があります。
この起動オプションをつけてシェルスクリプトなり、AppleScriptなりからブラウザを起動するのです。
Winだと…今なんですかね、Windows PowerShell ですか? まだ DOS窓でバッチファイルとか使ってんのかなぁ。
ローカルファイル読める起動オプションはChromeだと --allow-file-access-from-filesですね。

どうせエディタでスクリプトを書いて実行するのですから、VS Code に『Debugger for Chrome』機能拡張入れて launch.json 起動オプション runtimeArgs に追加しておけば、コーディングから実行までスムースです。
デバッグパネル(ウィンドウ左の虫に三角アイコンで出る)の[実行とデバッグ]ボタンで launch.json は設定できます。
僕の場合は、HTMLファイルは index.html にして launch.json の内容は、こんな感じになりました。

{
    // IntelliSense を使用して利用可能な属性を学べます。
    // 既存の属性の説明をホバーして表示します。
    // 詳細情報は次を確認してください: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Launch Chrome",
            "type": "pwa-chrome",
            "request": "launch",
            "file": "${workspaceRoot}/index.html",
            "runtimeArgs": [
                "--allow-file-access-from-files",
            ]
        }
    ]
}

これで F5キー押すだけで実行できます。うぇーい!
この記事のコードでは画像ファイル読んでないんで、起動オプションなくても関係ないんですけどね(笑)

NW.js とかのローカルJS環境で動かそうというんだったら別の問題があったりするかもしれませんが、とりあえずブラウザで行きます。
NW.jsとpixi.jsでゲームを作る方法 って記事を見つけたので、興味のある方はどーぞ。

Web上で実験できるんだよね

プログラミングで一番脱落しやすいポイントは環境構築というのは言うを俟たないですが、PixiJS はありがたいことに Web実行環境が作られていて、そこで練習できます。

PixiPlayground

「最初に言えよ」って感じですね。すんません。
ここに PixiJS Examples のサンプルコードをコピって改造して遊べます。
…おおっと、サンプルコード見てるだけで、あっという間に時間が溶けてしまいますね。楽しいですね!!

HelloWorld行きましょう

前述の『PixiJS入門』読んでると思いますので…え、読んでないの?読んで読んで!!すぐ読んで!
もうしっかりした記事はあるから、こっちは雑に行くので!
あとJavaScriptは使い慣れてる前提で行くので、よろしく!
ちなみに僕は大して慣れてません(笑)

ファイルの準備

とりあえず必要なファイルは以下です。いつも通りのJavaScriptって感じですね。

  • PixiJS の .jsファイル
  • 表示用ページの .html ファイル
  • テストコードを書く .jsファイル

HTMLファイルの<script>タグでPixiJSを読んで、<body>は空でOK。最後にテストコード用の<script>書く感じ。

PixiJS は最新版をダウンロードしておけばいいんですが、僕の場合は『RPGツクールMZ』で使おうと思っているのでバージョンを5.2.4で揃えます。
PixiJS はメジャーバージョンアップでガラリと内容が変わる傾向があるので、バージョン合わせは大切です。
ダウンロードしたファイルでなく、Webにあるファイルを直接指定もできます。楽チンですね。
各種バージョンの CDN(content delivery network)用URLがCDN PixiJSに用意されてますので、お好きなバージョンのURLを <script> に書いて使えばいいです。
5.2.4はCDN PixiJS 5.2.4です。

CDNってのはこういうネットワークを通じてライブラリなど配信する場合に、適切なサーバでキャッシュしたりする仕組みらしいです。
そのおかげで世界中から同一URLのファイルにアクセスしても、スムースにファイルがダウンロードされる…らしいです。

pixi.js が通常のファイルです。 pixi.min.js の方が実行に不要なコメントとか改行とかを取っ払ってあるので軽いです。
pixi.min.js.map ってついてるやつは、pixi.min.js と一緒に置いとくと min のコードを minなしコードに対応づけしてくれる…みたいです(よくわかってない)

開発時に手元にファイルがないのも困るので、該当URLにあるファイルをダウンロードしちゃいます。

GitHubのPixiJSリポジトリ の右にある Releases から辿った GitHub PixiJS Release v5.2.4 からも(というかこっちが普通)ダウンロードできますので、お好みで!

GiuHub の方にはサンプルコードやら各種フィルタやらが用意してあるので、そのうち見て回ることになると思います。

node.js用のパッケージも用意してありますので、そっちがいい人はそっちを…というか、そっちがいい人はこんな記事を読まなくても以下略。

舞台の設定

先に解説したローカルファイルのエラー回避方法のお好きなやつでブラウザ立ち上げて、HTMLファイルを開きます。
もう先の『PixiJS入門』で体験済みだと思うので、ざっと流す感じでコード書いて行きます。

const app = new PIXI.Application();

この PIXI.Application ってクラスは v5で導入されたもの。
v4までは必要なクラスのインスタンスをいくつも生成・保持しなきゃいけなくて面倒臭かったのを、これ一つを作れば必要なインスタンスを生成してプロパティに保持してくれます。
以下のプロパティ(members)がそうです。

プロパティ 説明
renderer (WebGL)描画部分
stage PixiJS の画像データオブジェクトを配置するコンテナ
ticker 描画のタイマー(フレーム)管理
view 描画する canvas 要素
loader ファイル読み込み管理

要は、何をするにもPIXI.Applicationインスタンス(ここではapp )を起点にやっていけばいいのです。
楽チンです!!

document.body.appendChild(app.view);

view には <canvas>(HTMLCanvasElement)が入ってますので、それをHTMLの <body> に追加しちゃうわけです。
なので、HTML側は空でよかったんですね。
もちろん、すでにHTMLに用意してある <canvas>を設定することもできますし、適当な id をつけた要素に追加してもいいです。
この辺は普通のブラウザ用 JavaScriptなので、お好みでどうぞプリーズ。

舞台に役者を配置する

PixiJSは影絵芝居のような仕組みになっていて、 スクリーンが view で、舞台である stage はスクリーンの奥にあって、ライトである renderer に照らされて、最終的にスクリーンに映像が表示される、という感じです。
ここまでの仕組みはPIXI.Application が用意してくれているので、次は stage に乗せる舞台背景や人形(オブジェクト)が必要ということです。

影絵でなくて、撮影台(stage)に置いたアニメ用のセル(オブジェクト)を撮影(renderer)、フィルムにしてスクリーン(view)に映写する方が、イメージは近いかもしれません…お好みの脳内イメージで!!

さて、これはPixiJSのクラスツリーの一部なんですが、PIXI.DisplayObject 以下は全部画面表示用のクラスです。
さっきのたとえで行けば、ステージの上の影絵の背景や人形(あるいは背景とセル)に当たるやつです。

いっぱいあって思わずキョドッてしまいますが PIXI.Text 使ってみますかね。うわぁメッシュ変形らしきもの PIXI.Mesh もあるぞ(目移り)
プログラミングは"Hello World!"と画面に出すのがお約束ですし、まず影絵芝居でもお話のタイトル文字を出さないとですねっ!!
僕の場合"Hello World!"やると、そこで満足して学習やめちゃうパターンが多くて、あんまり縁起良くないですが(笑)

const titleText = new PIXI.Text( "Hello World" );
app.stage.addChild( titleText );

とまぁ、こんな感じでしょうか。
さっきは appendChild() だったのに今度は addChild() なのなんなの?と思いますが…前に理由を調べたと思うんだけど、なんでだったか忘れてしまいました。
たぶん DOM と JavaScriptオブジェクトを区別するような意味合いだったと思います。勘ですけど!

では、コードをひとつにまとめて実行してみましょう。

const app = new PIXI.Application();
document.body.appendChild(app.view);
const titleText = new PIXI.Text( "Hello World!" );
app.stage.addChild( titleText );

あれ?表示されません。あー、Application の背景色の規定値が黒で、文字の規定値も黒だから「闇夜のカラス」になってるのか。
ここは、背景か文字かの色を変えましょう。

const app = new PIXI.Application( { backgroundColor: 0x003333 } );
document.body.appendChild( app.view );
const titleText = new PIXI.Text( "Hello World!", { fill: 0xffffff } );
app.stage.addChild( titleText );

緑と白に変えて黒板っぽく。
そしてこの文字のスタイルは PIXI.TextStyleオブジェクトでも指定できます。
このクラスを見れば、具体的にどんなスタイルが設定できるかわかって便利ですね。
設定できる項目が大量にあってクラクラしますが。

const app = new PIXI.Application( { backgroundColor: 0x003333 } );
document.body.appendChild( app.view );
const textStyle = new PIXI.TextStyle( { fill: 0xffffff } )
const titleText = new PIXI.Text( "Hello World!", textStyle );
app.stage.addChild( titleText );

表示できるテキストは長文OKで改行も含められますが、途中でスタイルを変えることはできないみたいです。
canvasに直接書くなら、getContext( "2d" )CanvasRenderingContext2D 取って fillText()する手がありますが、PIXI.Displayobject に文字をテキストフィールドみたいに書く方法はないのかなぁ。
PIXI.Graphics にも文字描画メソッドないし。PIXI.Textオブジェクトをいっぱい並べるのも管理面倒くさい気もします。
シューティングゲームで鬼弾幕表示するよりは軽そうだからいいだろ、という話もありますが。

ただこのPIXI.Text、文字を生成する際は WebGL を使わず Canvas で生成してるみたいです、というか WebGL に文字表示の機能はなかったはず。
一旦生成してしまえば、もはやラスタ画像なので WebGL で描画されます。
また PIXI.Textはインスタンス生成後も文字やスタイルは変更可能で、変更したらやっぱり Canvas で生成するので負荷がかかっちゃいます。
文字を大量に動かしたりする場合は、頻繁に生成せずに済むような作りにするのが良さそうです。

ちなみに PixiJS はベクター画像の SVGファイルも扱えますが、読み込んだ時点でラスタ変換するようです。

役者を動かす

てなわけで、さらにコードを追加して文字を動かしてみました。

titleText.position.set( 350, 300 );
app.ticker.add( delta => {
    titleText.rotation += 0.05 * ( 1 + delta );
} );

見れば大体わかると思いますが、ちょっとだけ説明。
titleText.position.set( 350, 300 ) は次のコードとやってることは一緒です。お好みで!

titleText.x = 350;
titleText.y = 300;

delta は描画が重くなって呼び出しが1フレーム(1/60秒)に間に合わなくなった場合の差分です。通常は 0 で、よほど処理が大変でない限り 2 以上は返ってきません。
単純にアニメーションする場合はこのコードのように時間が飛んだ分、描画位置を先に進めた方がスムースに見えていいのです。
ただし、アクションゲームでこれやると画像が飛んで「敵とぶつかった画像が画面に出ないのにいきなり爆発する」みたいな酷いことになるので、deltaの値は使わずにアニメーションを遅くした方が、はるかにマシです。

回転軸を文字の中心にもってきたり titleText.anchor.set(0.5)、位置を移動させたり titleText.x++ して遊ぶといいと思います。
PixiJSはあくまでも2Dの描画のためのライブラリであって、アニメーション機能は最低限しかありません。
なので、もうちょっと複雑なことやりたい場合は、さらにJavaScriptライブラリを追加するといいでしょう。
『PixiJS入門』に GSAP(Green Sock Animation Platoform) の TweenMaxモジュールのこと書いてありましたね(丸投げ)

2D描画専用と言いつつ、一応、簡単な衝突チェックとUIのための入力イベント処理は持ってるみたいです。
それから、擬似3D的な技術も使えるみたい。
この辺は後で調べてみるかもみないかもしれません。

まとめ

PixiJS とりあえず動かすところまでは、結構ハードル低い環境って感じですね。
ただ、僕の場合『RPGツクールMV』手に入れた頃に、一度やろうと思って挫折してるんですよね。
うーん、どこに挫折ポイントがあったのか思い出せない。
たぶん『PixiJS入門』がなかったせいでしょう。
よくある「うわぁ、英語だよめんどくせぇ症候群」にかかったに違いありません。

ならしょうがないね!!

とゆーわけで、さらに色々やろうとすると再発の危険がデンジャラスです。
いい日本語のページ見つけたら、教えてください! (素直に英語読みなさい)

Discussion