Scaffold tactical RPG web prototype
This commit is contained in:
85
src/game/scenes/StoryScene.ts
Normal file
85
src/game/scenes/StoryScene.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
import Phaser from 'phaser';
|
||||
import { prologueLines, type StoryLine } from '../data/scenario';
|
||||
import { palette } from '../ui/palette';
|
||||
|
||||
const portraitKeys: Record<StoryLine['portrait'], string> = {
|
||||
lord: 'portrait-lord',
|
||||
strategist: 'portrait-strategist',
|
||||
captain: 'portrait-captain'
|
||||
};
|
||||
|
||||
export class StoryScene extends Phaser.Scene {
|
||||
private lineIndex = 0;
|
||||
private portrait?: Phaser.GameObjects.Image;
|
||||
private nameText?: Phaser.GameObjects.Text;
|
||||
private bodyText?: Phaser.GameObjects.Text;
|
||||
|
||||
constructor() {
|
||||
super('StoryScene');
|
||||
}
|
||||
|
||||
create() {
|
||||
const { width, height } = this.scale;
|
||||
this.add.rectangle(0, 0, width, height, 0x151922).setOrigin(0);
|
||||
this.drawCampBackground(width, height);
|
||||
this.drawDialogPanel(width, height);
|
||||
this.showLine(0);
|
||||
|
||||
this.input.on('pointerdown', () => this.advance());
|
||||
this.input.keyboard?.on('keydown-SPACE', () => this.advance());
|
||||
this.input.keyboard?.on('keydown-ENTER', () => this.advance());
|
||||
}
|
||||
|
||||
private drawCampBackground(width: number, height: number) {
|
||||
const graphics = this.add.graphics();
|
||||
graphics.fillStyle(0x26303a, 1);
|
||||
graphics.fillRect(0, height * 0.54, width, height * 0.46);
|
||||
graphics.fillStyle(0x5f6d5a, 1);
|
||||
graphics.fillTriangle(0, height * 0.54, 240, 240, 470, height * 0.54);
|
||||
graphics.fillStyle(0x384858, 1);
|
||||
graphics.fillTriangle(300, height * 0.54, 570, 160, 870, height * 0.54);
|
||||
graphics.fillStyle(0x8a4f3d, 1);
|
||||
graphics.fillRect(935, 264, 98, 200);
|
||||
graphics.fillStyle(0xd8b15f, 1);
|
||||
graphics.fillTriangle(1033, 264, 1180, 304, 1033, 344);
|
||||
}
|
||||
|
||||
private drawDialogPanel(width: number, height: number) {
|
||||
const panelY = height - 214;
|
||||
this.add.rectangle(64, panelY, width - 128, 158, palette.panel, 0.95).setOrigin(0);
|
||||
this.add.rectangle(64, panelY, width - 128, 4, palette.gold, 0.9).setOrigin(0);
|
||||
this.portrait = this.add.image(150, panelY + 79, 'portrait-lord');
|
||||
this.nameText = this.add.text(238, panelY + 28, '', {
|
||||
fontSize: '24px',
|
||||
color: '#d8b15f',
|
||||
fontStyle: '700'
|
||||
});
|
||||
this.bodyText = this.add.text(238, panelY + 68, '', {
|
||||
fontSize: '24px',
|
||||
color: '#e8dfca',
|
||||
wordWrap: { width: width - 370, useAdvancedWrap: true },
|
||||
lineSpacing: 8
|
||||
});
|
||||
this.add.text(width - 190, panelY + 122, 'SPACE / ENTER', {
|
||||
fontSize: '16px',
|
||||
color: '#9aa3ad'
|
||||
});
|
||||
}
|
||||
|
||||
private showLine(index: number) {
|
||||
const line = prologueLines[index];
|
||||
this.portrait?.setTexture(portraitKeys[line.portrait]);
|
||||
this.nameText?.setText(line.speaker);
|
||||
this.bodyText?.setText(line.text);
|
||||
}
|
||||
|
||||
private advance() {
|
||||
if (this.lineIndex >= prologueLines.length - 1) {
|
||||
this.scene.start('BattleScene');
|
||||
return;
|
||||
}
|
||||
|
||||
this.lineIndex += 1;
|
||||
this.showLine(this.lineIndex);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user