tyrants-edge/src/scenes/SkirmishDeckSelectScene.js

229 lines
8.8 KiB
JavaScript

export class SkirmishDeckSelectScene extends Phaser.Scene {
constructor() { super('SkirmishDeckSelectScene'); }
init(data) {
this.selectedLevel = data.selectedLevel || 1;
this.selectedDifficulty = data.selectedDifficulty || 'Medium';
}
create() {
const { width, height } = this.scale;
this.add.rectangle(width / 2, height / 2, width, height, 0x0d1b2a);
this.add.text(width / 2, 40, 'Select Decks', {
fontSize: '42px', color: '#d4af37', fontFamily: 'RaiderCrusader'
}).setOrigin(0.5);
this.add.text(width / 2, 90, `${this.selectedDifficulty} Difficulty • Card Level ${this.selectedLevel}`, {
fontSize: '18px', color: '#888888', fontFamily: 'Audiowide'
}).setOrigin(0.5);
const cardManager = this.registry.get('cardManager');
const allDecks = this.registry.get('skirmishDecks') || [];
this.availableDecks = allDecks.filter(d => d.difficulty === this.selectedDifficulty);
this.cardManager = cardManager;
this.playerChoice = 'draft'; // 'draft' or deck id
this.opponentChoice = 'draft';
// ── Left panel: Your Deck ──
this._buildPanel(160, 'Your Deck', 'player');
// ── Right panel: Opponent Deck ──
this._buildPanel(1040, 'Opponent Deck', 'opponent');
// ── Divider ──
this.add.rectangle(width / 2, height / 2, 3, height - 200, 0x334466, 0.5);
// ── Action button ──
this.actionBtnBg = null;
this.actionBtnTxt = null;
this._updateActionButton();
this._makeBackButton();
}
_buildPanel(startX, title, side) {
const panelW = 720;
const panelCX = startX + panelW / 2;
const { height } = this.scale;
this.add.text(panelCX, 130, title, {
fontSize: '28px', color: '#d4af37', fontFamily: 'Audiowide'
}).setOrigin(0.5);
// Draft Deck option
const draftY = 200;
const draftBg = this.add.rectangle(panelCX, draftY, panelW - 60, 65, 0x1a3a5c)
.setInteractive({ useHandCursor: true })
.setStrokeStyle(2, 0x4488ff);
const draftTxt = this.add.text(panelCX, draftY - 8, 'Draft Deck', {
fontSize: '22px', color: '#ffffff', fontFamily: 'Audiowide'
}).setOrigin(0.5);
const draftSub = this.add.text(panelCX, draftY + 16, 'Build a custom deck from a random card pool', {
fontSize: '13px', color: '#88aacc', fontFamily: 'Audiowide'
}).setOrigin(0.5);
draftBg.on('pointerdown', () => {
this.sound.play('sfx_menu_select', { volume: 0.7 });
if (side === 'player') this.playerChoice = 'draft';
else this.opponentChoice = 'draft';
this._refreshPanelHighlights();
this._updateActionButton();
});
const panelKey = `${side}Panel`;
this[panelKey] = { draftBg, draftTxt, draftSub, deckEntries: [] };
// ── Premade deck list ──
const listTop = 260;
const entryH = 140;
this.availableDecks.forEach((deck, i) => {
const y = listTop + i * (entryH + 12) + entryH / 2;
if (y + entryH / 2 > height - 100) return; // safety clamp
const commander = this.cardManager.getCard(deck.commander);
const cmdName = commander ? commander.name : deck.commander;
const bg = this.add.rectangle(panelCX, y, panelW - 60, entryH, 0x112233)
.setInteractive({ useHandCursor: true })
.setStrokeStyle(2, 0x334466);
const titleTxt = this.add.text(startX + 50, y - 42, deck.title, {
fontSize: '20px', color: '#ffffff', fontFamily: 'Audiowide'
});
const cmdTxt = this.add.text(startX + 50, y - 16, `Commander: ${cmdName}`, {
fontSize: '14px', color: '#88aaff', fontFamily: 'Audiowide'
});
const summaryTxt = this.add.text(startX + 50, y + 8, deck.summary, {
fontSize: '12px', color: '#999999', fontFamily: 'Audiowide',
wordWrap: { width: panelW - 100 }
});
const countTxt = this.add.text(startX + panelW - 80, y - 42, `${deck.cards.length} cards`, {
fontSize: '13px', color: '#aaaaaa', fontFamily: 'Audiowide'
}).setOrigin(1, 0);
bg.on('pointerover', () => {
const choice = side === 'player' ? this.playerChoice : this.opponentChoice;
if (choice !== deck.id) bg.setFillStyle(0x1a3344);
});
bg.on('pointerout', () => {
const choice = side === 'player' ? this.playerChoice : this.opponentChoice;
if (choice !== deck.id) bg.setFillStyle(0x112233);
});
bg.on('pointerdown', () => {
this.sound.play('sfx_menu_select', { volume: 0.7 });
if (side === 'player') this.playerChoice = deck.id;
else this.opponentChoice = deck.id;
this._refreshPanelHighlights();
this._updateActionButton();
});
this[panelKey].deckEntries.push({ bg, titleTxt, cmdTxt, summaryTxt, countTxt, deckId: deck.id });
});
this._refreshPanelHighlights();
}
_refreshPanelHighlights() {
for (const side of ['player', 'opponent']) {
const panel = this[`${side}Panel`];
const choice = side === 'player' ? this.playerChoice : this.opponentChoice;
// Draft button highlight
const isDraft = choice === 'draft';
panel.draftBg.setFillStyle(isDraft ? 0x2a5a8c : 0x1a2a3a);
panel.draftBg.setStrokeStyle(2, isDraft ? 0x88ccff : 0x444444);
panel.draftTxt.setColor(isDraft ? '#ffffff' : '#888888');
panel.draftSub.setColor(isDraft ? '#88aacc' : '#555555');
// Premade deck highlights
for (const entry of panel.deckEntries) {
const isSelected = choice === entry.deckId;
entry.bg.setFillStyle(isSelected ? 0x1a3a5c : 0x112233);
entry.bg.setStrokeStyle(2, isSelected ? 0x88ccff : 0x334466);
entry.titleTxt.setColor(isSelected ? '#ffffff' : '#aaaaaa');
}
}
}
_updateActionButton() {
const { width, height } = this.scale;
const btnY = height - 60;
// Destroy existing button
if (this.actionBtnBg) { this.actionBtnBg.destroy(); this.actionBtnBg = null; }
if (this.actionBtnTxt) { this.actionBtnTxt.destroy(); this.actionBtnTxt = null; }
const bothPremade = this.playerChoice !== 'draft' && this.opponentChoice !== 'draft';
if (bothPremade) {
// Start Battle
this.actionBtnBg = this.add.rectangle(width / 2, btnY, 300, 60, 0x226622)
.setInteractive({ useHandCursor: true })
.setStrokeStyle(2, 0x44aa44);
this.actionBtnTxt = this.add.text(width / 2, btnY, 'Start Battle', {
fontSize: '26px', color: '#ffffff', fontStyle: 'bold', fontFamily: 'Audiowide'
}).setOrigin(0.5);
this.actionBtnBg.on('pointerover', () => this.actionBtnBg.setFillStyle(0x338833));
this.actionBtnBg.on('pointerout', () => this.actionBtnBg.setFillStyle(0x226622));
this.actionBtnBg.on('pointerdown', () => {
this.sound.play('sfx_menu_select', { volume: 0.7 });
const playerDeck = this._getDeckById(this.playerChoice);
const opponentDeck = this._getDeckById(this.opponentChoice);
this.scene.start('BattleScene', {
skirmish: true,
deck: { commander: playerDeck.commander, cards: [...playerDeck.cards] },
opponentDeck: { commander: opponentDeck.commander, cards: [...opponentDeck.cards] },
playerLevel: this.selectedLevel,
enemyLevel: this.selectedLevel,
difficulty: this.selectedDifficulty
});
});
} else {
// Draft Cards
this.actionBtnBg = this.add.rectangle(width / 2, btnY, 300, 60, 0x224488)
.setInteractive({ useHandCursor: true })
.setStrokeStyle(2, 0x4488ff);
this.actionBtnTxt = this.add.text(width / 2, btnY, 'Draft Cards', {
fontSize: '26px', color: '#ffffff', fontStyle: 'bold', fontFamily: 'Audiowide'
}).setOrigin(0.5);
this.actionBtnBg.on('pointerover', () => this.actionBtnBg.setFillStyle(0x3366aa));
this.actionBtnBg.on('pointerout', () => this.actionBtnBg.setFillStyle(0x224488));
this.actionBtnBg.on('pointerdown', () => {
this.sound.play('sfx_menu_select', { volume: 0.7 });
this.scene.start('SkirmishDraftScene', {
selectedLevel: this.selectedLevel,
selectedDifficulty: this.selectedDifficulty,
playerChoice: this.playerChoice,
opponentChoice: this.opponentChoice,
playerPremadeDeck: this.playerChoice !== 'draft' ? this._getDeckById(this.playerChoice) : null,
opponentPremadeDeck: this.opponentChoice !== 'draft' ? this._getDeckById(this.opponentChoice) : null
});
});
}
}
_getDeckById(id) {
return this.availableDecks.find(d => d.id === id) || null;
}
_makeBackButton() {
const bg = this.add.rectangle(80, 45, 160, 50, 0x333333)
.setInteractive({ useHandCursor: true })
.setStrokeStyle(1, 0x888888);
this.add.text(80, 45, 'Back', { fontSize: '18px', color: '#ffffff', fontFamily: 'Audiowide' }).setOrigin(0.5);
bg.on('pointerdown', () => {
this.sound.play('sfx_menu_select', { volume: 0.7 });
this.scene.start('SkirmishSetupScene');
});
}
}