text-and-bitmaptext について
ゲーム開発者向けの Phaser 4 テキストと BitmapText のガイドです。スタイルやレイアウトに加え、Canvas テキスト、静的・動的ビットマップテキストの使い分けを解説します。
主な機能
- 01Canvas テキストのスタイル設定
- 02折り返し、配置、パディングの設定
- 03静的・動的 BitmapText の利用
- 04テキスト境界と文字情報の確認
活用シーン
- 01スタイル付きのゲームラベルやタイトルの作成
- 02頻繁に更新されるスコアやタイマーの表示
- 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
| 機能 | Text | BitmapText | DynamicBitmapText |
|---|---|---|---|
| レンダリング方式 | Canvas 2D API、テクスチャとしてアップロード | 事前レンダリングされたフォントテクスチャ | 事前レンダリングされたフォントテクスチャ |
| Web/CSS フォント | 可 | 不可 | 不可 |
| シャドウ、グラデーション、ストローク | 可(Canvas API) | ドロップシャドウのみ(WebGL) | 不可 |
| ワードラップ | 組み込み(width、callback、advanced) | setMaxWidth | setMaxWidth |
| 文字単位のエフェクト | 不可 | setCharacterTint、setWordTint(WebGL) | setDisplayCallback |
| パフォーマンス | 低速(変更時にキャンバステクスチャを再作成) | 高速(バッチレンダリング) | 中程度(文字ごとにコールバック) |
| 配置 | left、right、center、justify | ALIGN_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 のプロパティ
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
fontFamily | string | 'Courier' | CSS フォントファミリー |
fontSize | string/number | '16px' | フォントサイズ(数値の場合は自動的に 'px' が付加されます) |
fontStyle | string | '' | CSS フォントスタイル('bold'、'italic'、'bold italic') |
font | string | - | 省略記法: 'bold 24px Arial'(family/size/style を上書きします) |
color | string/CanvasGradient/CanvasPattern | '#fff' | 塗りつぶしの色 |
stroke | string/CanvasGradient/CanvasPattern | '#fff' | ストロークの色 |
strokeThickness | number | 0 | ストロークの幅(0 = ストロークなし) |
backgroundColor | string | null | 単色の背景色 |
align | string | 'left' | 複数行の配置: 'left'、'right'、'center'、'justify' |
maxLines | number | 0 | 描画する最大行数(0 = 無制限) |
fixedWidth | number | 0 | 固定のキャンバス幅(0 = 自動) |
fixedHeight | number | 0 | 固定のキャンバス高さ(0 = 自動) |
resolution | number | 0 | キャンバスの解像度(0 = ゲーム設定を使用) |
rtl | boolean | false | 右から左への描画 |
baselineX | number | 1.2 | フォントメトリクスの水平方向のパディング |
baselineY | number | 1.4 | フォントメトリクスの垂直方向のパディング |
testString | string | '|MEqgy' | フォントの高さの測定に使用する文字列 |
wordWrap | object | - | { width, callback, callbackScope, useAdvancedWrap } |
shadow | object | - | { offsetX, offsetY, color, blur, stroke, fill } |
padding | object | - | { left, right, top, bottom } または { x, y } |
lineSpacing | number | 0 | 行間の追加の垂直方向の間隔 |
letterSpacing | number | 0 | 文字間の追加の水平方向の間隔 |
metrics | object | - | 測定を省略するための事前計算済みの { 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。
注意点
-
テキストは変更のたびに再レンダリングされます。
setText、setStyle、setColorなどを呼び出すたびに、内部キャンバスが再作成され、(WebGL では) テクスチャが再アップロードされます。スタイルの変更はまとめて行い、updateText()を一度だけ呼び出すか、スタイルオブジェクトのプロパティを直接設定して最後にupdateText()を呼び出してください。 -
フォントは使用前に読み込む必要があります。 Text オブジェクトは Canvas の
fillTextAPI を使用するため、フォントがブラウザで利用可能である必要があります (CSS、Web フォントローダー経由で読み込むか、すでにインストールされているか)。Phaser は Web フォントを読み込みません。サードパーティ製のローダーか CSS の@font-faceを使用してください。 -
特殊文字を含むフォント名は引用符で囲む必要があります。 数字や特殊文字を含むフォント名は、文字列内で二重引用符で囲む必要があります:
fontFamily: '"Press Start 2P"'。 -
テキストの原点はデフォルトで (0, 0) です。 デフォルトが (0.5, 0.5) である Sprite とは異なり、Text オブジェクトのデフォルトの原点は左上です。中央揃えにするには
setOrigin(0.5)を呼び出してください。 -
配置は複数行のテキストにのみ影響します。
align: 'center'は 1 行のテキストには効果がありません。1 行を中央揃えにするには、setOrigin(0.5)を使用するか手動で配置してください。 -
BitmapText のフォントはキャッシュに存在する必要があります。
this.add.bitmapText()に渡すフォントキーは、this.load.bitmapFont()で読み込まれたキーと一致する必要があります。存在しない場合、コンソールに警告が表示され、未定義の動作になります。 -
BitmapText の
setMaxWidthは空白でのみ折り返します。 空白文字 (デフォルトの文字コード 32 = スペース) が見つからない場合、折り返しは行われません。折り返し文字を変更するには、setMaxWidthの第 2 引数を使用してください。 -
DynamicBitmapText はより高コストです。 表示コールバックは毎フレーム、すべての文字に対して実行されます。文字単位の操作が必要な場合にのみ使用してください。
-
setCharacterTintとsetWordTintは WebGL 専用です。 これらは Canvas レンダラーでは効果がありません。 -
setDropShadowは WebGL 専用で、静的 BitmapText 専用です。 DynamicBitmapText や Canvas レンダラーでは動作しません。 -
Text の
letterSpacingは高コストです。 ゼロ以外の場合、Phaser は行全体を一度に描画するのではなく、fillTextで各文字を個別にレンダリングします。カスタムの文字間隔を持つ大量のテキストには BitmapText を使用してください。 -
setFillとsetColorは同等です。 どちらも TextStyle のcolorプロパティを設定します。スタイル設定ではcolorのエイリアスとしてfillも受け付けます。 -
setRTLはsetTextより前に呼び出す必要があります。 右から左へのモードは、内部キャンバスの構築方法を変更します。テキストを設定した後にsetRTL(true)を呼び出すと、テキストが正しくレンダリングされない可能性があります。RTL はスタイル設定で設定するか、setText()を呼び出す前にsetRTL()を呼び出してください。 -
頻繁に更新されるコンテンツには BitmapText がはるかに高速です。 Text は変更のたびに Canvas 全体を再レンダリングし、GPU テクスチャを再アップロードします。BitmapText は既存のテクスチャアトラスの頂点データを更新するだけです。スコア、タイマー、ダメージ数値など、毎フレーム変化するテキストには、常に BitmapText を優先してください。
ソースファイルマップ
| ファイル | 説明 |
|---|---|
src/gameobjects/text/Text.js | Text クラス(Canvas ベースのレンダリング) |
src/gameobjects/text/TextFactory.js | this.add.text() ファクトリ |
src/gameobjects/text/TextStyle.js | TextStyle クラス(すべてのスタイルプロパティ + セッター) |
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.js | this.add.bitmapText() ファクトリ |
src/gameobjects/bitmaptext/dynamic/DynamicBitmapText.js | DynamicBitmapText(BitmapText を継承) |
src/gameobjects/bitmaptext/dynamic/DynamicBitmapTextFactory.js | this.add.dynamicBitmapText() ファクトリ |
src/gameobjects/bitmaptext/ParseRetroFont.js | レトロフォントパーサー(RetroFont.Parse) |
src/gameobjects/bitmaptext/RetroFont.js | RetroFont 名前空間(Parse + TEXT_SET 定数) |
src/gameobjects/bitmaptext/const.js | TEXT_SET1 から TEXT_SET11 までの定数 |
src/gameobjects/bitmaptext/GetBitmapTextSize.js | BitmapText の境界計算 |
src/gameobjects/bitmaptext/typedefs/ | RetroFontConfig、DisplayCallbackConfig、BitmapTextSize の型定義 |