import { Container, Graphics, Text } from 'pixi.js';
/**
* Универсальное окно диалога: имя говорящего, текст, подсказка «далее».
* Жанронезависимо: игра сама решает, чей это диалог и что идёт дальше.
*/
export interface DialogueLine {
speaker: string;
text: string;
}
export interface DialogueBoxOptions {
/** Виртуальные пиксели. */
width: number;
height: number;
/** Отступы панели от краёв экрана. */
margin: number;
}
export class DialogueBox {
readonly view: Container;
visible = false;
private panel: Graphics;
private nameText: Text;
private bodyText: Text;
private hintText: Text;
constructor(options: DialogueBoxOptions) {
this.view = new Container();
this.view.visible = false;
this.view.eventMode = 'static';
this.panel = new Graphics();
this.nameText = new Text({
text: '',
style: { fontFamily: 'monospace', fontSize: 8, fill: 0xffffcc }
});
this.bodyText = new Text({
text: '',
style: {
fontFamily: 'monospace',
fontSize: 8,
fill: 0xffffff,
wordWrap: true,
wordWrapWidth: options.width - options.margin * 4,
lineHeight: 10
}
});
this.hintText = new Text({
text: 'далее ▸',
style: { fontFamily: 'monospace', fontSize: 8, fill: 0xaaaaaa }
});
this.view.addChild(this.panel, this.nameText, this.bodyText, this.hintText);
this.layout(options);
}
private layout(options: DialogueBoxOptions): void {
const w = options.width;
const h = options.height;
const m = options.margin;
this.panel.rect(m, h - m - 48, w - m * 2, 48).fill({ color: 0x101018, alpha: 0.92 });
this.panel.rect(m, h - m - 48, w - m * 2, 48).stroke({ color: 0x8899aa, width: 1 });
this.nameText.position.set(m + 4, h - m - 44);
this.bodyText.position.set(m + 4, h - m - 34);
this.hintText.position.set(w - m - 40, h - m - 8);
}
show(line: DialogueLine): void {
this.nameText.text = line.speaker;
this.bodyText.text = line.text;
this.view.visible = true;
this.visible = true;
}
hide(): void {
this.view.visible = false;
this.visible = false;
}
}