mcpField
T
text-and-bitmaptext

text-and-bitmaptext

github.com/phaserjs開発40.6k841 回インストール10 週間前に更新
リポジトリ

text-and-bitmaptext について

ゲーム開発者向けの Phaser 4 テキストと BitmapText のガイドです。スタイルやレイアウトに加え、Canvas テキスト、静的・動的ビットマップテキストの使い分けを解説します。

主な機能

  1. 01Canvas テキストのスタイル設定
  2. 02折り返し、配置、パディングの設定
  3. 03静的・動的 BitmapText の利用
  4. 04テキスト境界と文字情報の確認

活用シーン

  1. 01スタイル付きのゲームラベルやタイトルの作成
  2. 02頻繁に更新されるスコアやタイマーの表示
  3. 03個々の文字へのアニメーション適用

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/phaserjs/phaser --skill text-and-bitmaptext

インストール後、Claude Code で/text-and-bitmaptextを入力して読み込まれたか確認します。

詳細

テキストと BitmapText

Phaser 4 でのテキスト表示 -- Canvas ベースの Text ゲームオブジェクト、TextStyle の設定、ワードラップ、BitmapText(静的および動的)、レトロフォント、テキストの配置、テキストの境界、パディング。

主要なソースパス: src/gameobjects/text/、src/gameobjects/bitmaptext/static/、src/gameobjects/bitmaptext/dynamic/ 関連スキル: ../loading-assets/SKILL.md、../sprites-and-images/SKILL.md、../game-object-components/SKILL.md

クイックスタート

// Canvas-based Text (flexible styling, uses browser fonts)
const title = this.add.text(400, 50, 'Hello World', {
    fontFamily: 'Arial',
    fontSize: '32px',
    color: '#ffffff'
});

// BitmapText (pre-rendered font texture, faster rendering)
// Font must be loaded first: this.load.bitmapFont('myFont', 'font.png', 'font.xml')
const score = this.add.bitmapText(400, 100, 'myFont', 'Score: 0', 32);

// DynamicBitmapText (per-character manipulation via callback)
const fancy = this.add.dynamicBitmapText(400, 200, 'myFont', 'Wavy!', 32);
fancy.setDisplayCallback(function (data) {
    data.y += Math.sin(data.index * 0.5 + fancy.scene.time.now * 0.005) * 10;
    return data;
});

コアコンセプト

Text と BitmapText
機能TextBitmapTextDynamicBitmapText
レンダリング方式Canvas 2D API、テクスチャとしてアップロード事前レンダリングされたフォントテクスチャ事前レンダリングされたフォントテクスチャ
Web/CSS フォント可不可不可
シャドウ、グラデーション、ストローク可(Canvas API)ドロップシャドウのみ(WebGL)不可
ワードラップ組み込み(width、callback、advanced)setMaxWidthsetMaxWidth
文字単位のエフェクト不可setCharacterTint、setWordTint(WebGL)setDisplayCallback
パフォーマンス低速(変更時にキャンバステクスチャを再作成)高速(バッチレンダリング)中程度(文字ごとにコールバック)
配置left、right、center、justifyALIGN_LEFT (0)、ALIGN_CENTER (1)、ALIGN_RIGHT (2)BitmapText と同じ
RTL サポート可(rtl スタイルオプション)不可不可

経験則: 柔軟なスタイリング、Web フォント、または更新頻度の低い UI 要素には Text を使用します。スコア、タイマー、頻繁に更新されるもの、または大量にレンダリングされるものには BitmapText を使用します。文字単位のアニメーションエフェクトが必要な場合にのみ DynamicBitmapText を使用します。

TextStyle

Text ゲームオブジェクトはすべてのスタイリングを TextStyle インスタンスに委譲し、text.style でアクセスできます。Text の作成時にスタイル設定オブジェクトを渡すか、後でセッターメソッドで更新します。スタイルオブジェクトは内部的に Canvas 2D プロパティを使用します。

fontFamily のデフォルトは 'Courier'、fontSize のデフォルトは '16px'、color のデフォルトは '#fff' です。font 省略プロパティ(例: 'bold 24px Arial')を指定すると、fontFamily、fontSize、fontStyle が上書きされます。

一般的なパターン

基本的なテキストの作成
// Simple text with inline style
const label = this.add.text(100, 100, 'Player 1', {
    fontFamily: 'Georgia',
    fontSize: '24px',
    color: '#00ff00'
});

// Using the font shorthand (sets fontStyle, fontSize, fontFamily)
const bold = this.add.text(100, 150, 'Bold Text', {
    font: 'bold 28px Arial'
});

// Array of strings creates multi-line text
const multi = this.add.text(100, 200, ['Line 1', 'Line 2', 'Line 3'], {
    fontFamily: 'Arial',
    fontSize: '18px',
    color: '#ffffff'
});

// Text origin defaults to (0, 0) -- top-left corner
label.setOrigin(0.5); // center the text on its position
テキストのスタイリング
const text = this.add.text(400, 300, 'Styled', {
    fontFamily: 'Verdana',
    fontSize: '48px',
    color: '#ff0000',
    stroke: '#000000',
    strokeThickness: 4,
    backgroundColor: '#333333',
    shadow: { offsetX: 2, offsetY: 2, color: '#000', blur: 4, stroke: false, fill: true }
});

// Modify style after creation (all return `this` for chaining)
text.setColor('#00ffff');
text.setFontSize(64);
text.setFontFamily('Courier');
text.setFontStyle('italic');
text.setStroke('#ff00ff', 6);
text.setShadow(3, 3, '#000', 5, false, true);
text.setBackgroundColor('#222');

// Replace entire style at once
text.setStyle({ fontSize: '64px', fontFamily: 'Arial', color: '#ffffff', align: 'center' });

// Canvas gradients and patterns work as fill/stroke
const gradient = text.context.createLinearGradient(0, 0, 0, text.height);
gradient.addColorStop(0, '#ff0000');
gradient.addColorStop(1, '#0000ff');
text.setFill(gradient);
ワードラップ
// Basic word wrap by pixel width
const wrapped = this.add.text(50, 50, 'Long text here...', {
    fontFamily: 'Arial',
    fontSize: '20px',
    color: '#fff',
    wordWrap: { width: 300 }
});

// Or set after creation
wrapped.setWordWrapWidth(300);

// Advanced wrap (collapses spaces, trims whitespace)
wrapped.setWordWrapWidth(300, true);

// Custom word wrap callback
wrapped.setWordWrapCallback(function (text, textObject) {
    // Return wrapped text as string with \n or array of lines
    return text.split(' ').join('\n');
});

// Get wrapped lines as array
const lines = wrapped.getWrappedText();
テキストの配置
// Alignment only affects multi-line text: 'left' (default), 'right', 'center', 'justify'
const aligned = this.add.text(400, 100, 'Line 1\nLonger Line 2\nLine 3', {
    fontFamily: 'Arial', fontSize: '24px', color: '#fff', align: 'center'
});

aligned.setAlign('right');

// For center alignment to look correct, combine with fixedWidth:
aligned.setFixedSize(300, 0);
aligned.setAlign('center');
動的なテキスト更新
const scoreText = this.add.text(10, 10, 'Score: 0', {
    fontFamily: 'Arial',
    fontSize: '24px',
    color: '#fff'
});

// setText replaces content (accepts string or string[])
scoreText.setText('Score: 100');
scoreText.setText(['Score: 100', 'Lives: 3']); // joins with \n

// appendText adds to existing content
scoreText.appendText('Extra line');          // prepends \n by default
scoreText.appendText(' more', false);        // no carriage return

// Read current text
const current = scoreText.text;
テキストのパディング
// Padding adds space around text inside the canvas
const padded = this.add.text(100, 100, 'Padded', {
    fontFamily: 'Arial', fontSize: '24px', color: '#fff',
    backgroundColor: '#333',
    padding: { left: 10, right: 10, top: 5, bottom: 5 }
});

padded.setPadding({ x: 10, y: 5 });       // shorthand: x=left+right, y=top+bottom
padded.setPadding(10, 5, 10, 5);           // left, top, right, bottom
padded.setPadding(10);                     // single value = all sides
固定サイズ、最大行数、および行間
// Fixed dimensions create a text canvas of exact size
const fixed = this.add.text(100, 100, 'Fixed box', {
    fontFamily: 'Arial', fontSize: '18px', color: '#fff',
    fixedWidth: 200, fixedHeight: 100,
    wordWrap: { width: 200 }, align: 'center'
});
fixed.setMaxLines(3); // limit displayed lines

// Line and letter spacing (in style config or via setters)
const spaced = this.add.text(100, 200, 'Spaced\nLines', {
    fontFamily: 'Arial', fontSize: '24px', color: '#fff',
    lineSpacing: 10, letterSpacing: 2
});
spaced.setLineSpacing(20);
spaced.setLetterSpacing(5);
BitmapText の作成
// Load in preload: this.load.bitmapFont('pixelFont', 'font.png', 'font.xml');

// Static BitmapText -- fast, batched rendering
const bmpText = this.add.bitmapText(100, 100, 'pixelFont', 'Hello', 32);

// With alignment (for multi-line)
const aligned = this.add.bitmapText(100, 200, 'pixelFont', 'Line 1\nLine 2', 24, 1);
// align: 0 = left, 1 = center, 2 = right

// Convenience alignment methods
bmpText.setLeftAlign();
bmpText.setCenterAlign();
bmpText.setRightAlign();

// Modify text
bmpText.setText('Updated!');
bmpText.text = 'Also works';

// Font size
bmpText.setFontSize(48);
bmpText.fontSize = 48;

// Spacing
bmpText.setLetterSpacing(2);
bmpText.setLineSpacing(5);

// Word wrap by max pixel width
bmpText.setMaxWidth(200);
BitmapText のドロップシャドウとティント
// Drop shadow (WebGL only, static BitmapText only)
bmpText.setDropShadow(2, 2, 0x000000, 0.5);
// Clear shadow
bmpText.setDropShadow();

// Tint individual characters (WebGL only)
bmpText.setCharacterTint(0, 5, Phaser.TintModes.MULTIPLY, 0xff0000);
// start index, length (-1 for all from start), tintMode, color

// Tint by word (string match or word index)
bmpText.setWordTint('Score', -1, Phaser.TintModes.MULTIPLY, 0x00ff00);
DynamicBitmapText
const dynamic = this.add.dynamicBitmapText(100, 100, 'pixelFont', 'Dynamic!', 32);

// Per-character display callback -- invoked each render frame per character
dynamic.setDisplayCallback(function (data) {
    // data properties: parent, tint, index, charCode, x, y, scale, rotation, data
    data.x += Math.sin(data.index + dynamic.scene.time.now * 0.01) * 5;
    data.y += Math.cos(data.index + dynamic.scene.time.now * 0.01) * 5;
    return data;
});

// Scrolling text window
dynamic.setSize(200, 50);      // crop region in pixels
dynamic.setScrollX(10);
dynamic.setScrollY(0);
レトロフォント

レトロフォントは、標準的な画像からの固定幅文字グリッドを使用します(XML/JSON フォントファイルは不要です)。

// In preload -- load the image containing the font characters
this.load.image('retroFont', 'retroFont.png');

// In create -- parse the retro font configuration
const config = {
    image: 'retroFont',
    width: 8,           // character width in pixels
    height: 8,          // character height in pixels
    chars: Phaser.GameObjects.RetroFont.TEXT_SET1,
    charsPerRow: 16,
    offset: { x: 0, y: 0 },
    spacing: { x: 0, y: 0 },
    lineSpacing: 0
};

// Parse adds it to the BitmapFont cache
this.cache.bitmapFont.add('retroFont', { data: Phaser.GameObjects.RetroFont.Parse(this, config) });

// Now use it like any BitmapText
const retro = this.add.bitmapText(100, 100, 'retroFont', 'RETRO TEXT', 8);

使用可能な Phaser.GameObjects.RetroFont TEXT_SET 定数: TEXT_SET1(ASCII 印刷可能文字全体)、TEXT_SET2(スペースから Z まで)、TEXT_SET3〜TEXT_SET11(大文字、数字、句読点のさまざまなサブセット)。TEXT_SET10 は大文字のみです。

テキストの境界(BitmapText)
// getTextBounds returns local, global, line, word, and character data
const bounds = bmpText.getTextBounds();
// bounds.local       -- { x, y, width, height } at origin 0,0
// bounds.global      -- { x, y, width, height } with scale + world position
// bounds.lines       -- per-line { x, y, width, height }
// bounds.words       -- word objects with positions
// bounds.characters  -- character objects with positions

// width/height are read-only properties (computed from global bounds)
console.log(bmpText.width, bmpText.height);

// Get character at world position (useful for click detection)
const char = bmpText.getCharacterAt(pointer.worldX, pointer.worldY);
解像度(高 DPI)
// Higher resolution for crisp text on HiDPI displays (costs more memory)
const crisp = this.add.text(100, 100, 'Sharp!', {
    fontFamily: 'Arial', fontSize: '24px', color: '#fff', resolution: 2
});
crisp.setResolution(window.devicePixelRatio); // change after creation

設定リファレンス

TextStyle のプロパティ
プロパティ型デフォルト説明
fontFamilystring'Courier'CSS フォントファミリー
fontSizestring/number'16px'フォントサイズ(数値の場合は自動的に 'px' が付加されます)
fontStylestring''CSS フォントスタイル('bold'、'italic'、'bold italic')
fontstring-省略記法: 'bold 24px Arial'(family/size/style を上書きします)
colorstring/CanvasGradient/CanvasPattern'#fff'塗りつぶしの色
strokestring/CanvasGradient/CanvasPattern'#fff'ストロークの色
strokeThicknessnumber0ストロークの幅(0 = ストロークなし)
backgroundColorstringnull単色の背景色
alignstring'left'複数行の配置: 'left'、'right'、'center'、'justify'
maxLinesnumber0描画する最大行数(0 = 無制限)
fixedWidthnumber0固定のキャンバス幅(0 = 自動)
fixedHeightnumber0固定のキャンバス高さ(0 = 自動)
resolutionnumber0キャンバスの解像度(0 = ゲーム設定を使用)
rtlbooleanfalse右から左への描画
baselineXnumber1.2フォントメトリクスの水平方向のパディング
baselineYnumber1.4フォントメトリクスの垂直方向のパディング
testStringstring'|MEqgy'フォントの高さの測定に使用する文字列
wordWrapobject-{ width, callback, callbackScope, useAdvancedWrap }
shadowobject-{ offsetX, offsetY, color, blur, stroke, fill }
paddingobject-{ left, right, top, bottom } または { x, y }
lineSpacingnumber0行間の追加の垂直方向の間隔
letterSpacingnumber0文字間の追加の水平方向の間隔
metricsobject-測定を省略するための事前計算済みの { ascent, descent, fontSize }

ファクトリメソッド

// Text -- Canvas-based
this.add.text(x, y, text, style);
// x, y: number; text: string | string[]; style: TextStyle (optional)
// Returns: Phaser.GameObjects.Text

// BitmapText -- static, fast
this.add.bitmapText(x, y, font, text, size, align);
// x, y: number; font: string (cache key); text: string | string[] (optional)
// size: number (optional, defaults to font data size); align: number (optional, 0)
// Returns: Phaser.GameObjects.BitmapText

// DynamicBitmapText -- per-character callback
this.add.dynamicBitmapText(x, y, font, text, size);
// Same as bitmapText but returns DynamicBitmapText
// Returns: Phaser.GameObjects.DynamicBitmapText

API クイックリファレンス

Text のメソッド

setText(value), appendText(value, addCR?), setStyle(style), setFont(font), setFontFamily(family), setFontSize(size), setFontStyle(style), setColor(color), setFill(color), setStroke(color, thickness), setShadow(x, y, color, blur, stroke, fill), setBackgroundColor(color), setWordWrapWidth(width, useAdvanced?), setWordWrapCallback(callback, scope?), setAlign(align), setPadding(left, top?, right?, bottom?), setFixedSize(width, height), setMaxLines(max), setLineSpacing(value), setLetterSpacing(value), setResolution(value), setRTL(rtl?), getWrappedText(text?), updateText()

すべてのセッターはチェーン用に this を返します。プロパティ: text(get/set)、style(TextStyle インスタンス)、padding、lineSpacing、letterSpacing、autoRound、splitRegExp。

BitmapText のメソッド

setText(value), setFont(font, size?, align?), setFontSize(size), setLetterSpacing(spacing?), setLineSpacing(spacing?), setMaxWidth(value, wordWrapCharCode?), setLeftAlign(), setCenterAlign(), setRightAlign(), setDropShadow(x?, y?, color?, alpha?), setCharacterTint(start?, length?, tintMode?, tl?, tr?, bl?, br?), setWordTint(word, count?, tintMode?, tl?, tr?, bl?, br?), getTextBounds(round?), getCharacterAt(x, y, camera?)

プロパティ(get/set): text、fontSize、letterSpacing、lineSpacing、align(数値)、maxWidth。読み取り専用: width、height、font、fontData。

配置の定数: BitmapText.ALIGN_LEFT(0)、BitmapText.ALIGN_CENTER(1)、BitmapText.ALIGN_RIGHT(2)。

DynamicBitmapText のメソッド(追加分)

setDisplayCallback(callback), setSize(width, height), setScrollX(value), setScrollY(value)

プロパティ: scrollX、scrollY、cropWidth、cropHeight、displayCallback、callbackData。

注意点

  1. テキストは変更のたびに再レンダリングされます。 setText、setStyle、setColor などを呼び出すたびに、内部キャンバスが再作成され、(WebGL では) テクスチャが再アップロードされます。スタイルの変更はまとめて行い、updateText() を一度だけ呼び出すか、スタイルオブジェクトのプロパティを直接設定して最後に updateText() を呼び出してください。

  2. フォントは使用前に読み込む必要があります。 Text オブジェクトは Canvas の fillText API を使用するため、フォントがブラウザで利用可能である必要があります (CSS、Web フォントローダー経由で読み込むか、すでにインストールされているか)。Phaser は Web フォントを読み込みません。サードパーティ製のローダーか CSS の @font-face を使用してください。

  3. 特殊文字を含むフォント名は引用符で囲む必要があります。 数字や特殊文字を含むフォント名は、文字列内で二重引用符で囲む必要があります: fontFamily: '"Press Start 2P"'。

  4. テキストの原点はデフォルトで (0, 0) です。 デフォルトが (0.5, 0.5) である Sprite とは異なり、Text オブジェクトのデフォルトの原点は左上です。中央揃えにするには setOrigin(0.5) を呼び出してください。

  5. 配置は複数行のテキストにのみ影響します。 align: 'center' は 1 行のテキストには効果がありません。1 行を中央揃えにするには、setOrigin(0.5) を使用するか手動で配置してください。

  6. BitmapText のフォントはキャッシュに存在する必要があります。 this.add.bitmapText() に渡すフォントキーは、this.load.bitmapFont() で読み込まれたキーと一致する必要があります。存在しない場合、コンソールに警告が表示され、未定義の動作になります。

  7. BitmapText の setMaxWidth は空白でのみ折り返します。 空白文字 (デフォルトの文字コード 32 = スペース) が見つからない場合、折り返しは行われません。折り返し文字を変更するには、setMaxWidth の第 2 引数を使用してください。

  8. DynamicBitmapText はより高コストです。 表示コールバックは毎フレーム、すべての文字に対して実行されます。文字単位の操作が必要な場合にのみ使用してください。

  9. setCharacterTint と setWordTint は WebGL 専用です。 これらは Canvas レンダラーでは効果がありません。

  10. setDropShadow は WebGL 専用で、静的 BitmapText 専用です。 DynamicBitmapText や Canvas レンダラーでは動作しません。

  11. Text の letterSpacing は高コストです。 ゼロ以外の場合、Phaser は行全体を一度に描画するのではなく、fillText で各文字を個別にレンダリングします。カスタムの文字間隔を持つ大量のテキストには BitmapText を使用してください。

  12. setFill と setColor は同等です。 どちらも TextStyle の color プロパティを設定します。スタイル設定では color のエイリアスとして fill も受け付けます。

  13. setRTL は setText より前に呼び出す必要があります。 右から左へのモードは、内部キャンバスの構築方法を変更します。テキストを設定した後に setRTL(true) を呼び出すと、テキストが正しくレンダリングされない可能性があります。RTL はスタイル設定で設定するか、setText() を呼び出す前に setRTL() を呼び出してください。

  14. 頻繁に更新されるコンテンツには BitmapText がはるかに高速です。 Text は変更のたびに Canvas 全体を再レンダリングし、GPU テクスチャを再アップロードします。BitmapText は既存のテクスチャアトラスの頂点データを更新するだけです。スコア、タイマー、ダメージ数値など、毎フレーム変化するテキストには、常に BitmapText を優先してください。

ソースファイルマップ

ファイル説明
src/gameobjects/text/Text.jsText クラス(Canvas ベースのレンダリング)
src/gameobjects/text/TextFactory.jsthis.add.text() ファクトリ
src/gameobjects/text/TextStyle.jsTextStyle クラス(すべてのスタイルプロパティ + セッター)
src/gameobjects/text/GetTextSize.js内部テキスト計測
src/gameobjects/text/MeasureText.jsフォントメトリクスの計測
src/gameobjects/text/typedefs/TextStyle、TextWordWrap、TextPadding、TextShadow の型定義
src/gameobjects/bitmaptext/static/BitmapText.js静的 BitmapText クラス
src/gameobjects/bitmaptext/static/BitmapTextFactory.jsthis.add.bitmapText() ファクトリ
src/gameobjects/bitmaptext/dynamic/DynamicBitmapText.jsDynamicBitmapText(BitmapText を継承)
src/gameobjects/bitmaptext/dynamic/DynamicBitmapTextFactory.jsthis.add.dynamicBitmapText() ファクトリ
src/gameobjects/bitmaptext/ParseRetroFont.jsレトロフォントパーサー(RetroFont.Parse)
src/gameobjects/bitmaptext/RetroFont.jsRetroFont 名前空間(Parse + TEXT_SET 定数)
src/gameobjects/bitmaptext/const.jsTEXT_SET1 から TEXT_SET11 までの定数
src/gameobjects/bitmaptext/GetBitmapTextSize.jsBitmapText の境界計算
src/gameobjects/bitmaptext/typedefs/RetroFontConfig、DisplayCallbackConfig、BitmapTextSize の型定義

コメント