本文へスキップ

描画 ​

シーンは draw を通して描画します。論理単位で扱うイミディエイトモードの API です。バッチ処理された WebGL2 レンダラーの上で動き、WebGL2 が使えない環境では自動で Canvas 2D にフォールバックします。どちらでもコードは同じです。

ts
render(draw) {
  draw.withCamera(game.camera, () => {
    draw.sprite(heroFrame, hero.x, hero.y, { origin: [0.5, 1], flipX: hero.facingLeft, flash: hero.hurt });
    draw.rect(0, groundY, 320, 8, "#2f3a1f");
    particles.draw(draw);
  });
  draw.text(`score ${score}`, 4, 4, { font: "8px monospace", color: "#cffb2d" });
}

API ​

呼び出し描くもの
sprite(frame | image, x, y, options?)画像、またはスプライトシートのフレーム。オプション:origin、scaleX、scaleY、rotation、flipX、flipY、alpha、tint、flash、smooth
rect(x, y, w, h, color)塗りつぶした矩形
circle(x, y, radius, color)塗りつぶした、アンチエイリアス付きの円
line(x1, y1, x2, y2, width, color)線
text(string, x, y, options?)キャッシュされた、くっきりしたテキスト。オプション:font、color、align、baseline、alpha
push() / pop()、translate、scale、rotate変換スタック
withCamera(camera, fn)カメラの視点で fn を実行
clip(x, y, w, h, fn)矩形の内側にだけ描く(UI パネル、リスト、ミニマップ)。入れ子にできます
alpha、blend("normal" | "add")全体のアルファとブレンドモード
raw{ kind: "webgl2", gl } または { kind: "2d", ctx } の抜け道

色は 16 進文字列("#cffb2d"、"#cffb2d80")、任意の CSS カラー、または数値 0xRRGGBBAA で指定します。

なぜ速いのか ​

すべての呼び出しは GPU バッファの 1 インスタンスになります。1 バッチにつき最大 8 枚のテクスチャをバインドするので、スプライト、テキスト、パーティクルが混ざってもバッチが途切れません。ホットパスではメモリを確保しません。

debuff は spryte で描画しています。レンダラーのベンチマークでは、draw.sprite は PixiJS の Sprite より約 2.8〜3.3 倍速く、50,000〜100,000 個のスプライトを 60 fps で描き続けます。パーティクルや弾幕、群れには draw.sprites(frame, positions, count, options, each?) を使えば、位置を並べた Float32Array を 1 回の呼び出しでまとめて描けます。コピーごとのスケール、回転、色も指定できます。こちらは 60 fps で約 800,000 スプライト を描き、パーティクルごとにすべてのプロパティを変えた場合でも PixiJS の ParticleContainer より 3.8 倍速い 結果です。ノート PC の GPU 1 台での計測なので、目安として見てください(計測方法と注意点)。

バックエンドを選ぶ ​

ts
new Game({ canvas, width, height, renderer: "auto" }); // デフォルト:WebGL2、なければ Canvas 2D
new Game({ canvas, width, height, renderer: "2d" }); // Canvas 2D を強制

game.draw.kind で、どちらが有効かわかります。Canvas 2D では、tint はアルファだけが反映されます。