本文へスキップ

スプライト ​

draw.sprite(frameOrImage, x, y, options?) は、画像またはその一部を指定した位置に描きます。たいていのゲームで一番よく呼ぶ関数で、アロケーションを起こしません。

ts
// 画像全体を (160, 90) を中心に
draw.sprite(hero, 160, 90);
draw.sprite(hero, 160, 90, { rotation: 0.3, tint: "#f0f" }); // 回転してティント

画像とフレーム ​

第1引数は画像(HTMLImageElement、HTMLCanvasElement、OffscreenCanvas、ImageBitmap、またはレンダーターゲット)か、画像の矩形を表す Frame({ image, x, y, w, h })です。

ts
import type { Frame } from "spryte";

const sheet = await load("/hero-sheet.png"); // load() は「はじめる」のもの

// 16×16 グリッド上の4フレームの歩行サイクル
const walk: Frame[] = [0, 1, 2, 3].map((i) => ({ image: sheet, x: i * 16, y: 0, w: 16, h: 16 }));

function render(time: number) {
  const frame = walk[Math.floor(time / 100) % walk.length]!;
  draw.sprite(frame, player.x, player.y);
}

テクスチャアトラスも同じです。アトラスのデータから領域ごとに Frame を1つずつ作り、すべて同じ image を指すようにします。

オプション ​

オプションデフォルト
origin[0.5, 0.5]フレームサイズに対する割合で指定するアンカー。[0, 0] は左上、[0.5, 1] は下端の中央です。
scaleX、scaleY1各軸の拡大率。
rotation0原点を中心とした回転(ラジアン)。
flipX、flipYfalse原点を中心に軸で反転。
alpha1不透明度。グローバルな draw.alpha と掛け合わされます。
tint白乗算する色。
flash0白へ寄せる度合い(0〜1)。被弾時のフラッシュ用です。
smoothdraw.smoothこのスプライトだけのリニアフィルタリング。
ts
// 地面に立ち、左を向き、被弾後にフラッシュするキャラクター
draw.sprite(frame, x, groundY, {
  origin: [0.5, 1],
  flipX: facing < 0,
  flash: hitTimer > 0 ? 1 : 0,
});

// 脈打つコイン
const pulse = 1 + Math.sin(t * 8) * 0.1;
draw.sprite(coin, x, y, { scaleX: pulse, scaleY: pulse });

// 幽霊:半透明で青くティント
draw.sprite(ghost, x, y, { alpha: 0.5, tint: "#88aaff" });

tint には spryte のどの色形式も使えます。"#rgb"、"#rgba"、"#rrggbb"、"#rrggbbaa"、数値 0xRRGGBBAA、または任意の CSS カラーです。色を参照してください。

オプションオブジェクトを使い回す ​

sprite() はオプションを読むだけで保持しないので、ホットループではスプライトごとに作らず、1つのオブジェクトを使い回してください。

ts
import type { SpriteDrawOptions } from "spryte";

const opts: SpriteDrawOptions = { rotation: 0, alpha: 1 };

for (const enemy of enemies) {
  opts.rotation = enemy.angle;
  opts.alpha = enemy.fade;
  draw.sprite(enemyFrame, enemy.x, enemy.y, opts);
}

オプションなしの draw.sprite(img, x, y) もアロケーションを起こしません。

描画順 ​

呼び出し順がそのまま描画順です。後の呼び出しが前のものの上に描かれます。z-index もシーングラフもないので、描きたいレイヤーの順に描いてください。

ts
draw.begin("#000", 320, 180, scale);
drawBackground();
for (const e of enemies) draw.sprite(enemyFrame, e.x, e.y);
draw.sprite(playerFrame, player.x, player.y);
drawHud();
draw.end();

奥行きでソートしたいなら、ループの前に自分の配列をソートします。呼び出しは spryte が自動でバッチ処理します。1フレームに何回 GPU 呼び出しをしたかは draw.drawCalls でわかります。

ピクセルスナップ ​

smooth がオフのとき、回転していないスプライトは整数ピクセル上に配置されます。小数の位置で最近傍サンプリングをすると、フレームごとに輪郭が1ピクセル増えたり減ったりして、ちらつきに見えるからです。回転したスプライトはスナップされません。詳しくはドット絵を参照してください。

ピクセルの変更 ​

canvas から描画していて、そのピクセルを変えた場合は、draw.invalidate(canvas) を呼んで再アップロードします。変化しない画像には何も必要ありません。

次へ:一括スプライト