ノベルゲームのようにテキストを1文字ずつ表示させるためのクラスDisplayTextByCharを紹介します。
DisplayTextByChar クラス
DisplayTextByCharは、PhaserのTextオブジェクトを拡張し、1文字ずつ表示する機能を追加したクラスです。
クラスのコンストラクタ
このクラスのコンストラクタは以下のパラメータを受け取ります:
scene: テキストを表示するPhaserのシーンオブジェクト。x,y: テキストを表示する位置のX座標とY座標。text: 表示するテキスト。style: テキストのスタイルを定義するオブジェクト(フォントサイズや色など)。delayDef: 各文字の表示間隔をミリ秒で指定します(デフォルトは100ミリ秒)。
クラスの実装
import Phaser from "phaser";
/**
* 文字ごとにテキストを表示するクラス
*/
class DisplayTextByChar extends Phaser.GameObjects.Text {
delayDef: number;
timerEvent: Phaser.Time.TimerEvent;
/**
* コンストラクタ
*/
constructor(
scene: Phaser.Scene,
x: number,
y: number,
text: string,
style: Phaser.Types.GameObjects.Text.TextStyle,
delayDef: number = 100
) {
super(scene, x, y, "", style);
this.delayDef = delayDef;
this.timerEvent = scene.time.addEvent({});
this.setStyle(style);
scene.add.existing(this);
this.startTextAnimation(text);
}
/**
* テキスト表示の遅延時間を更新する
*/
updateDelay(delay: number) {
this.timerEvent.reset({
delay: delay,
repeat: this.timerEvent.repeatCount,
callback: this.timerEvent.callback,
});
}
/**
* 次のテキストを設定する
*/
setNextText(text: string) {
this.text = "";
this.timerEvent.remove();
this.startTextAnimation(text);
}
/**
* テキストをスキップする
*/
skipText() {
this.timerEvent.reset({
delay: 0.1,
repeat: this.timerEvent.repeatCount,
callback: this.timerEvent.callback,
});
}
/**
* テキスト表示が完了したかを確認
*/
isComplete(): boolean {
return this.timerEvent.repeatCount === 0;
}
/**
* テキストアニメーションを開始する
*/
private startTextAnimation(text: string) {
let i = 0;
this.timerEvent = this.scene.time.addEvent({
delay: this.delayDef,
repeat: text.length - 1,
callback: () => {
if (i >= text.length) {
return;
}
this.text += text[i];
i++;
},
});
}
}
export { DisplayTextByChar };
機能の説明
- テキストオブジェクトの作成:
Textオブジェクトを拡張し、指定されたスタイルでテキストを表示します。 - テキストを1文字ずつ表示: Phaserのタイマーイベントを利用し、指定された遅延ごとに1文字ずつ追加します。
- テキストの更新:
setNextTextメソッドで新しいテキストをセットし、アニメーションを再開できます。 - スキップ機能:
skipTextメソッドで表示速度を最速にして、すぐに全文を表示できます。 - 表示完了の判定:
isCompleteメソッドでテキストの表示が終わったかどうかを確認できます。
使用例
以下のコードでDisplayTextByCharを使用してテキストを1文字ずつ表示できます。
import Phaser from 'phaser';
import { DisplayTextByChar } from './DisplayTextByChar';
class MyScene extends Phaser.Scene {
constructor() {
super('MyScene');
}
create() {
const style = { fontSize: '32px', color: '#fff' };
const textObj = new DisplayTextByChar(this, 100, 100, 'Hello, World!', style);
}
}
ページ上部の画像は以下のコードで動いています。
import Phaser from 'phaser';
import { DisplayTextByChar } from './DisplayTextByChar';
const DEFAULT_WIDTH = 640;
const DEFAULT_HEIGHT = 480;
class MyScene extends Phaser.Scene {
constructor() {
super('MyScene');
}
create() {
const style = { fontFamily: 'Arial', fontSize: '32px', color: '#ffffff' };
new DisplayTextByChar(this, DEFAULT_WIDTH / 2, DEFAULT_HEIGHT / 2, 'Hello World!', style).setOrigin(0.5, 0.5);
}
}
このクラスを利用することで、Phaser3で簡単にノベルゲームのようなテキストアニメーションを実装できます。