Add dialogue character portraits
This commit is contained in:
@@ -1,11 +1,20 @@
|
||||
import Phaser from 'phaser';
|
||||
import { prologuePages, type StoryPage } from '../data/scenario';
|
||||
import { prologuePages, type PortraitKey, type StoryPage } from '../data/scenario';
|
||||
import { palette } from '../ui/palette';
|
||||
|
||||
const portraitKeys: Record<PortraitKey, string> = {
|
||||
liuBei: 'portrait-liu-bei',
|
||||
guanYu: 'portrait-guan-yu',
|
||||
zhangFei: 'portrait-zhang-fei'
|
||||
};
|
||||
|
||||
export class StoryScene extends Phaser.Scene {
|
||||
private pageIndex = 0;
|
||||
private background?: Phaser.GameObjects.Image;
|
||||
private chapterText?: Phaser.GameObjects.Text;
|
||||
private portrait?: Phaser.GameObjects.Image;
|
||||
private portraitFrame?: Phaser.GameObjects.Rectangle;
|
||||
private portraitDivider?: Phaser.GameObjects.Rectangle;
|
||||
private nameText?: Phaser.GameObjects.Text;
|
||||
private bodyText?: Phaser.GameObjects.Text;
|
||||
private progressText?: Phaser.GameObjects.Text;
|
||||
@@ -43,7 +52,7 @@ export class StoryScene extends Phaser.Scene {
|
||||
const panelW = width - 144;
|
||||
const panelH = 172;
|
||||
|
||||
this.add.rectangle(panelX, panelY, panelW, panelH, palette.panelDark, 0.86).setOrigin(0);
|
||||
this.add.rectangle(panelX, panelY, panelW, panelH, palette.panelDark, 0.88).setOrigin(0);
|
||||
this.add.rectangle(panelX, panelY, panelW, 3, palette.gold, 0.9).setOrigin(0);
|
||||
this.add.rectangle(panelX, panelY + panelH, panelW, 1, palette.gold, 0.35).setOrigin(0);
|
||||
|
||||
@@ -56,7 +65,15 @@ export class StoryScene extends Phaser.Scene {
|
||||
shadow: { offsetX: 0, offsetY: 2, color: '#05070a', blur: 6, fill: true }
|
||||
});
|
||||
|
||||
this.nameText = this.add.text(panelX + 24, panelY + 28, '', {
|
||||
this.portraitFrame = this.add.rectangle(panelX + 86, panelY + 86, 136, 136, 0x090d12, 0.88);
|
||||
this.portraitFrame.setStrokeStyle(2, palette.gold, 0.58);
|
||||
|
||||
this.portrait = this.add.image(panelX + 86, panelY + 86, 'portrait-liu-bei');
|
||||
this.portrait.setDisplaySize(128, 128);
|
||||
|
||||
this.portraitDivider = this.add.rectangle(panelX + 166, panelY + 28, 1, panelH - 56, palette.gold, 0.22).setOrigin(0);
|
||||
|
||||
this.nameText = this.add.text(panelX + 198, panelY + 28, '', {
|
||||
fontFamily: '"Malgun Gothic", "Noto Sans KR", serif',
|
||||
fontSize: '24px',
|
||||
color: '#f1e3c2',
|
||||
@@ -64,11 +81,11 @@ export class StoryScene extends Phaser.Scene {
|
||||
padding: { top: 4, bottom: 4 }
|
||||
});
|
||||
|
||||
this.bodyText = this.add.text(panelX + 24, panelY + 78, '', {
|
||||
this.bodyText = this.add.text(panelX + 198, panelY + 78, '', {
|
||||
fontFamily: '"Malgun Gothic", "Noto Sans KR", serif',
|
||||
fontSize: '25px',
|
||||
color: '#e8dfca',
|
||||
wordWrap: { width: panelW - 56, useAdvancedWrap: true },
|
||||
wordWrap: { width: panelW - 236, useAdvancedWrap: true },
|
||||
lineSpacing: 10,
|
||||
padding: { top: 4, bottom: 6 },
|
||||
shadow: { offsetX: 0, offsetY: 2, color: '#05070a', blur: 5, fill: true }
|
||||
@@ -99,9 +116,25 @@ export class StoryScene extends Phaser.Scene {
|
||||
private applyPage(page: StoryPage) {
|
||||
this.applyBackground(page.background);
|
||||
this.chapterText?.setText(page.chapter);
|
||||
this.nameText?.setPosition(96, this.scale.height - 210);
|
||||
this.bodyText?.setPosition(96, this.scale.height - 160);
|
||||
this.bodyText?.setWordWrapWidth(this.scale.width - 200, true);
|
||||
|
||||
if (page.portrait) {
|
||||
this.portraitFrame?.setVisible(true);
|
||||
this.portrait?.setVisible(true);
|
||||
this.portraitDivider?.setVisible(true);
|
||||
this.portrait?.setTexture(portraitKeys[page.portrait]);
|
||||
this.portrait?.setDisplaySize(128, 128);
|
||||
this.nameText?.setPosition(270, this.scale.height - 210);
|
||||
this.bodyText?.setPosition(270, this.scale.height - 160);
|
||||
this.bodyText?.setWordWrapWidth(this.scale.width - 374, true);
|
||||
} else {
|
||||
this.portraitFrame?.setVisible(false);
|
||||
this.portrait?.setVisible(false);
|
||||
this.portraitDivider?.setVisible(false);
|
||||
this.nameText?.setPosition(96, this.scale.height - 210);
|
||||
this.bodyText?.setPosition(96, this.scale.height - 160);
|
||||
this.bodyText?.setWordWrapWidth(this.scale.width - 200, true);
|
||||
}
|
||||
|
||||
this.nameText?.setText(page.speaker ?? '나레이션');
|
||||
this.bodyText?.setText(page.text);
|
||||
this.progressText?.setText(`${this.pageIndex + 1} / ${prologuePages.length} SPACE / ENTER`);
|
||||
|
||||
Reference in New Issue
Block a user