import { SaveManager } from '../managers/SaveManager.js'; export class StoreScene extends Phaser.Scene { constructor() { super('StoreScene'); } create() { const { width, height } = this.scale; const save = this.registry.get('save'); const packManager = this.registry.get('packManager'); this.add.rectangle(width / 2, height / 2, width, height, 0x0d1b2a); this.add.text(width / 2, 45, 'Card Store', { fontSize: '42px', color: '#d4af37' }).setOrigin(0.5); this.add.text(width / 2, 90, 'Buy packs to expand your collection', { fontSize: '20px', color: '#888888' }).setOrigin(0.5); this.goldText = this.add.text(width - 20, 20, `Gold: ${save.gold}`, { fontSize: '24px', color: '#ffd700' }).setOrigin(1, 0); const packs = packManager.getAllPacks(); packs.forEach((pack, i) => { const x = width / 2 + (i - packs.length / 2 + 0.5) * 440; this._renderPack(pack, x, 350); }); this.revealArea = []; this._makeBackButton(); } _renderPack(pack, x, y) { // Pack visual const packBg = this.add.rectangle(x, y, 380, 340, 0x1a3a5c) .setStrokeStyle(3, 0xffd700); // Pack art (procedural) this.add.rectangle(x, y - 60, 180, 150, 0x0d2240).setStrokeStyle(1, 0x4488ff); this.add.text(x, y - 60, 'PACK', { fontSize: '38px', color: '#4488ff' }).setOrigin(0.5); this.add.text(x, y + 45, pack.name, { fontSize: '24px', color: '#ffffff' }).setOrigin(0.5); this.add.text(x, y + 75, `${pack.cardCount} cards per pack`, { fontSize: '18px', color: '#aaaaaa' }).setOrigin(0.5); this.add.text(x, y + 100, `Cost: ${pack.cost} Gold`, { fontSize: '20px', color: '#ffd700' }).setOrigin(0.5); // Drop rates display const rateLines = Object.entries(pack.dropRates).map(([r, v]) => `${r.charAt(0).toUpperCase() + r.slice(1)}: ${Math.floor(v * 100)}%` ).join(' '); this.add.text(x, y + 128, rateLines, { fontSize: '14px', color: '#888888', wordWrap: { width: 360 }, align: 'center' }).setOrigin(0.5); const buyBtn = this.add.rectangle(x, y + 170, 240, 55, 0x224422) .setInteractive({ useHandCursor: true }) .setStrokeStyle(2, 0x44aa44); const buyTxt = this.add.text(x, y + 170, 'Buy Pack', { fontSize: '22px', color: '#ffffff' }).setOrigin(0.5); buyBtn.on('pointerover', () => buyBtn.setFillStyle(0x336633)); buyBtn.on('pointerout', () => buyBtn.setFillStyle(0x224422)); buyBtn.on('pointerdown', () => this._buyPack(pack)); } _buyPack(pack) { const save = this.registry.get('save'); const packManager = this.registry.get('packManager'); const { width, height } = this.scale; if (!SaveManager.spendGold(save, pack.cost)) { this._showMsg('Not enough gold!', '#ff4444'); return; } const cards = packManager.openPack(pack.id, save); if (!cards || cards.length === 0) { this._showMsg('Pack is empty!', '#ff8800'); return; } cards.forEach(card => SaveManager.addCard(save, card.id)); this.registry.set('save', save); this.goldText.setText(`Gold: ${save.gold}`); // Clear previous reveal this.revealArea.forEach(o => o.destroy()); this.revealArea = []; // Show revealed cards with animation const totalW = cards.length * 300 + (cards.length - 1) * 20; const startX = width / 2 - totalW / 2 + 140; const rarityColors = { common: 0x888888, rare: 0x4488ff, epic: 0xaa44ff, legendary: 0xffaa00 }; const factionColors = { imperial: 0x2244aa, raider: 0xaa2222 }; // Label const label = this.add.text(width / 2, 700, 'You received:', { fontSize: '22px', color: '#ffffff' }).setOrigin(0.5).setAlpha(0); this.revealArea.push(label); this.tweens.add({ targets: label, alpha: 1, duration: 300 }); cards.forEach((card, i) => { const x = startX + i * 320; const y = 860; const bg = this.add.rectangle(x, y, 280, 210, factionColors[card.faction] || 0x1a3a5c) .setStrokeStyle(3, rarityColors[card.rarity] || 0x888888) .setAlpha(0); const nameT = this.add.text(x, y - 70, card.name, { fontSize: '20px', color: '#ffffff', wordWrap: { width: 260 }, align: 'center' }).setOrigin(0.5).setAlpha(0); const rarityT = this.add.text(x, y - 30, card.rarity.toUpperCase(), { fontSize: '16px', color: '#' + (rarityColors[card.rarity] || 0x888888).toString(16).padStart(6, '0') }).setOrigin(0.5).setAlpha(0); const statsT = this.add.text(x, y + 4, `ATK:${card.attack} HP:${card.health} ARM:${card.armor}`, { fontSize: '16px', color: '#aaaaff' }).setOrigin(0.5).setAlpha(0); const skillT = this.add.text(x, y + 34, card.skills.map(s => s.name).join(', '), { fontSize: '14px', color: '#ffcc44' }).setOrigin(0.5).setAlpha(0); const newT = this.add.text(x, y + 65, (save.collection[card.id] || 0) === 1 ? 'NEW!' : `x${save.collection[card.id]}`, { fontSize: '16px', color: (save.collection[card.id] || 0) === 1 ? '#44ff44' : '#aaaaaa' }).setOrigin(0.5).setAlpha(0); this.revealArea.push(bg, nameT, rarityT, statsT, skillT, newT); this.tweens.add({ targets: [bg, nameT, rarityT, statsT, skillT, newT], alpha: 1, duration: 400, delay: i * 350, ease: 'Power2' }); }); } _showMsg(msg, color) { const { width } = this.scale; const t = this.add.text(width / 2, 660, msg, { fontSize: '24px', color }).setOrigin(0.5); this.time.delayedCall(2000, () => t.destroy()); } _makeBackButton() { const bg = this.add.rectangle(80, 1040, 160, 45, 0x333333) .setInteractive({ useHandCursor: true }) .setStrokeStyle(1, 0x888888); this.add.text(80, 1040, 'Back', { fontSize: '18px', color: '#ffffff' }).setOrigin(0.5); bg.on('pointerdown', () => this.scene.start('MainMenuScene')); } }