@robingamedev/visual-novel-dialogue
Version:
A minimal, JSON-driven dialogue plugin for Phaser 3 games with support for branching choices, typewriter effects, and simple inline formatting.
105 lines • 3.52 kB
JavaScript
import { GameObjects } from 'phaser';
export class DialogueBox extends GameObjects.Container {
constructor(scene, config) {
super(scene);
this.config = config;
// Default dimensions and style
const width = 600;
const height = 140;
const padding = 24;
const boxColor = 0x222244;
const boxAlpha = 0.92;
// Background
this.background = scene.add.rectangle(0, 0, width, height, boxColor, boxAlpha);
this.background.setOrigin(0, 0);
this.add(this.background);
// Text
this.text = scene.add.text(padding, padding, '', {
fontFamily: config.fontFamily || 'Arial',
fontSize: '24px',
color: '#fff',
wordWrap: { width: width - padding * 2 },
});
this.text.setOrigin(0, 0);
this.add(this.text);
// Set position based on config
this.setBoxPosition(config.boxPosition || 'bottom', scene.scale.width, scene.scale.height, width, height);
scene.add.existing(this);
this.setDepth(1000); // Ensure on top
}
setBoxPosition(position, screenW, screenH, boxW, boxH) {
let x = (screenW - boxW) / 2;
let y = 0;
if (position === 'bottom') {
y = screenH - boxH - 32;
}
else if (position === 'top') {
y = 32;
}
else if (position === 'center') {
y = (screenH - boxH) / 2;
}
this.setPosition(x, y);
}
setText(text) {
// Reset to default style before setting new text
this.resetTextStyle();
this.text.setText(text);
}
setTextWithStyle(text, style) {
if (style) {
// Apply individual style properties
if (style.color) {
this.text.setColor(style.color);
}
if (style.bold) {
this.text.setFontStyle('bold');
}
if (style.italic) {
this.text.setFontStyle('italic');
}
if (style.fontSize) {
this.text.setFontSize(`${style.fontSize}px`);
}
// Debug logging
console.log('Applying style:', style, 'to text:', text);
}
this.text.setText(text);
}
resetTextStyle() {
// Reset to default using individual setters
this.text.setColor('#fff');
this.text.setFontStyle('normal');
this.text.setFontSize('24px');
console.log('Reset text style to default');
}
setNameplate(name, color) {
if (!this.nameplate) {
this.nameplate = this.scene.add.text(0, -28, '', {
fontFamily: this.config.fontFamily || 'Arial',
fontSize: '20px',
color: color || '#fff',
fontStyle: 'bold',
backgroundColor: 'rgba(0,0,0,0.5)',
padding: { left: 8, right: 8, top: 2, bottom: 2 },
});
this.nameplate.setOrigin(0, 0);
this.add(this.nameplate);
}
this.nameplate.setText(name);
this.nameplate.setColor(color);
this.nameplate.setVisible(true);
}
hideNameplate() {
if (this.nameplate) {
this.nameplate.setVisible(false);
}
}
destroy(fromScene) {
this.background.destroy();
this.text.destroy();
this.nameplate?.destroy();
super.destroy(fromScene);
}
}
//# sourceMappingURL=DialogueBox.js.map