78 lines
2.3 KiB
JavaScript
78 lines
2.3 KiB
JavaScript
const CARD_W = 220;
|
|
const CARD_H = 100;
|
|
const CARD_GAP = 30;
|
|
const CARD_NORMAL = 0x223355;
|
|
const CARD_HOVER = 0x3355aa;
|
|
const CARD_BORDER = 0x4488ff;
|
|
|
|
export class SkillTreeUI {
|
|
constructor(scene, skillTree, player, onClose) {
|
|
this.scene = scene;
|
|
this.skillTree = skillTree;
|
|
this.player = player;
|
|
this.onClose = onClose;
|
|
this._elements = [];
|
|
this._build();
|
|
}
|
|
|
|
_build() {
|
|
const W = this.scene.scale.width;
|
|
const H = this.scene.scale.height;
|
|
|
|
// Dim background
|
|
const overlay = this.scene.add.rectangle(W / 2, H / 2, W, H, 0x000000, 0.6).setDepth(20);
|
|
this._elements.push(overlay);
|
|
|
|
// Title
|
|
const title = this.scene.add.text(W / 2, H / 2 - 160, `LEVEL UP!`, {
|
|
fontSize: '36px', fill: '#ffdd44', fontStyle: 'bold'
|
|
}).setOrigin(0.5).setDepth(21);
|
|
this._elements.push(title);
|
|
|
|
const sub = this.scene.add.text(W / 2, H / 2 - 115, 'Choose a skill:', {
|
|
fontSize: '18px', fill: '#aaaaaa'
|
|
}).setOrigin(0.5).setDepth(21);
|
|
this._elements.push(sub);
|
|
|
|
// Skill cards
|
|
const available = this.skillTree.getAvailable();
|
|
const total = available.length;
|
|
const startX = W / 2 - ((CARD_W + CARD_GAP) * (total - 1)) / 2;
|
|
|
|
available.forEach((node, i) => {
|
|
const cx = startX + i * (CARD_W + CARD_GAP);
|
|
const cy = H / 2 + 20;
|
|
|
|
const card = this.scene.add.rectangle(cx, cy, CARD_W, CARD_H, CARD_NORMAL)
|
|
.setStrokeStyle(2, CARD_BORDER)
|
|
.setInteractive({ useHandCursor: true })
|
|
.setDepth(21);
|
|
|
|
const label = this.scene.add.text(cx, cy - 18, node.label, {
|
|
fontSize: '16px', fill: '#ffffff', fontStyle: 'bold', wordWrap: { width: CARD_W - 20 }
|
|
}).setOrigin(0.5).setDepth(22);
|
|
|
|
const desc = this.scene.add.text(cx, cy + 18, node.description, {
|
|
fontSize: '13px', fill: '#aaccff', wordWrap: { width: CARD_W - 20 }
|
|
}).setOrigin(0.5).setDepth(22);
|
|
|
|
card.on('pointerover', () => card.setFillStyle(CARD_HOVER));
|
|
card.on('pointerout', () => card.setFillStyle(CARD_NORMAL));
|
|
card.on('pointerdown', () => this._select(node.id));
|
|
|
|
this._elements.push(card, label, desc);
|
|
});
|
|
}
|
|
|
|
_select(nodeId) {
|
|
this.skillTree.applyNode(nodeId, this.player.stats);
|
|
this._destroy();
|
|
this.onClose();
|
|
}
|
|
|
|
_destroy() {
|
|
this._elements.forEach(e => e?.destroy());
|
|
this._elements = [];
|
|
}
|
|
}
|