feat(ui): add custom fonts and apply Audiowide/RaiderCrusader across all scenes

- Add `Audiowide-Regular.ttf` and `raidercrusader.ttf` to assets/fonts.
- Update Phaser version to v3.90.0 in index.html.
- Load custom fonts in BootScene.preload().
- Apply `fontFamily: 'Audiowide'` to standard UI text (stats, labels, menus).
- Apply `fontFamily: 'RaiderCrusader'` to prominent titles and large display text (main menu, victory/defeat, pack labels).
- Consistently update text styles in CardObject, CardTooltip, HealthBar, and all scene files.
This commit is contained in:
Brian Fertig 2026-03-15 13:57:59 -06:00
parent 4c0e7eb77c
commit c4e967c72c
16 changed files with 199 additions and 167 deletions

Binary file not shown.

Binary file not shown.

View File

@ -1,17 +1,35 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tyrant's Edge</title> <title>Tyrant's Edge</title>
<style> <style>
* { margin: 0; padding: 0; box-sizing: border-box; } * {
body { background: #1a1a2e; display: flex; justify-content: center; align-items: center; height: 100vh; overflow: hidden; } margin: 0;
canvas { display: block; } padding: 0;
box-sizing: border-box;
}
body {
background: #1a1a2e;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
overflow: hidden;
}
canvas {
display: block;
}
</style> </style>
</head> </head>
<body> <body>
<script src="https://cdn.jsdelivr.net/npm/phaser@3.60.0/dist/phaser.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/phaser@v3.90.0/dist/phaser.min.js"></script>
<script type="module" src="src/game.js"></script> <script type="module" src="src/game.js"></script>
</body> </body>
</html>
</html>

View File

@ -60,7 +60,7 @@ export class CardObject extends Phaser.GameObjects.Container {
this.atkText = this.scene.add.text( this.atkText = this.scene.add.text(
-w / 2 + Math.round(5 * scale), topBannerCY, -w / 2 + Math.round(5 * scale), topBannerCY,
`${this.cardData.currentAttack}`, `${this.cardData.currentAttack}`,
{ fontSize: fs(9), color: '#ff8877', fontStyle: 'bold' } { fontSize: fs(9), color: '#ff8877', fontStyle: 'bold', fontFamily: 'Audiowide' }
).setOrigin(0, 0.5); ).setOrigin(0, 0.5);
this.add(this.atkText); this.add(this.atkText);
@ -68,7 +68,7 @@ export class CardObject extends Phaser.GameObjects.Container {
this.atkLabel = this.scene.add.text( this.atkLabel = this.scene.add.text(
this.atkText.x + this.atkText.width + Math.round(2 * scale), topBannerCY, this.atkText.x + this.atkText.width + Math.round(2 * scale), topBannerCY,
'ATK', 'ATK',
{ fontSize: fs(5.5), color: '#886666' } { fontSize: fs(5.5), color: '#886666', fontFamily: 'Audiowide' }
).setOrigin(0, 0.5); ).setOrigin(0, 0.5);
this.add(this.atkLabel); this.add(this.atkLabel);
@ -76,7 +76,7 @@ export class CardObject extends Phaser.GameObjects.Container {
this.armText = this.scene.add.text( this.armText = this.scene.add.text(
w / 2 - Math.round(5 * scale), topBannerCY, w / 2 - Math.round(5 * scale), topBannerCY,
`${this.cardData.currentArmor}`, `${this.cardData.currentArmor}`,
{ fontSize: fs(9), color: '#88aaff', fontStyle: 'bold' } { fontSize: fs(9), color: '#88aaff', fontStyle: 'bold', fontFamily: 'Audiowide' }
).setOrigin(1, 0.5); ).setOrigin(1, 0.5);
this.add(this.armText); this.add(this.armText);
@ -84,7 +84,7 @@ export class CardObject extends Phaser.GameObjects.Container {
this.armLabel = this.scene.add.text( this.armLabel = this.scene.add.text(
this.armText.x - this.armText.width - Math.round(2 * scale), topBannerCY, this.armText.x - this.armText.width - Math.round(2 * scale), topBannerCY,
'ARM', 'ARM',
{ fontSize: fs(5.5), color: '#667799' } { fontSize: fs(5.5), color: '#667799', fontFamily: 'Audiowide' }
).setOrigin(1, 0.5); ).setOrigin(1, 0.5);
this.add(this.armLabel); this.add(this.armLabel);
@ -119,7 +119,7 @@ export class CardObject extends Phaser.GameObjects.Container {
this.nameText = this.scene.add.text(0, nameY, this.cardData.name, { this.nameText = this.scene.add.text(0, nameY, this.cardData.name, {
fontSize: fs(8), color: '#ffffff', fontSize: fs(8), color: '#ffffff',
wordWrap: { width: w - Math.round(8 * scale) }, align: 'center' wordWrap: { width: w - Math.round(8 * scale) }, align: 'center', fontFamily: 'Audiowide'
}).setOrigin(0.5, 0.5); }).setOrigin(0.5, 0.5);
this.add(this.nameText); this.add(this.nameText);
@ -133,7 +133,7 @@ export class CardObject extends Phaser.GameObjects.Container {
const skillY = contentTop + contentH * 0.72; const skillY = contentTop + contentH * 0.72;
this.skillText = this.scene.add.text(0, skillY, skillStr, { this.skillText = this.scene.add.text(0, skillY, skillStr, {
fontSize: fs(7), color: '#ffcc44', fontSize: fs(7), color: '#ffcc44',
wordWrap: { width: w - Math.round(8 * scale) }, align: 'center' wordWrap: { width: w - Math.round(8 * scale) }, align: 'center', fontFamily: 'Audiowide'
}).setOrigin(0.5, 0.5); }).setOrigin(0.5, 0.5);
this.add(this.skillText); this.add(this.skillText);
} }
@ -146,7 +146,7 @@ export class CardObject extends Phaser.GameObjects.Container {
this.hpText = this.scene.add.text( this.hpText = this.scene.add.text(
-w / 2 + Math.round(5 * scale), bottomBannerCY, -w / 2 + Math.round(5 * scale), bottomBannerCY,
`${Math.max(0, this.cardData.currentHP)}`, `${Math.max(0, this.cardData.currentHP)}`,
{ fontSize: fs(9), color: '#44ee88', fontStyle: 'bold' } { fontSize: fs(9), color: '#44ee88', fontStyle: 'bold', fontFamily: 'Audiowide' }
).setOrigin(0, 0.5); ).setOrigin(0, 0.5);
this.add(this.hpText); this.add(this.hpText);
@ -154,7 +154,7 @@ export class CardObject extends Phaser.GameObjects.Container {
this.hpLabel = this.scene.add.text( this.hpLabel = this.scene.add.text(
this.hpText.x + this.hpText.width + Math.round(2 * scale), bottomBannerCY, this.hpText.x + this.hpText.width + Math.round(2 * scale), bottomBannerCY,
'HP', 'HP',
{ fontSize: fs(5.5), color: '#337755' } { fontSize: fs(5.5), color: '#337755', fontFamily: 'Audiowide' }
).setOrigin(0, 0.5); ).setOrigin(0, 0.5);
this.add(this.hpLabel); this.add(this.hpLabel);
@ -162,7 +162,7 @@ export class CardObject extends Phaser.GameObjects.Container {
this.dlyText = this.scene.add.text( this.dlyText = this.scene.add.text(
w / 2 - Math.round(5 * scale), bottomBannerCY, w / 2 - Math.round(5 * scale), bottomBannerCY,
`${this.cardData.currentDelay}`, `${this.cardData.currentDelay}`,
{ fontSize: fs(9), color: '#aaaaaa', fontStyle: 'bold' } { fontSize: fs(9), color: '#aaaaaa', fontStyle: 'bold', fontFamily: 'Audiowide' }
).setOrigin(1, 0.5); ).setOrigin(1, 0.5);
this.add(this.dlyText); this.add(this.dlyText);
@ -170,7 +170,7 @@ export class CardObject extends Phaser.GameObjects.Container {
const dlyLabel = this.scene.add.text( const dlyLabel = this.scene.add.text(
w / 2 - Math.round(19 * scale), bottomBannerCY, w / 2 - Math.round(19 * scale), bottomBannerCY,
'DLY', 'DLY',
{ fontSize: fs(5.5), color: '#777777' } { fontSize: fs(5.5), color: '#777777', fontFamily: 'Audiowide' }
).setOrigin(1, 0.5); ).setOrigin(1, 0.5);
this.add(dlyLabel); this.add(dlyLabel);
@ -183,7 +183,8 @@ export class CardObject extends Phaser.GameObjects.Container {
{ {
fontSize: fs(6), color: '#ffffff', fontStyle: 'bold', fontSize: fs(6), color: '#ffffff', fontStyle: 'bold',
backgroundColor: '#000000aa', backgroundColor: '#000000aa',
padding: { x: Math.round(2 * scale), y: Math.round(1 * scale) } padding: { x: Math.round(2 * scale), y: Math.round(1 * scale) },
fontFamily: 'Audiowide'
} }
).setOrigin(0, 0); ).setOrigin(0, 0);
this.add(lvBadge); this.add(lvBadge);
@ -251,7 +252,8 @@ export class CardObject extends Phaser.GameObjects.Container {
color: '#4488ff', color: '#4488ff',
fontStyle: 'bold', fontStyle: 'bold',
stroke: '#000000', stroke: '#000000',
strokeThickness: Math.max(1, Math.round(2 * s)) strokeThickness: Math.max(1, Math.round(2 * s)),
fontFamily: 'Audiowide'
} }
).setOrigin(1, 0.5).setDepth(50); ).setOrigin(1, 0.5).setDepth(50);
this.add(lossText); this.add(lossText);
@ -307,7 +309,8 @@ export class CardObject extends Phaser.GameObjects.Container {
color: '#88aaff', color: '#88aaff',
fontStyle: 'bold', fontStyle: 'bold',
stroke: '#000000', stroke: '#000000',
strokeThickness: Math.max(1, Math.round(2 * s)) strokeThickness: Math.max(1, Math.round(2 * s)),
fontFamily: 'Audiowide'
} }
).setOrigin(1, 0.5).setDepth(50); ).setOrigin(1, 0.5).setDepth(50);
this.add(bonusText); this.add(bonusText);
@ -365,7 +368,8 @@ export class CardObject extends Phaser.GameObjects.Container {
color: '#ffaa00', color: '#ffaa00',
fontStyle: 'bold', fontStyle: 'bold',
stroke: '#000000', stroke: '#000000',
strokeThickness: Math.max(1, Math.round(2 * s)) strokeThickness: Math.max(1, Math.round(2 * s)),
fontFamily: 'Audiowide'
} }
).setOrigin(0, 0.5).setDepth(50); ).setOrigin(0, 0.5).setDepth(50);
this.add(bonusText); this.add(bonusText);
@ -430,7 +434,8 @@ export class CardObject extends Phaser.GameObjects.Container {
color: '#ff4444', color: '#ff4444',
fontStyle: 'bold', fontStyle: 'bold',
stroke: '#000000', stroke: '#000000',
strokeThickness: Math.max(1, Math.round(2 * s)) strokeThickness: Math.max(1, Math.round(2 * s)),
fontFamily: 'Audiowide'
} }
).setOrigin(0, 0.5).setDepth(50); ).setOrigin(0, 0.5).setDepth(50);
this.add(lossText); this.add(lossText);

View File

@ -43,7 +43,7 @@ export class CardTooltip extends Phaser.GameObjects.Container {
// Card name // Card name
lines.push({ lines.push({
text: this.cardData.name, text: this.cardData.name,
style: { fontSize: '28px', color: '#ffffff', fontStyle: 'bold', wordWrap: { width: W - PAD * 2 }, align: 'center' }, style: { fontSize: '28px', color: '#ffffff', fontStyle: 'bold', wordWrap: { width: W - PAD * 2 }, align: 'center', fontFamily: 'Audiowide' },
marginTop: 0, align: 'center' marginTop: 0, align: 'center'
}); });
@ -51,7 +51,7 @@ export class CardTooltip extends Phaser.GameObjects.Container {
const meta = `${this._cap(this.cardData.type)} · ${this._cap(this.cardData.faction)} · ${this._cap(this.cardData.rarity)}`; const meta = `${this._cap(this.cardData.type)} · ${this._cap(this.cardData.faction)} · ${this._cap(this.cardData.rarity)}`;
lines.push({ lines.push({
text: meta, text: meta,
style: { fontSize: '16px', color: '#999999', wordWrap: { width: W - PAD * 2 }, align: 'center' }, style: { fontSize: '16px', color: '#999999', wordWrap: { width: W - PAD * 2 }, align: 'center', fontFamily: 'Audiowide' },
marginTop: 6, align: 'center' marginTop: 6, align: 'center'
}); });
@ -62,7 +62,7 @@ export class CardTooltip extends Phaser.GameObjects.Container {
const stats = `ATK ${this.cardData.attack} HP ${this.cardData.health} ARM ${this.cardData.armor} DLY ${this.cardData.delay}`; const stats = `ATK ${this.cardData.attack} HP ${this.cardData.health} ARM ${this.cardData.armor} DLY ${this.cardData.delay}`;
lines.push({ lines.push({
text: stats, text: stats,
style: { fontSize: '20px', color: '#cccccc', fontStyle: 'bold', wordWrap: { width: W - PAD * 2 }, align: 'center' }, style: { fontSize: '20px', color: '#cccccc', fontStyle: 'bold', wordWrap: { width: W - PAD * 2 }, align: 'center', fontFamily: 'Audiowide' },
marginTop: 12, align: 'center' marginTop: 12, align: 'center'
}); });
@ -80,9 +80,9 @@ export class CardTooltip extends Phaser.GameObjects.Container {
const valStr = skill.value != null ? ` ${skill.value}` : ''; const valStr = skill.value != null ? ` ${skill.value}` : '';
lines.push({ lines.push({
text: `${skill.name}${allMod}${valStr}`, text: `${skill.name}${allMod}${valStr}`,
style: { fontSize: '21px', color: catColor, fontStyle: 'bold', wordWrap: { width: W - PAD * 2 } }, style: { fontSize: '21px', color: catColor, fontStyle: 'bold', wordWrap: { width: W - PAD * 2 }, fontFamily: 'Audiowide' },
marginTop: 14, align: 'left', marginTop: 14, align: 'left',
suffix: { text: ` ${triggerLabel}`, style: { fontSize: '15px', color: '#888888' } } suffix: { text: ` ${triggerLabel}`, style: { fontSize: '15px', color: '#888888', fontFamily: 'Audiowide' } }
}); });
// Skill description — use allDescription when "all" modifier is present // Skill description — use allDescription when "all" modifier is present
@ -94,7 +94,7 @@ export class CardTooltip extends Phaser.GameObjects.Container {
: rawDesc; : rawDesc;
lines.push({ lines.push({
text: desc, text: desc,
style: { fontSize: '17px', color: '#bbbbbb', wordWrap: { width: W - PAD * 2 } }, style: { fontSize: '17px', color: '#bbbbbb', wordWrap: { width: W - PAD * 2 }, fontFamily: 'Audiowide' },
marginTop: 4, align: 'left' marginTop: 4, align: 'left'
}); });
} }
@ -106,7 +106,7 @@ export class CardTooltip extends Phaser.GameObjects.Container {
lines.push({ divider: true, marginTop: 14 }); lines.push({ divider: true, marginTop: 14 });
lines.push({ lines.push({
text: `"${this.cardData.flavorText}"`, text: `"${this.cardData.flavorText}"`,
style: { fontSize: '16px', color: '#777777', fontStyle: 'italic', wordWrap: { width: W - PAD * 2 }, align: 'center' }, style: { fontSize: '16px', color: '#777777', fontStyle: 'italic', wordWrap: { width: W - PAD * 2 }, align: 'center', fontFamily: 'Audiowide' },
marginTop: 10, align: 'center' marginTop: 10, align: 'center'
}); });
} }

View File

@ -9,7 +9,7 @@ export class HealthBar {
this.bg = scene.add.rectangle(x, y, width, height, 0x333333).setOrigin(0, 0.5); this.bg = scene.add.rectangle(x, y, width, height, 0x333333).setOrigin(0, 0.5);
this.bar = scene.add.rectangle(x, y, width, height, 0x22cc44).setOrigin(0, 0.5); this.bar = scene.add.rectangle(x, y, width, height, 0x22cc44).setOrigin(0, 0.5);
this.text = scene.add.text(x + width / 2, y, `${maxHP}/${maxHP}`, { this.text = scene.add.text(x + width / 2, y, `${maxHP}/${maxHP}`, {
fontSize: '10px', color: '#ffffff' fontSize: '10px', color: '#ffffff', fontFamily: 'Audiowide'
}).setOrigin(0.5, 0.5); }).setOrigin(0.5, 0.5);
} }

View File

@ -129,8 +129,8 @@ export class BattleScene extends Phaser.Scene {
this.add.rectangle(280, height / 2, 1, height, 0x222244); this.add.rectangle(280, height / 2, 1, height, 0x222244);
// Side labels // Side labels
this.add.text(14, 95, 'OPPONENT', { fontSize: '17px', color: '#ff8888' }); this.add.text(14, 95, 'OPPONENT', { fontSize: '17px', color: '#ff8888', fontFamily: 'Audiowide' });
this.add.text(14, 520, 'PLAYER', { fontSize: '17px', color: '#88aaff' }); this.add.text(14, 520, 'PLAYER', { fontSize: '17px', color: '#88aaff', fontFamily: 'Audiowide' });
this.battlefield = new BattleField(this, { this.battlefield = new BattleField(this, {
playerY: 715, opponentY: 305, playerY: 715, opponentY: 305,
@ -161,7 +161,7 @@ export class BattleScene extends Phaser.Scene {
if (!this.playerDeckData) { if (!this.playerDeckData) {
this.add.text(width / 2, height / 2, 'No deck configured!\nGo to Deck Builder first.', { this.add.text(width / 2, height / 2, 'No deck configured!\nGo to Deck Builder first.', {
fontSize: '20px', color: '#ff4444', align: 'center' fontSize: '20px', color: '#ff4444', align: 'center', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
this._makeBackButton(); this._makeBackButton();
return; return;
@ -175,23 +175,23 @@ export class BattleScene extends Phaser.Scene {
// ── Top bar ────────────────────────────────────────────────────────────── // ── Top bar ──────────────────────────────────────────────────────────────
this.turnText = this.add.text(960, 30, 'Turn 0', { this.turnText = this.add.text(960, 30, 'Turn 0', {
fontSize: '20px', color: '#ffffff' fontSize: '20px', color: '#ffffff', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
const battleLabel = this.missionData ? this.missionData.name : 'Skirmish Battle'; const battleLabel = this.missionData ? this.missionData.name : 'Skirmish Battle';
this.add.text(960, 58, battleLabel, { this.add.text(960, 58, battleLabel, {
fontSize: '14px', color: '#888888' fontSize: '14px', color: '#888888', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
// ── Combat log — bottom strip ──────────────────────────────────────────── // ── Combat log — bottom strip ────────────────────────────────────────────
this.statusText = this.add.text(width / 2, 1058, 'Press SPACE or click Next Turn to start', { this.statusText = this.add.text(width / 2, 1058, 'Press SPACE or click Next Turn to start', {
fontSize: '17px', color: '#aaaaaa' fontSize: '17px', color: '#aaaaaa', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
this.logLines = []; this.logLines = [];
for (let i = 0; i < 6; i++) { for (let i = 0; i < 6; i++) {
this.logLines.push(this.add.text(14, 915 + i * 20, '', { this.logLines.push(this.add.text(14, 915 + i * 20, '', {
fontSize: '15px', color: '#777777' fontSize: '15px', color: '#777777', fontFamily: 'Audiowide'
})); }));
} }
@ -207,7 +207,7 @@ export class BattleScene extends Phaser.Scene {
.setInteractive({ useHandCursor: true }) .setInteractive({ useHandCursor: true })
.setStrokeStyle(1, 0x44aa44); .setStrokeStyle(1, 0x44aa44);
this.autoBtnText = this.add.text(1680, 35, 'Auto: OFF', { this.autoBtnText = this.add.text(1680, 35, 'Auto: OFF', {
fontSize: '18px', color: '#ffffff' fontSize: '18px', color: '#ffffff', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
autoBtn.on('pointerdown', () => this._toggleAuto()); autoBtn.on('pointerdown', () => this._toggleAuto());
@ -215,7 +215,7 @@ export class BattleScene extends Phaser.Scene {
.setInteractive({ useHandCursor: true }) .setInteractive({ useHandCursor: true })
.setStrokeStyle(1, 0x4488ff); .setStrokeStyle(1, 0x4488ff);
this.add.text(1840, 35, 'Next Turn', { this.add.text(1840, 35, 'Next Turn', {
fontSize: '18px', color: '#ffffff' fontSize: '18px', color: '#ffffff', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
nextBtn.on('pointerdown', () => this._beginTurn()); nextBtn.on('pointerdown', () => this._beginTurn());
@ -240,7 +240,7 @@ export class BattleScene extends Phaser.Scene {
// Label above the card (separate text so it never scales/shakes with the card) // Label above the card (separate text so it never scales/shakes with the card)
this.add.text(s.cx, s.cy - h / 2 - 14, s.label, this.add.text(s.cx, s.cy - h / 2 - 14, s.label,
{ fontSize: '15px', color: s.labelColor }).setOrigin(0.5); { fontSize: '15px', color: s.labelColor, fontFamily: 'Audiowide' }).setOrigin(0.5);
// Use CardObject for visual consistency with lane cards // Use CardObject for visual consistency with lane cards
const cardObj = new CardObject(this, s.cx, s.cy, s.data, { width: w, height: h }); const cardObj = new CardObject(this, s.cx, s.cy, s.data, { width: w, height: h });
@ -249,8 +249,8 @@ export class BattleScene extends Phaser.Scene {
this.commanderObjects.set(s.data.instanceId, cardObj); this.commanderObjects.set(s.data.instanceId, cardObj);
} }
this.oDeckText = this.add.text(14, 115, '', { fontSize: '15px', color: '#aaaaaa' }); this.oDeckText = this.add.text(14, 115, '', { fontSize: '15px', color: '#aaaaaa', fontFamily: 'Audiowide' });
this.pDeckText = this.add.text(14, 540, '', { fontSize: '15px', color: '#aaaaaa' }); this.pDeckText = this.add.text(14, 540, '', { fontSize: '15px', color: '#aaaaaa', fontFamily: 'Audiowide' });
} }
_beginTurn() { _beginTurn() {
@ -1481,7 +1481,7 @@ export class BattleScene extends Phaser.Scene {
const dmgText = this.add.text( const dmgText = this.add.text(
dmgAnchorX, dmgAnchorY - 100, dmgAnchorX, dmgAnchorY - 100,
`-${event.damage}`, `-${event.damage}`,
{ fontSize: '56px', color: '#ff3333', stroke: '#000000', strokeThickness: 5 } { fontSize: '56px', color: '#ff3333', stroke: '#000000', strokeThickness: 5, fontFamily: 'RaiderCrusader' }
).setOrigin(0.5).setDepth(30); ).setOrigin(0.5).setDepth(30);
this.tweens.add({ this.tweens.add({
@ -2463,7 +2463,8 @@ export class BattleScene extends Phaser.Scene {
color: '#ff8877', color: '#ff8877',
fontStyle: 'bold', fontStyle: 'bold',
stroke: '#000000', stroke: '#000000',
strokeThickness: Math.max(1, Math.round(2 * s)) strokeThickness: Math.max(1, Math.round(2 * s)),
fontFamily: 'Audiowide'
} }
).setOrigin(1, 0.5).setDepth(50); ).setOrigin(1, 0.5).setDepth(50);
@ -2664,7 +2665,8 @@ export class BattleScene extends Phaser.Scene {
fontStyle: 'bold', fontStyle: 'bold',
stroke: '#000000', stroke: '#000000',
strokeThickness: 3, strokeThickness: 3,
align: 'center' align: 'center',
fontFamily: 'Audiowide'
}).setOrigin(0.5, 0.5).setDepth(55); }).setOrigin(0.5, 0.5).setDepth(55);
this.tweens.add({ this.tweens.add({
@ -2750,7 +2752,7 @@ export class BattleScene extends Phaser.Scene {
this.pickerObjects.push(panel); this.pickerObjects.push(panel);
const title = this.add.text(width / 2, panelY - panelH / 2 + 26, 'Choose a card to deploy', { const title = this.add.text(width / 2, panelY - panelH / 2 + 26, 'Choose a card to deploy', {
fontSize: '22px', color: '#d4af37' fontSize: '22px', color: '#d4af37', fontFamily: 'Audiowide'
}).setOrigin(0.5).setDepth(11); }).setOrigin(0.5).setDepth(11);
this.pickerObjects.push(title); this.pickerObjects.push(title);
@ -2792,7 +2794,7 @@ export class BattleScene extends Phaser.Scene {
.setInteractive({ useHandCursor: true }) .setInteractive({ useHandCursor: true })
.setDepth(11); .setDepth(11);
const passTxt = this.add.text(width / 2, panelY + panelH / 2 - 28, 'Pass (deploy nothing)', { const passTxt = this.add.text(width / 2, panelY + panelH / 2 - 28, 'Pass (deploy nothing)', {
fontSize: '17px', color: '#aaaaaa' fontSize: '17px', color: '#aaaaaa', fontFamily: 'Audiowide'
}).setOrigin(0.5).setDepth(12); }).setOrigin(0.5).setDepth(12);
passBtn.on('pointerdown', () => { passBtn.on('pointerdown', () => {
this._destroyCardPicker(); this._destroyCardPicker();
@ -2908,11 +2910,11 @@ export class BattleScene extends Phaser.Scene {
this.add.text(width / 2, height / 2 - 120, won ? 'VICTORY!' : 'DEFEAT', { this.add.text(width / 2, height / 2 - 120, won ? 'VICTORY!' : 'DEFEAT', {
fontSize: '72px', color: won ? '#44ff44' : '#ff4444', fontSize: '72px', color: won ? '#44ff44' : '#ff4444',
stroke: '#000000', strokeThickness: 6 stroke: '#000000', strokeThickness: 6, fontFamily: 'RaiderCrusader'
}).setOrigin(0.5); }).setOrigin(0.5);
this.add.text(width / 2, height / 2 - 40, `Battle lasted ${this.engine.turn} turns`, { this.add.text(width / 2, height / 2 - 40, `Battle lasted ${this.engine.turn} turns`, {
fontSize: '24px', color: '#aaaaaa' fontSize: '24px', color: '#aaaaaa', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
if (won && this.missionData) { if (won && this.missionData) {
@ -2938,7 +2940,7 @@ export class BattleScene extends Phaser.Scene {
this.registry.set('save', save); this.registry.set('save', save);
this.add.text(width / 2, height / 2 + 20, `+${rewards.gold} Gold`, { this.add.text(width / 2, height / 2 + 20, `+${rewards.gold} Gold`, {
fontSize: '36px', color: '#ffd700' fontSize: '36px', color: '#ffd700', fontFamily: 'RaiderCrusader'
}).setOrigin(0.5); }).setOrigin(0.5);
if (rewards.cards && rewards.cards.length > 0) { if (rewards.cards && rewards.cards.length > 0) {
@ -2948,7 +2950,7 @@ export class BattleScene extends Phaser.Scene {
return c ? c.name : id; return c ? c.name : id;
}).join(', '); }).join(', ');
this.add.text(width / 2, height / 2 + 70, `New card(s): ${cardNames}`, { this.add.text(width / 2, height / 2 + 70, `New card(s): ${cardNames}`, {
fontSize: '22px', color: '#aaffaa' fontSize: '22px', color: '#aaffaa', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
} }
@ -2957,12 +2959,12 @@ export class BattleScene extends Phaser.Scene {
const cmdCard = cardManager.getCard(unlockedCommander); const cmdCard = cardManager.getCard(unlockedCommander);
const cmdName = cmdCard ? cmdCard.name : unlockedCommander; const cmdName = cmdCard ? cmdCard.name : unlockedCommander;
this.add.text(width / 2, height / 2 + 110, `Commander unlocked: ${cmdName}!`, { this.add.text(width / 2, height / 2 + 110, `Commander unlocked: ${cmdName}!`, {
fontSize: '22px', color: '#ffdd44' fontSize: '22px', color: '#ffdd44', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
} }
} else if (!won) { } else if (!won) {
this.add.text(width / 2, height / 2 + 20, 'Better luck next time!', { this.add.text(width / 2, height / 2 + 20, 'Better luck next time!', {
fontSize: '24px', color: '#aaaaaa' fontSize: '24px', color: '#aaaaaa', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
} }
@ -2970,7 +2972,7 @@ export class BattleScene extends Phaser.Scene {
.setInteractive({ useHandCursor: true }) .setInteractive({ useHandCursor: true })
.setStrokeStyle(2, 0x4488ff); .setStrokeStyle(2, 0x4488ff);
this.add.text(width / 2, height / 2 + 160, 'Continue', { this.add.text(width / 2, height / 2 + 160, 'Continue', {
fontSize: '28px', color: '#ffffff' fontSize: '28px', color: '#ffffff', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
backBtn.on('pointerdown', () => { backBtn.on('pointerdown', () => {
if (this.missionData) { if (this.missionData) {
@ -3011,7 +3013,7 @@ export class BattleScene extends Phaser.Scene {
const bg = this.add.rectangle(80, 35, 180, 44, 0x333333) const bg = this.add.rectangle(80, 35, 180, 44, 0x333333)
.setInteractive({ useHandCursor: true }) .setInteractive({ useHandCursor: true })
.setStrokeStyle(1, 0x888888); .setStrokeStyle(1, 0x888888);
this.add.text(80, 35, '← Back', { fontSize: '18px', color: '#ffffff' }).setOrigin(0.5); this.add.text(80, 35, '← Back', { fontSize: '18px', color: '#ffffff', fontFamily: 'Audiowide' }).setOrigin(0.5);
bg.on('pointerdown', () => { bg.on('pointerdown', () => {
if (this.autoTimer) this.autoTimer.remove(); if (this.autoTimer) this.autoTimer.remove();
this.scene.start('MainMenuScene'); this.scene.start('MainMenuScene');

View File

@ -7,6 +7,10 @@ export class BootScene extends Phaser.Scene {
constructor() { super('BootScene'); } constructor() { super('BootScene'); }
preload() { preload() {
// Load custom fonts
this.load.font('RaiderCrusader', 'assets/fonts/raidercrusader.ttf');
this.load.font('Audiowide', 'assets/fonts/Audiowide-Regular.ttf');
// Load all JSON data files // Load all JSON data files
this.load.image('vs', 'assets/images/ui/vs.png'); this.load.image('vs', 'assets/images/ui/vs.png');
this.load.image('attacksFirst', 'assets/images/ui/attacksFirst.png'); this.load.image('attacksFirst', 'assets/images/ui/attacksFirst.png');
@ -51,7 +55,7 @@ export class BootScene extends Phaser.Scene {
// Loading text // Loading text
const loadText = this.add.text(this.scale.width / 2, this.scale.height / 2, 'Loading...', { const loadText = this.add.text(this.scale.width / 2, this.scale.height / 2, 'Loading...', {
fontSize: '28px', color: '#ffffff' fontSize: '28px', color: '#ffffff', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
this.load.on('progress', (value) => { this.load.on('progress', (value) => {

View File

@ -18,12 +18,12 @@ export class CampaignScene extends Phaser.Scene {
this.add.rectangle(width / 2, height / 2, width, height, 0x0d1b2a); this.add.rectangle(width / 2, height / 2, width, height, 0x0d1b2a);
this.add.text(width / 2, 45, campaign ? campaign.name : 'Campaign', { this.add.text(width / 2, 45, campaign ? campaign.name : 'Campaign', {
fontSize: '42px', color: '#d4af37' fontSize: '42px', color: '#d4af37', fontFamily: 'RaiderCrusader'
}).setOrigin(0.5); }).setOrigin(0.5);
if (campaign) { if (campaign) {
this.add.text(width / 2, 90, `Level ${campaign.level} — ${campaign.faction.toUpperCase()}`, { this.add.text(width / 2, 90, `Level ${campaign.level} — ${campaign.faction.toUpperCase()}`, {
fontSize: '18px', color: '#888888' fontSize: '18px', color: '#888888', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
} }
@ -56,32 +56,32 @@ export class CampaignScene extends Phaser.Scene {
this.add.text(x, y - 70, mission.name, { this.add.text(x, y - 70, mission.name, {
fontSize: '20px', color: isUnlocked ? '#ffffff' : '#666666', fontSize: '20px', color: isUnlocked ? '#ffffff' : '#666666',
wordWrap: { width: 270 }, align: 'center' wordWrap: { width: 270 }, align: 'center', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
this.add.text(x, y - 35, `Mission ${i + 1}`, { this.add.text(x, y - 35, `Mission ${i + 1}`, {
fontSize: '16px', color: '#888888' fontSize: '16px', color: '#888888', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
this.add.text(x, y, isDone ? 'Complete' : isUnlocked ? 'Click to battle' : 'Locked', { this.add.text(x, y, isDone ? 'Complete' : isUnlocked ? 'Click to battle' : 'Locked', {
fontSize: '16px', color: isDone ? '#44ff44' : isUnlocked ? '#aaffaa' : '#666666' fontSize: '16px', color: isDone ? '#44ff44' : isUnlocked ? '#aaffaa' : '#666666', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
// Rewards // Rewards
this.add.text(x, y + 30, `+${mission.rewards.gold} gold`, { this.add.text(x, y + 30, `+${mission.rewards.gold} gold`, {
fontSize: '14px', color: '#ffd700' fontSize: '14px', color: '#ffd700', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
if (mission.rewards.cards && mission.rewards.cards.length > 0) { if (mission.rewards.cards && mission.rewards.cards.length > 0) {
this.add.text(x, y + 55, `Card reward available`, { this.add.text(x, y + 55, `Card reward available`, {
fontSize: '14px', color: '#aaffaa' fontSize: '14px', color: '#aaffaa', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
} }
}); });
// Mission lore panel // Mission lore panel
this.loreText = this.add.text(width / 2, height - 70, 'Hover over a mission to learn more.', { this.loreText = this.add.text(width / 2, height - 70, 'Hover over a mission to learn more.', {
fontSize: '18px', color: '#888888', align: 'center', wordWrap: { width: width - 100 } fontSize: '18px', color: '#888888', align: 'center', wordWrap: { width: width - 100 }, fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
this._makeBackButton(); this._makeBackButton();
@ -91,7 +91,7 @@ export class CampaignScene extends Phaser.Scene {
const save = this.registry.get('save'); const save = this.registry.get('save');
if (!save.decks || save.decks.length === 0) { if (!save.decks || save.decks.length === 0) {
this.add.text(960, 940, 'No deck! Create a deck in Deck Builder first.', { this.add.text(960, 940, 'No deck! Create a deck in Deck Builder first.', {
fontSize: '22px', color: '#ff4444' fontSize: '22px', color: '#ff4444', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
return; return;
} }
@ -133,7 +133,7 @@ export class CampaignScene extends Phaser.Scene {
const bg = this.add.rectangle(80, 45, 160, 50, 0x333333) const bg = this.add.rectangle(80, 45, 160, 50, 0x333333)
.setInteractive({ useHandCursor: true }) .setInteractive({ useHandCursor: true })
.setStrokeStyle(1, 0x888888); .setStrokeStyle(1, 0x888888);
this.add.text(80, 45, 'Back', { fontSize: '18px', color: '#ffffff' }).setOrigin(0.5); this.add.text(80, 45, 'Back', { fontSize: '18px', color: '#ffffff', fontFamily: 'Audiowide' }).setOrigin(0.5);
bg.on('pointerdown', () => { bg.on('pointerdown', () => {
this.sound.play('sfx_menu_select', { volume: 0.7 }); this.sound.play('sfx_menu_select', { volume: 0.7 });
this.scene.start('CampaignSelectScene'); this.scene.start('CampaignSelectScene');

View File

@ -13,11 +13,11 @@ export class CampaignSelectScene extends Phaser.Scene {
this.add.rectangle(width / 2, height / 2, width, height, 0x0d1b2a); this.add.rectangle(width / 2, height / 2, width, height, 0x0d1b2a);
this.add.text(width / 2, 45, 'Select Campaign', { this.add.text(width / 2, 45, 'Select Campaign', {
fontSize: '42px', color: '#d4af37' fontSize: '42px', color: '#d4af37', fontFamily: 'RaiderCrusader'
}).setOrigin(0.5); }).setOrigin(0.5);
this.add.text(width / 2, 95, `Player Level: ${save.level || 1}`, { this.add.text(width / 2, 95, `Player Level: ${save.level || 1}`, {
fontSize: '20px', color: '#88aaff' fontSize: '20px', color: '#88aaff', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
const FACTION_COLORS = { const FACTION_COLORS = {
@ -50,25 +50,25 @@ export class CampaignSelectScene extends Phaser.Scene {
const nameColor = isUnlocked ? '#ffffff' : '#666666'; const nameColor = isUnlocked ? '#ffffff' : '#666666';
this.add.text(x, y - 150, campaign.name, { this.add.text(x, y - 150, campaign.name, {
fontSize: '22px', color: nameColor, fontStyle: 'bold', fontSize: '22px', color: nameColor, fontStyle: 'bold',
wordWrap: { width: 270 }, align: 'center' wordWrap: { width: 270 }, align: 'center', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
// Faction label // Faction label
const fColor = FACTION_COLORS[campaign.faction] || '#888888'; const fColor = FACTION_COLORS[campaign.faction] || '#888888';
this.add.text(x, y - 115, campaign.faction.toUpperCase(), { this.add.text(x, y - 115, campaign.faction.toUpperCase(), {
fontSize: '14px', color: fColor fontSize: '14px', color: fColor, fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
// Level requirement // Level requirement
this.add.text(x, y - 85, `Level ${campaign.level}`, { this.add.text(x, y - 85, `Level ${campaign.level}`, {
fontSize: '16px', color: '#aaaaaa' fontSize: '16px', color: '#aaaaaa', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
// Progress or lock status // Progress or lock status
if (isUnlocked) { if (isUnlocked) {
if (campaign.missions.length === 0) { if (campaign.missions.length === 0) {
this.add.text(x, y, 'Coming Soon', { this.add.text(x, y, 'Coming Soon', {
fontSize: '18px', color: '#888844' fontSize: '18px', color: '#888844', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
} else { } else {
const progressStr = isComplete const progressStr = isComplete
@ -76,7 +76,7 @@ export class CampaignSelectScene extends Phaser.Scene {
: `${completedMissions.length} / ${campaign.missions.length} missions`; : `${completedMissions.length} / ${campaign.missions.length} missions`;
const progressColor = isComplete ? '#44ff44' : '#aaffaa'; const progressColor = isComplete ? '#44ff44' : '#aaffaa';
this.add.text(x, y - 20, progressStr, { this.add.text(x, y - 20, progressStr, {
fontSize: '16px', color: progressColor fontSize: '16px', color: progressColor, fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
// Click to play // Click to play
@ -89,23 +89,23 @@ export class CampaignSelectScene extends Phaser.Scene {
}); });
this.add.text(x, y + 30, 'Click to play', { this.add.text(x, y + 30, 'Click to play', {
fontSize: '14px', color: '#88aaff' fontSize: '14px', color: '#88aaff', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
} }
// Starter reward info // Starter reward info
if (campaign.starterReward?.cards?.length > 0 && !isComplete) { if (campaign.starterReward?.cards?.length > 0 && !isComplete) {
this.add.text(x, y + 80, 'Completion Reward:', { this.add.text(x, y + 80, 'Completion Reward:', {
fontSize: '13px', color: '#ffd700' fontSize: '13px', color: '#ffd700', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
this.add.text(x, y + 100, `${campaign.starterReward.cards.length} cards`, { this.add.text(x, y + 100, `${campaign.starterReward.cards.length} cards`, {
fontSize: '13px', color: '#ffeeaa' fontSize: '13px', color: '#ffeeaa', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
} }
} else { } else {
// Locked // Locked
this.add.text(x, y - 20, 'LOCKED', { this.add.text(x, y - 20, 'LOCKED', {
fontSize: '24px', color: '#555555', fontStyle: 'bold' fontSize: '24px', color: '#555555', fontStyle: 'bold', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
// Unlock requirement // Unlock requirement
@ -114,7 +114,7 @@ export class CampaignSelectScene extends Phaser.Scene {
: `Requires Level ${campaign.requiredLevel}`; : `Requires Level ${campaign.requiredLevel}`;
this.add.text(x, y + 20, reqText, { this.add.text(x, y + 20, reqText, {
fontSize: '13px', color: '#666666', fontSize: '13px', color: '#666666',
wordWrap: { width: 260 }, align: 'center' wordWrap: { width: 260 }, align: 'center', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
} }
}); });
@ -126,7 +126,7 @@ export class CampaignSelectScene extends Phaser.Scene {
const bg = this.add.rectangle(80, 45, 160, 50, 0x333333) const bg = this.add.rectangle(80, 45, 160, 50, 0x333333)
.setInteractive({ useHandCursor: true }) .setInteractive({ useHandCursor: true })
.setStrokeStyle(1, 0x888888); .setStrokeStyle(1, 0x888888);
this.add.text(80, 45, 'Back', { fontSize: '18px', color: '#ffffff' }).setOrigin(0.5); this.add.text(80, 45, 'Back', { fontSize: '18px', color: '#ffffff', fontFamily: 'Audiowide' }).setOrigin(0.5);
bg.on('pointerdown', () => { bg.on('pointerdown', () => {
this.sound.play('sfx_menu_select', { volume: 0.7 }); this.sound.play('sfx_menu_select', { volume: 0.7 });
this.scene.start('MainMenuScene'); this.scene.start('MainMenuScene');

View File

@ -110,14 +110,14 @@ export class CollectionScene extends Phaser.Scene {
// Title // Title
this.add.text(30, 22, 'COLLECTION', { this.add.text(30, 22, 'COLLECTION', {
fontSize: '32px', color: '#d4af37', fontStyle: 'bold' fontSize: '32px', color: '#d4af37', fontStyle: 'bold', fontFamily: 'Audiowide'
}).setOrigin(0, 0); }).setOrigin(0, 0);
// Owned count // Owned count
const totalCards = this.cardManager.getAllCards().length; const totalCards = this.cardManager.getAllCards().length;
const ownedCards = Object.keys(this.save.collection).length; const ownedCards = Object.keys(this.save.collection).length;
this.ownedText = this.add.text(320, 30, `Owned: ${ownedCards}/${totalCards}`, { this.ownedText = this.add.text(320, 30, `Owned: ${ownedCards}/${totalCards}`, {
fontSize: '18px', color: '#888888' fontSize: '18px', color: '#888888', fontFamily: 'Audiowide'
}).setOrigin(0, 0); }).setOrigin(0, 0);
// Faction filters // Faction filters
@ -157,7 +157,7 @@ export class CollectionScene extends Phaser.Scene {
const padX = 14; const padX = 14;
const h = 24; const h = 24;
const displayLabel = label.charAt(0).toUpperCase() + label.slice(1); const displayLabel = label.charAt(0).toUpperCase() + label.slice(1);
const tmpText = this.add.text(0, 0, displayLabel, { fontSize: '14px' }); const tmpText = this.add.text(0, 0, displayLabel, { fontSize: '14px', fontFamily: 'Audiowide' });
const textW = tmpText.width; const textW = tmpText.width;
tmpText.destroy(); tmpText.destroy();
const w = textW + padX * 2; const w = textW + padX * 2;
@ -166,7 +166,7 @@ export class CollectionScene extends Phaser.Scene {
.setInteractive({ useHandCursor: true }) .setInteractive({ useHandCursor: true })
.setStrokeStyle(1, 0x666688); .setStrokeStyle(1, 0x666688);
const text = this.add.text(x + w / 2, y + h / 2, displayLabel, { const text = this.add.text(x + w / 2, y + h / 2, displayLabel, {
fontSize: '14px', color: '#ffffff' fontSize: '14px', color: '#ffffff', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
bg.on('pointerdown', onClick); bg.on('pointerdown', onClick);
@ -276,7 +276,7 @@ export class CollectionScene extends Phaser.Scene {
const emptyText = this.add.text( const emptyText = this.add.text(
GRID_PAD_X + GRID_W / 2, GRID_PAD_Y + GRID_H / 2, GRID_PAD_X + GRID_W / 2, GRID_PAD_Y + GRID_H / 2,
'No cards match the current filter.', 'No cards match the current filter.',
{ fontSize: '22px', color: '#666666' } { fontSize: '22px', color: '#666666', fontFamily: 'Audiowide' }
).setOrigin(0.5); ).setOrigin(0.5);
this.gridContainer.add(emptyText); this.gridContainer.add(emptyText);
this._gridCards.push(emptyText); this._gridCards.push(emptyText);
@ -404,11 +404,11 @@ export class CollectionScene extends Phaser.Scene {
.setStrokeStyle(1, 0x222244); .setStrokeStyle(1, 0x222244);
this._showcasePlaceholder = this.add.text(cx, cy, 'SELECT A CARD', { this._showcasePlaceholder = this.add.text(cx, cy, 'SELECT A CARD', {
fontSize: '24px', color: '#333355', fontStyle: 'bold' fontSize: '24px', color: '#333355', fontStyle: 'bold', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
this._showcaseNotCollected = this.add.text(cx, cy + 190, 'NOT COLLECTED', { this._showcaseNotCollected = this.add.text(cx, cy + 190, 'NOT COLLECTED', {
fontSize: '16px', color: '#aa3333', fontStyle: 'bold' fontSize: '16px', color: '#aa3333', fontStyle: 'bold', fontFamily: 'Audiowide'
}).setOrigin(0.5).setVisible(false); }).setOrigin(0.5).setVisible(false);
} }
@ -742,7 +742,7 @@ export class CollectionScene extends Phaser.Scene {
const bg = this.add.rectangle(80, 1040, 140, 40, 0x333333) const bg = this.add.rectangle(80, 1040, 140, 40, 0x333333)
.setInteractive({ useHandCursor: true }) .setInteractive({ useHandCursor: true })
.setStrokeStyle(1, 0x888888); .setStrokeStyle(1, 0x888888);
this.add.text(80, 1040, 'Back', { fontSize: '18px', color: '#ffffff' }).setOrigin(0.5); this.add.text(80, 1040, 'Back', { fontSize: '18px', color: '#ffffff', fontFamily: 'Audiowide' }).setOrigin(0.5);
bg.on('pointerdown', () => this.scene.start('MainMenuScene')); bg.on('pointerdown', () => this.scene.start('MainMenuScene'));
bg.on('pointerover', () => bg.setStrokeStyle(2, 0xaaaaaa)); bg.on('pointerover', () => bg.setStrokeStyle(2, 0xaaaaaa));
bg.on('pointerout', () => bg.setStrokeStyle(1, 0x888888)); bg.on('pointerout', () => bg.setStrokeStyle(1, 0x888888));

View File

@ -36,7 +36,7 @@ export class DeckBuilderScene extends Phaser.Scene {
scanlines.fillRect(0, y, width, 1); scanlines.fillRect(0, y, width, 1);
} }
this.add.text(width / 2, 36, 'Deck Builder', { fontSize: '38px', color: '#d4af37' }).setOrigin(0.5); this.add.text(width / 2, 36, 'Deck Builder', { fontSize: '38px', color: '#d4af37', fontFamily: 'RaiderCrusader' }).setOrigin(0.5);
const save = this.registry.get('save'); const save = this.registry.get('save');
this.cardManager = this.registry.get('cardManager'); this.cardManager = this.registry.get('cardManager');
@ -118,7 +118,7 @@ export class DeckBuilderScene extends Phaser.Scene {
// ── Commander section ── // ── Commander section ──
if (commanders.length > 0) { if (commanders.length > 0) {
const cmdLabel = this.add.text(this.GRID_LEFT, cursorY, 'Commanders', { const cmdLabel = this.add.text(this.GRID_LEFT, cursorY, 'Commanders', {
fontSize: '18px', color: '#d4af37' fontSize: '18px', color: '#d4af37', fontFamily: 'Audiowide'
}); });
this.scrollContainer.add(cmdLabel); this.scrollContainer.add(cmdLabel);
@ -139,7 +139,7 @@ export class DeckBuilderScene extends Phaser.Scene {
// ── Assault section ── // ── Assault section ──
if (assaults.length > 0) { if (assaults.length > 0) {
const assLabel = this.add.text(this.GRID_LEFT, cursorY, 'Assault Cards', { const assLabel = this.add.text(this.GRID_LEFT, cursorY, 'Assault Cards', {
fontSize: '18px', color: '#d4af37' fontSize: '18px', color: '#d4af37', fontFamily: 'Audiowide'
}); });
this.scrollContainer.add(assLabel); this.scrollContainer.add(assLabel);
@ -160,7 +160,7 @@ export class DeckBuilderScene extends Phaser.Scene {
// Show empty message if all filtered out // Show empty message if all filtered out
if (commanders.length === 0 && assaults.length === 0) { if (commanders.length === 0 && assaults.length === 0) {
const emptyTxt = this.add.text(500, 400, 'No cards match the current filters.', { const emptyTxt = this.add.text(500, 400, 'No cards match the current filters.', {
fontSize: '20px', color: '#666666' fontSize: '20px', color: '#666666', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
this.scrollContainer.add(emptyTxt); this.scrollContainer.add(emptyTxt);
} }
@ -194,7 +194,7 @@ export class DeckBuilderScene extends Phaser.Scene {
// Owned/used count // Owned/used count
const countY = cy + this.CARD_H / 2 + 4; const countY = cy + this.CARD_H / 2 + 4;
const countText = this.add.text(cx, countY, `Owned: ${owned} | In Deck: ${used}`, { const countText = this.add.text(cx, countY, `Owned: ${owned} | In Deck: ${used}`, {
fontSize: '11px', color: canAdd ? '#88cc88' : '#555555' fontSize: '11px', color: canAdd ? '#88cc88' : '#555555', fontFamily: 'Audiowide'
}).setOrigin(0.5, 0); }).setOrigin(0.5, 0);
this.scrollContainer.add(countText); this.scrollContainer.add(countText);
@ -204,7 +204,7 @@ export class DeckBuilderScene extends Phaser.Scene {
const btnBg = this.add.rectangle(cx, btnY, this.CARD_W - 10, this.BTN_H, canAdd ? 0x225522 : 0x222222) const btnBg = this.add.rectangle(cx, btnY, this.CARD_W - 10, this.BTN_H, canAdd ? 0x225522 : 0x222222)
.setStrokeStyle(1, canAdd ? 0x44aa44 : 0x333333); .setStrokeStyle(1, canAdd ? 0x44aa44 : 0x333333);
const btnTxt = this.add.text(cx, btnY, btnLabel, { const btnTxt = this.add.text(cx, btnY, btnLabel, {
fontSize: '12px', color: canAdd ? '#44ff44' : '#444444' fontSize: '12px', color: canAdd ? '#44ff44' : '#444444', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
this.scrollContainer.add(btnBg); this.scrollContainer.add(btnBg);
this.scrollContainer.add(btnTxt); this.scrollContainer.add(btnTxt);
@ -255,7 +255,7 @@ export class DeckBuilderScene extends Phaser.Scene {
this.deckPanelGroup.push(panelBg); this.deckPanelGroup.push(panelBg);
const title = this.add.text(panelCX, 90, 'Current Deck', { const title = this.add.text(panelCX, 90, 'Current Deck', {
fontSize: '24px', color: '#d4af37' fontSize: '24px', color: '#d4af37', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
this.deckPanelGroup.push(title); this.deckPanelGroup.push(title);
@ -264,7 +264,7 @@ export class DeckBuilderScene extends Phaser.Scene {
const cmdBg = this.add.rectangle(panelCX, 140, PANEL_W - 40, 46, cmdCard ? 0x1a3a5c : 0x1a1a2e) const cmdBg = this.add.rectangle(panelCX, 140, PANEL_W - 40, 46, cmdCard ? 0x1a3a5c : 0x1a1a2e)
.setStrokeStyle(2, 0xffd700); .setStrokeStyle(2, 0xffd700);
const cmdText = this.add.text(panelCX, 140, cmdCard ? `Commander: ${cmdCard.name}` : 'No Commander Selected', { const cmdText = this.add.text(panelCX, 140, cmdCard ? `Commander: ${cmdCard.name}` : 'No Commander Selected', {
fontSize: '17px', color: cmdCard ? '#ffd700' : '#555555' fontSize: '17px', color: cmdCard ? '#ffd700' : '#555555', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
this.deckPanelGroup.push(cmdBg, cmdText); this.deckPanelGroup.push(cmdBg, cmdText);
@ -272,7 +272,7 @@ export class DeckBuilderScene extends Phaser.Scene {
const rmBtn = this.add.rectangle(panelCX + PANEL_W / 2 - 40, 140, 34, 28, 0x662222) const rmBtn = this.add.rectangle(panelCX + PANEL_W / 2 - 40, 140, 34, 28, 0x662222)
.setInteractive({ useHandCursor: true }).setStrokeStyle(1, 0xff4444); .setInteractive({ useHandCursor: true }).setStrokeStyle(1, 0xff4444);
const rmTxt = this.add.text(panelCX + PANEL_W / 2 - 40, 140, 'X', { const rmTxt = this.add.text(panelCX + PANEL_W / 2 - 40, 140, 'X', {
fontSize: '14px', color: '#ff4444' fontSize: '14px', color: '#ff4444', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
rmBtn.on('pointerdown', () => { rmBtn.on('pointerdown', () => {
const oldCmd = this.workingDeck.commander; const oldCmd = this.workingDeck.commander;
@ -301,20 +301,20 @@ export class DeckBuilderScene extends Phaser.Scene {
const bg = this.add.rectangle(panelCX, y, PANEL_W - 40, ENTRY_H - 4, 0x1a3a5c) const bg = this.add.rectangle(panelCX, y, PANEL_W - 40, ENTRY_H - 4, 0x1a3a5c)
.setStrokeStyle(1, rarityColors[card.rarity] || 0x336699); .setStrokeStyle(1, rarityColors[card.rarity] || 0x336699);
const txt = this.add.text(PANEL_X + 30, y, `${card.name}`, { const txt = this.add.text(PANEL_X + 30, y, `${card.name}`, {
fontSize: '15px', color: '#ffffff' fontSize: '15px', color: '#ffffff', fontFamily: 'Audiowide'
}).setOrigin(0, 0.5); }).setOrigin(0, 0.5);
const countTxt = this.add.text(PANEL_X + 300, y, `x${count}`, { const countTxt = this.add.text(PANEL_X + 300, y, `x${count}`, {
fontSize: '15px', color: '#aaaaaa' fontSize: '15px', color: '#aaaaaa', fontFamily: 'Audiowide'
}).setOrigin(0, 0.5); }).setOrigin(0, 0.5);
const lv1 = card.levels[0]; const lv1 = card.levels[0];
const statsTxt = this.add.text(PANEL_X + 360, y, `ATK:${lv1.attack} HP:${lv1.health}`, { const statsTxt = this.add.text(PANEL_X + 360, y, `ATK:${lv1.attack} HP:${lv1.health}`, {
fontSize: '13px', color: '#8888cc' fontSize: '13px', color: '#8888cc', fontFamily: 'Audiowide'
}).setOrigin(0, 0.5); }).setOrigin(0, 0.5);
const rmBtn = this.add.rectangle(panelCX + PANEL_W / 2 - 40, y, 34, 28, 0x662222) const rmBtn = this.add.rectangle(panelCX + PANEL_W / 2 - 40, y, 34, 28, 0x662222)
.setInteractive({ useHandCursor: true }).setStrokeStyle(1, 0xff4444); .setInteractive({ useHandCursor: true }).setStrokeStyle(1, 0xff4444);
const rmTxt = this.add.text(panelCX + PANEL_W / 2 - 40, y, '-', { const rmTxt = this.add.text(panelCX + PANEL_W / 2 - 40, y, '-', {
fontSize: '18px', color: '#ff4444' fontSize: '18px', color: '#ff4444', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
rmBtn.on('pointerdown', () => { rmBtn.on('pointerdown', () => {
const idx = this.workingDeck.cards.lastIndexOf(cardId); const idx = this.workingDeck.cards.lastIndexOf(cardId);
@ -337,7 +337,7 @@ export class DeckBuilderScene extends Phaser.Scene {
const slotBg = this.add.rectangle(panelCX, y, PANEL_W - 40, ENTRY_H - 4, 0x0d0d1a) const slotBg = this.add.rectangle(panelCX, y, PANEL_W - 40, ENTRY_H - 4, 0x0d0d1a)
.setStrokeStyle(1, 0x222244); .setStrokeStyle(1, 0x222244);
const slotTxt = this.add.text(panelCX, y, '— empty slot —', { const slotTxt = this.add.text(panelCX, y, '— empty slot —', {
fontSize: '13px', color: '#333355' fontSize: '13px', color: '#333355', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
this.deckPanelGroup.push(slotBg, slotTxt); this.deckPanelGroup.push(slotBg, slotTxt);
y += ENTRY_H; y += ENTRY_H;
@ -346,14 +346,14 @@ export class DeckBuilderScene extends Phaser.Scene {
// Card count // Card count
const countColor = filled > 10 ? '#ff4444' : filled >= 3 ? '#aaaaff' : '#888888'; const countColor = filled > 10 ? '#ff4444' : filled >= 3 ? '#aaaaff' : '#888888';
const totalTxt = this.add.text(panelCX, y + 16, `Cards: ${filled} / 10`, { const totalTxt = this.add.text(panelCX, y + 16, `Cards: ${filled} / 10`, {
fontSize: '18px', color: countColor fontSize: '18px', color: countColor, fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
this.deckPanelGroup.push(totalTxt); this.deckPanelGroup.push(totalTxt);
// Validation // Validation
const validation = DeckManager.validate(this.workingDeck, this.cardManager); const validation = DeckManager.validate(this.workingDeck, this.cardManager);
const validTxt = this.add.text(panelCX, y + 44, validation.valid ? 'Valid Deck' : validation.errors[0], { const validTxt = this.add.text(panelCX, y + 44, validation.valid ? 'Valid Deck' : validation.errors[0], {
fontSize: '15px', color: validation.valid ? '#44ff44' : '#ff6644' fontSize: '15px', color: validation.valid ? '#44ff44' : '#ff6644', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
this.deckPanelGroup.push(validTxt); this.deckPanelGroup.push(validTxt);
@ -365,7 +365,7 @@ export class DeckBuilderScene extends Phaser.Scene {
const saveBg = this.add.rectangle(panelCX - 110, saveBtnY, 190, 46, 0x224422) const saveBg = this.add.rectangle(panelCX - 110, saveBtnY, 190, 46, 0x224422)
.setInteractive({ useHandCursor: true }).setStrokeStyle(2, 0x44aa44); .setInteractive({ useHandCursor: true }).setStrokeStyle(2, 0x44aa44);
const saveTxt = this.add.text(panelCX - 110, saveBtnY, 'Save Deck', { const saveTxt = this.add.text(panelCX - 110, saveBtnY, 'Save Deck', {
fontSize: '18px', color: '#ffffff' fontSize: '18px', color: '#ffffff', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
saveBg.on('pointerdown', () => { saveBg.on('pointerdown', () => {
const save = this.registry.get('save'); const save = this.registry.get('save');
@ -379,7 +379,7 @@ export class DeckBuilderScene extends Phaser.Scene {
const clearBg = this.add.rectangle(panelCX + 110, saveBtnY, 190, 46, 0x442222) const clearBg = this.add.rectangle(panelCX + 110, saveBtnY, 190, 46, 0x442222)
.setInteractive({ useHandCursor: true }).setStrokeStyle(2, 0xaa4444); .setInteractive({ useHandCursor: true }).setStrokeStyle(2, 0xaa4444);
const clearTxt = this.add.text(panelCX + 110, saveBtnY, 'Clear Deck', { const clearTxt = this.add.text(panelCX + 110, saveBtnY, 'Clear Deck', {
fontSize: '18px', color: '#ffffff' fontSize: '18px', color: '#ffffff', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
clearBg.on('pointerdown', () => { clearBg.on('pointerdown', () => {
this.workingDeck.commander = null; this.workingDeck.commander = null;
@ -419,7 +419,7 @@ export class DeckBuilderScene extends Phaser.Scene {
// ── Faction header ── // ── Faction header ──
const fHeader = this.add.text(PANEL_X + 20, y, 'Faction', { const fHeader = this.add.text(PANEL_X + 20, y, 'Faction', {
fontSize: '14px', color: '#d4af37', fontStyle: 'bold' fontSize: '14px', color: '#d4af37', fontStyle: 'bold', fontFamily: 'Audiowide'
}); });
this.filterGroup.push(fHeader); this.filterGroup.push(fHeader);
y += ROW_H; y += ROW_H;
@ -433,7 +433,7 @@ export class DeckBuilderScene extends Phaser.Scene {
// ── Rarity header ── // ── Rarity header ──
const rHeader = this.add.text(PANEL_X + 20, y, 'Rarity', { const rHeader = this.add.text(PANEL_X + 20, y, 'Rarity', {
fontSize: '14px', color: '#d4af37', fontStyle: 'bold' fontSize: '14px', color: '#d4af37', fontStyle: 'bold', fontFamily: 'Audiowide'
}); });
this.filterGroup.push(rHeader); this.filterGroup.push(rHeader);
y += ROW_H; y += ROW_H;
@ -458,14 +458,14 @@ export class DeckBuilderScene extends Phaser.Scene {
let checkmark = null; let checkmark = null;
if (active) { if (active) {
checkmark = this.add.text(cx, y, '\u2713', { checkmark = this.add.text(cx, y, '\u2713', {
fontSize: '12px', color: '#ffffff', fontStyle: 'bold' fontSize: '12px', color: '#ffffff', fontStyle: 'bold', fontFamily: 'Audiowide'
}).setOrigin(0.5, 0.4); }).setOrigin(0.5, 0.4);
this.filterGroup.push(checkmark); this.filterGroup.push(checkmark);
} }
// Label text // Label text
const txt = this.add.text(cx + checkSize / 2 + 8, y + 1, label, { const txt = this.add.text(cx + checkSize / 2 + 8, y + 1, label, {
fontSize: '13px', color: active ? colorStr : '#555555' fontSize: '13px', color: active ? colorStr : '#555555', fontFamily: 'Audiowide'
}).setOrigin(0, 0.5); }).setOrigin(0, 0.5);
// Hit area covers the full row for easy clicking // Hit area covers the full row for easy clicking
@ -492,7 +492,7 @@ export class DeckBuilderScene extends Phaser.Scene {
const backBtn = this.add.rectangle(80, this.scale.height - 40, 140, 40, 0x333333) const backBtn = this.add.rectangle(80, this.scale.height - 40, 140, 40, 0x333333)
.setInteractive({ useHandCursor: true }).setStrokeStyle(1, 0x888888); .setInteractive({ useHandCursor: true }).setStrokeStyle(1, 0x888888);
this.add.text(80, this.scale.height - 40, 'Back', { this.add.text(80, this.scale.height - 40, 'Back', {
fontSize: '18px', color: '#ffffff' fontSize: '18px', color: '#ffffff', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
backBtn.on('pointerdown', () => this.scene.start('MainMenuScene')); backBtn.on('pointerdown', () => this.scene.start('MainMenuScene'));
} }
@ -500,7 +500,7 @@ export class DeckBuilderScene extends Phaser.Scene {
_showMsg(msg, color) { _showMsg(msg, color) {
const { width } = this.scale; const { width } = this.scale;
const t = this.add.text(width / 2, this.scale.height - 100, msg, { const t = this.add.text(width / 2, this.scale.height - 100, msg, {
fontSize: '18px', color fontSize: '18px', color, fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
this.time.delayedCall(2000, () => { if (t.scene) t.destroy(); }); this.time.delayedCall(2000, () => { if (t.scene) t.destroy(); });
} }

View File

@ -104,10 +104,10 @@ export class FusionScene extends Phaser.Scene {
_buildHeader() { _buildHeader() {
this.add.text(360, 28, 'FUSION LAB', { this.add.text(360, 28, 'FUSION LAB', {
fontSize: '36px', color: '#d4af37', fontStyle: 'bold' fontSize: '36px', color: '#d4af37', fontStyle: 'bold', fontFamily: 'RaiderCrusader'
}).setOrigin(0.5); }).setOrigin(0.5);
this.add.text(360, 58, 'Combine 3 copies of a card to forge a stronger one', { this.add.text(360, 58, 'Combine 3 copies of a card to forge a stronger one', {
fontSize: '16px', color: '#888888' fontSize: '16px', color: '#888888', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
} }
@ -115,7 +115,7 @@ export class FusionScene extends Phaser.Scene {
_buildStacksArea() { _buildStacksArea() {
this.add.text(STACKS_LEFT + 10, STACKS_TOP - 22, 'AVAILABLE CARDS', { this.add.text(STACKS_LEFT + 10, STACKS_TOP - 22, 'AVAILABLE CARDS', {
fontSize: '14px', color: '#aaaaaa', fontStyle: 'bold' fontSize: '14px', color: '#aaaaaa', fontStyle: 'bold', fontFamily: 'Audiowide'
}); });
this.stacksContainer = this.add.container(0, 0); this.stacksContainer = this.add.container(0, 0);
@ -148,7 +148,7 @@ export class FusionScene extends Phaser.Scene {
this._previewTitle = this.add.text(PREVIEW_LEFT + PREVIEW_W / 2, PREVIEW_TOP + 15, this._previewTitle = this.add.text(PREVIEW_LEFT + PREVIEW_W / 2, PREVIEW_TOP + 15,
'POSSIBLE RESULTS', { 'POSSIBLE RESULTS', {
fontSize: '18px', color: '#d4af37', fontStyle: 'bold' fontSize: '18px', color: '#d4af37', fontStyle: 'bold', fontFamily: 'Audiowide'
}).setOrigin(0.5).setVisible(false); }).setOrigin(0.5).setVisible(false);
this._previewContainer = this.add.container(0, 0); this._previewContainer = this.add.container(0, 0);
@ -161,12 +161,12 @@ export class FusionScene extends Phaser.Scene {
.setStrokeStyle(1, 0x334466); .setStrokeStyle(1, 0x334466);
this.add.text(DECK_LEFT + DECK_W / 2, DECK_TOP + 20, 'YOUR DECK', { this.add.text(DECK_LEFT + DECK_W / 2, DECK_TOP + 20, 'YOUR DECK', {
fontSize: '20px', color: '#d4af37', fontStyle: 'bold' fontSize: '20px', color: '#d4af37', fontStyle: 'bold', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
this.add.text(DECK_LEFT + DECK_W / 2, DECK_TOP + 50, this.add.text(DECK_LEFT + DECK_W / 2, DECK_TOP + 50,
'Cards in your deck cannot be fused.\nRemove them in Deck Builder first.', { 'Cards in your deck cannot be fused.\nRemove them in Deck Builder first.', {
fontSize: '13px', color: '#666666', align: 'center', lineSpacing: 4 fontSize: '13px', color: '#666666', align: 'center', lineSpacing: 4, fontFamily: 'Audiowide'
}).setOrigin(0.5, 0); }).setOrigin(0.5, 0);
this._deckContainer = this.add.container(0, 0); this._deckContainer = this.add.container(0, 0);
@ -184,7 +184,7 @@ export class FusionScene extends Phaser.Scene {
const save = this.save; const save = this.save;
if (!save.decks || save.decks.length === 0) { if (!save.decks || save.decks.length === 0) {
const t = this.add.text(DECK_LEFT + DECK_W / 2, DECK_TOP + 160, 'No deck created yet.', { const t = this.add.text(DECK_LEFT + DECK_W / 2, DECK_TOP + 160, 'No deck created yet.', {
fontSize: '16px', color: '#555555' fontSize: '16px', color: '#555555', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
this._deckContainer.add(t); this._deckContainer.add(t);
return; return;
@ -202,7 +202,7 @@ export class FusionScene extends Phaser.Scene {
const entries = Object.entries(counts); const entries = Object.entries(counts);
if (entries.length === 0) { if (entries.length === 0) {
const t = this.add.text(DECK_LEFT + DECK_W / 2, DECK_TOP + 160, const t = this.add.text(DECK_LEFT + DECK_W / 2, DECK_TOP + 160,
'Deck is empty.', { fontSize: '16px', color: '#555555' }).setOrigin(0.5); 'Deck is empty.', { fontSize: '16px', color: '#555555', fontFamily: 'Audiowide' }).setOrigin(0.5);
this._deckContainer.add(t); this._deckContainer.add(t);
return; return;
} }
@ -231,7 +231,7 @@ export class FusionScene extends Phaser.Scene {
if (count > 1) { if (count > 1) {
const badge = this.add.text(x + thumbW / 2 - 2, y - thumbH / 2 + 2, `×${count}`, { const badge = this.add.text(x + thumbW / 2 - 2, y - thumbH / 2 + 2, `×${count}`, {
fontSize: '14px', color: '#ffffff', fontStyle: 'bold', fontSize: '14px', color: '#ffffff', fontStyle: 'bold',
backgroundColor: '#000000aa', padding: { x: 3, y: 2 } backgroundColor: '#000000aa', padding: { x: 3, y: 2 }, fontFamily: 'Audiowide'
}).setOrigin(1, 0); }).setOrigin(1, 0);
this._deckContainer.add(badge); this._deckContainer.add(badge);
} }
@ -242,14 +242,14 @@ export class FusionScene extends Phaser.Scene {
_buildBottomBar() { _buildBottomBar() {
// Recipe reference // Recipe reference
this.add.text(40, 850, 'Fusion Recipes:', { fontSize: '16px', color: '#d4af37' }); this.add.text(40, 850, 'Fusion Recipes:', { fontSize: '16px', color: '#d4af37', fontFamily: 'Audiowide' });
['3× Common → Rare', '3× Rare → Epic', '3× Epic → Legendary'].forEach((r, i) => { ['3× Common → Rare', '3× Rare → Epic', '3× Epic → Legendary'].forEach((r, i) => {
this.add.text(40, 875 + i * 22, r, { fontSize: '14px', color: '#888888' }); this.add.text(40, 875 + i * 22, r, { fontSize: '14px', color: '#888888', fontFamily: 'Audiowide' });
}); });
// Info text (visible when a stack is selected) // Info text (visible when a stack is selected)
this._fuseInfoText = this.add.text(1060, 855, '', { this._fuseInfoText = this.add.text(1060, 855, '', {
fontSize: '20px', color: '#ffffff' fontSize: '20px', color: '#ffffff', fontFamily: 'Audiowide'
}).setOrigin(0.5).setVisible(false); }).setOrigin(0.5).setVisible(false);
// Fuse button // Fuse button
@ -258,7 +258,7 @@ export class FusionScene extends Phaser.Scene {
.setInteractive({ useHandCursor: true }) .setInteractive({ useHandCursor: true })
.setVisible(false); .setVisible(false);
this._fuseBtnText = this.add.text(1060, 920, 'FUSE', { this._fuseBtnText = this.add.text(1060, 920, 'FUSE', {
fontSize: '26px', color: '#ffd700', fontStyle: 'bold' fontSize: '26px', color: '#ffd700', fontStyle: 'bold', fontFamily: 'Audiowide'
}).setOrigin(0.5).setVisible(false); }).setOrigin(0.5).setVisible(false);
this._fuseBtnBg.on('pointerover', () => { this._fuseBtnBg.on('pointerover', () => {
@ -333,7 +333,7 @@ export class FusionScene extends Phaser.Scene {
if (stacks.length === 0) { if (stacks.length === 0) {
const t = this.add.text(STACKS_LEFT + STACKS_W / 2, STACKS_TOP + 200, const t = this.add.text(STACKS_LEFT + STACKS_W / 2, STACKS_TOP + 200,
'No cards available for fusion.\nCollect more copies or remove\ncards from your deck.', { 'No cards available for fusion.\nCollect more copies or remove\ncards from your deck.', {
fontSize: '20px', color: '#666666', align: 'center', lineSpacing: 6 fontSize: '20px', color: '#666666', align: 'center', lineSpacing: 6, fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
this.stacksContainer.add(t); this.stacksContainer.add(t);
return; return;
@ -399,7 +399,8 @@ export class FusionScene extends Phaser.Scene {
const badgeText = this.add.text(badgeX, badgeY, badgeLabel, { const badgeText = this.add.text(badgeX, badgeY, badgeLabel, {
fontSize: stack.fusible ? '16px' : '13px', fontSize: stack.fusible ? '16px' : '13px',
color: stack.fusible ? '#44ff44' : '#ff6666', color: stack.fusible ? '#44ff44' : '#ff6666',
fontStyle: 'bold' fontStyle: 'bold',
fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
container.add(badgeText); container.add(badgeText);
@ -494,7 +495,7 @@ export class FusionScene extends Phaser.Scene {
if (candidates.length === 0) { if (candidates.length === 0) {
const t = this.add.text(PREVIEW_LEFT + PREVIEW_W / 2, PREVIEW_TOP + 100, const t = this.add.text(PREVIEW_LEFT + PREVIEW_W / 2, PREVIEW_TOP + 100,
'No cards of this rarity in this faction.', { 'No cards of this rarity in this faction.', {
fontSize: '16px', color: '#ff8800' fontSize: '16px', color: '#ff8800', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
this._previewContainer.add(t); this._previewContainer.add(t);
this._previewCards.push(t); this._previewCards.push(t);
@ -703,7 +704,7 @@ export class FusionScene extends Phaser.Scene {
// Card name text // Card name text
const nameText = this.add.text(width / 2, 630, resultCardDef.name, { const nameText = this.add.text(width / 2, 630, resultCardDef.name, {
fontSize: '28px', color: '#ffffff', fontStyle: 'bold', fontSize: '28px', color: '#ffffff', fontStyle: 'bold',
stroke: '#000000', strokeThickness: 3 stroke: '#000000', strokeThickness: 3, fontFamily: 'Audiowide'
}).setOrigin(0.5).setDepth(201).setAlpha(0); }).setOrigin(0.5).setDepth(201).setAlpha(0);
this.tweens.add({ targets: nameText, alpha: 1, duration: 300, delay: 800 }); this.tweens.add({ targets: nameText, alpha: 1, duration: 300, delay: 800 });
@ -711,7 +712,7 @@ export class FusionScene extends Phaser.Scene {
const rarityHex = '#' + glowColor.toString(16).padStart(6, '0'); const rarityHex = '#' + glowColor.toString(16).padStart(6, '0');
const rarityText = this.add.text(width / 2, 665, const rarityText = this.add.text(width / 2, 665,
resultCardDef.rarity.toUpperCase(), { resultCardDef.rarity.toUpperCase(), {
fontSize: '18px', color: rarityHex, fontStyle: 'bold' fontSize: '18px', color: rarityHex, fontStyle: 'bold', fontFamily: 'Audiowide'
}).setOrigin(0.5).setDepth(201).setAlpha(0); }).setOrigin(0.5).setDepth(201).setAlpha(0);
this.tweens.add({ targets: rarityText, alpha: 1, duration: 300, delay: 900 }); this.tweens.add({ targets: rarityText, alpha: 1, duration: 300, delay: 900 });
@ -721,7 +722,7 @@ export class FusionScene extends Phaser.Scene {
.setInteractive({ useHandCursor: true }) .setInteractive({ useHandCursor: true })
.setDepth(201).setAlpha(0); .setDepth(201).setAlpha(0);
const collectText = this.add.text(width / 2, 730, 'COLLECT', { const collectText = this.add.text(width / 2, 730, 'COLLECT', {
fontSize: '24px', color: '#44ff44', fontStyle: 'bold' fontSize: '24px', color: '#44ff44', fontStyle: 'bold', fontFamily: 'Audiowide'
}).setOrigin(0.5).setDepth(201).setAlpha(0); }).setOrigin(0.5).setDepth(201).setAlpha(0);
this.tweens.add({ this.tweens.add({
@ -816,7 +817,7 @@ export class FusionScene extends Phaser.Scene {
this._backBtn = this.add.rectangle(80, 1040, 160, 45, 0x333333) this._backBtn = this.add.rectangle(80, 1040, 160, 45, 0x333333)
.setInteractive({ useHandCursor: true }) .setInteractive({ useHandCursor: true })
.setStrokeStyle(1, 0x888888); .setStrokeStyle(1, 0x888888);
this.add.text(80, 1040, 'Back', { fontSize: '18px', color: '#ffffff' }).setOrigin(0.5); this.add.text(80, 1040, 'Back', { fontSize: '18px', color: '#ffffff', fontFamily: 'Audiowide' }).setOrigin(0.5);
this._backBtn.on('pointerover', () => { this._backBtn.on('pointerover', () => {
this.sound.play('sfx_menu_hover', { volume: 0.5 }); this.sound.play('sfx_menu_hover', { volume: 0.5 });
}); });
@ -832,7 +833,7 @@ export class FusionScene extends Phaser.Scene {
_showMsg(msg, color) { _showMsg(msg, color) {
if (this._msgText) this._msgText.destroy(); if (this._msgText) this._msgText.destroy();
this._msgText = this.add.text(this.scale.width / 2, 990, msg, { this._msgText = this.add.text(this.scale.width / 2, 990, msg, {
fontSize: '22px', color fontSize: '22px', color, fontFamily: 'Audiowide'
}).setOrigin(0.5).setDepth(10); }).setOrigin(0.5).setDepth(10);
this.time.delayedCall(2500, () => { this.time.delayedCall(2500, () => {
if (this._msgText) { this._msgText.destroy(); this._msgText = null; } if (this._msgText) { this._msgText.destroy(); this._msgText = null; }

View File

@ -80,25 +80,26 @@ export class MainMenuScene extends Phaser.Scene {
fontSize: '72px', fontSize: '72px',
color: '#d4af37', color: '#d4af37',
stroke: '#000000', stroke: '#000000',
strokeThickness: 6 strokeThickness: 6,
fontFamily: 'RaiderCrusader'
}).setOrigin(0.5); }).setOrigin(0.5);
this.add.text(width / 2, 190, 'A Collectible Card Game', { this.add.text(width / 2, 190, 'A Collectible Card Game', {
fontSize: '24px', color: '#888888' fontSize: '24px', color: '#888888', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
// Level & Gold display // Level & Gold display
this.add.text(width - 30, 30, `Level: ${save.level || 1}`, { this.add.text(width - 30, 30, `Level: ${save.level || 1}`, {
fontSize: '24px', color: '#88aaff' fontSize: '24px', color: '#88aaff', fontFamily: 'Audiowide'
}).setOrigin(1, 0); }).setOrigin(1, 0);
this.goldText = this.add.text(width - 30, 60, `Gold: ${save.gold}`, { this.goldText = this.add.text(width - 30, 60, `Gold: ${save.gold}`, {
fontSize: '24px', color: '#ffd700' fontSize: '24px', color: '#ffd700', fontFamily: 'Audiowide'
}).setOrigin(1, 0); }).setOrigin(1, 0);
// Version // Version
this.add.text(20, height - 20, 'v1.0', { this.add.text(20, height - 20, 'v1.0', {
fontSize: '14px', color: '#444444' fontSize: '14px', color: '#444444', fontFamily: 'Audiowide'
}).setOrigin(0, 1); }).setOrigin(0, 1);
const buttons = [ const buttons = [
@ -133,7 +134,7 @@ export class MainMenuScene extends Phaser.Scene {
.setStrokeStyle(2, 0x4488ff); .setStrokeStyle(2, 0x4488ff);
const text = this.add.text(x, y, label, { const text = this.add.text(x, y, label, {
fontSize: '28px', color: '#ffffff' fontSize: '28px', color: '#ffffff', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
bg.on('pointerover', () => { this.sound.play('sfx_menu_hover', { volume: 0.5 }); bg.setFillStyle(0x2a5a8c); }); bg.on('pointerover', () => { this.sound.play('sfx_menu_hover', { volume: 0.5 }); bg.setFillStyle(0x2a5a8c); });
@ -182,7 +183,7 @@ export class MainMenuScene extends Phaser.Scene {
.setInteractive({ useHandCursor: true }) .setInteractive({ useHandCursor: true })
.setStrokeStyle(1, 0x336633); .setStrokeStyle(1, 0x336633);
this.add.text(x, 25, '💾 Save Game to Your Drive', { this.add.text(x, 25, '💾 Save Game to Your Drive', {
fontSize: '14px', color: '#669966' fontSize: '14px', color: '#669966', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
saveBg.on('pointerover', () => saveBg.setStrokeStyle(1, 0x55aa55)); saveBg.on('pointerover', () => saveBg.setStrokeStyle(1, 0x55aa55));
@ -210,7 +211,7 @@ export class MainMenuScene extends Phaser.Scene {
.setInteractive({ useHandCursor: true }) .setInteractive({ useHandCursor: true })
.setStrokeStyle(1, 0x334466); .setStrokeStyle(1, 0x334466);
this.add.text(x, 65, '📂 Restore Game from File', { this.add.text(x, 65, '📂 Restore Game from File', {
fontSize: '14px', color: '#6688aa' fontSize: '14px', color: '#6688aa', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
restoreBg.on('pointerover', () => restoreBg.setStrokeStyle(1, 0x5577bb)); restoreBg.on('pointerover', () => restoreBg.setStrokeStyle(1, 0x5577bb));
@ -251,7 +252,7 @@ export class MainMenuScene extends Phaser.Scene {
_showStatusMsg(msg, color) { _showStatusMsg(msg, color) {
if (this._statusMsg) this._statusMsg.destroy(); if (this._statusMsg) this._statusMsg.destroy();
this._statusMsg = this.add.text(145, 95, msg, { this._statusMsg = this.add.text(145, 95, msg, {
fontSize: '13px', color fontSize: '13px', color, fontFamily: 'Audiowide'
}).setOrigin(0.5, 0); }).setOrigin(0.5, 0);
this.time.delayedCall(3000, () => { this.time.delayedCall(3000, () => {
if (this._statusMsg) { this._statusMsg.destroy(); this._statusMsg = null; } if (this._statusMsg) { this._statusMsg.destroy(); this._statusMsg = null; }
@ -266,7 +267,7 @@ export class MainMenuScene extends Phaser.Scene {
.setStrokeStyle(2, 0x448844); .setStrokeStyle(2, 0x448844);
const text = this.add.text(x, y, getLabel(), { const text = this.add.text(x, y, getLabel(), {
fontSize: '20px', color: '#88cc88' fontSize: '20px', color: '#88cc88', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
bg.on('pointerover', () => { this.sound.play('sfx_menu_hover', { volume: 0.5 }); bg.setFillStyle(0x2a3f2a); }); bg.on('pointerover', () => { this.sound.play('sfx_menu_hover', { volume: 0.5 }); bg.setFillStyle(0x2a3f2a); });

View File

@ -12,7 +12,7 @@ export class SkirmishSetupScene extends Phaser.Scene {
this.add.rectangle(width / 2, height / 2, width, height, 0x0d1b2a); this.add.rectangle(width / 2, height / 2, width, height, 0x0d1b2a);
this.add.text(width / 2, 60, 'Skirmish Setup', { this.add.text(width / 2, 60, 'Skirmish Setup', {
fontSize: '42px', color: '#d4af37' fontSize: '42px', color: '#d4af37', fontFamily: 'RaiderCrusader'
}).setOrigin(0.5); }).setOrigin(0.5);
this.selectedLevel = save.level || 1; this.selectedLevel = save.level || 1;
@ -20,11 +20,11 @@ export class SkirmishSetupScene extends Phaser.Scene {
// ── Level selector ──────────────────────────────────────────────── // ── Level selector ────────────────────────────────────────────────
this.add.text(width / 2, 180, 'Card Level', { this.add.text(width / 2, 180, 'Card Level', {
fontSize: '24px', color: '#ffffff' fontSize: '24px', color: '#ffffff', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
this.add.text(width / 2, 215, 'Both player and enemy cards will use this level', { this.add.text(width / 2, 215, 'Both player and enemy cards will use this level', {
fontSize: '14px', color: '#888888' fontSize: '14px', color: '#888888', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
this.levelButtons = []; this.levelButtons = [];
@ -39,7 +39,7 @@ export class SkirmishSetupScene extends Phaser.Scene {
.setStrokeStyle(2, isSelected ? 0x88ccff : (available ? 0x4488ff : 0x555555)); .setStrokeStyle(2, isSelected ? 0x88ccff : (available ? 0x4488ff : 0x555555));
const text = this.add.text(bx, by, `Lv ${lv}`, { const text = this.add.text(bx, by, `Lv ${lv}`, {
fontSize: '20px', color: available ? '#ffffff' : '#555555' fontSize: '20px', color: available ? '#ffffff' : '#555555', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
if (available) { if (available) {
@ -56,11 +56,11 @@ export class SkirmishSetupScene extends Phaser.Scene {
// ── Difficulty selector ─────────────────────────────────────────── // ── Difficulty selector ───────────────────────────────────────────
this.add.text(width / 2, 380, 'Difficulty', { this.add.text(width / 2, 380, 'Difficulty', {
fontSize: '24px', color: '#ffffff' fontSize: '24px', color: '#ffffff', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
this.add.text(width / 2, 415, 'Label only — no stat changes yet', { this.add.text(width / 2, 415, 'Label only — no stat changes yet', {
fontSize: '14px', color: '#888888' fontSize: '14px', color: '#888888', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
const difficulties = ['Easy', 'Medium', 'Hard', 'Legendary']; const difficulties = ['Easy', 'Medium', 'Hard', 'Legendary'];
@ -82,7 +82,7 @@ export class SkirmishSetupScene extends Phaser.Scene {
.setStrokeStyle(2, isSelected ? diffBorderColors[diff] : 0x444444); .setStrokeStyle(2, isSelected ? diffBorderColors[diff] : 0x444444);
const text = this.add.text(bx, by, diff, { const text = this.add.text(bx, by, diff, {
fontSize: '20px', color: isSelected ? '#ffffff' : '#aaaaaa' fontSize: '20px', color: isSelected ? '#ffffff' : '#aaaaaa', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
bg.on('pointerdown', () => { bg.on('pointerdown', () => {
@ -99,7 +99,7 @@ export class SkirmishSetupScene extends Phaser.Scene {
.setInteractive({ useHandCursor: true }) .setInteractive({ useHandCursor: true })
.setStrokeStyle(2, 0x4488ff); .setStrokeStyle(2, 0x4488ff);
this.add.text(width / 2, 620, 'Start Battle', { this.add.text(width / 2, 620, 'Start Battle', {
fontSize: '28px', color: '#ffffff', fontStyle: 'bold' fontSize: '28px', color: '#ffffff', fontStyle: 'bold', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
startBg.on('pointerover', () => startBg.setFillStyle(0x3366aa)); startBg.on('pointerover', () => startBg.setFillStyle(0x3366aa));
@ -150,7 +150,7 @@ export class SkirmishSetupScene extends Phaser.Scene {
_showError(msg) { _showError(msg) {
const { width } = this.scale; const { width } = this.scale;
this.add.text(width / 2, 720, msg, { this.add.text(width / 2, 720, msg, {
fontSize: '20px', color: '#ff4444' fontSize: '20px', color: '#ff4444', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
} }
@ -158,7 +158,7 @@ export class SkirmishSetupScene extends Phaser.Scene {
const bg = this.add.rectangle(80, 45, 160, 50, 0x333333) const bg = this.add.rectangle(80, 45, 160, 50, 0x333333)
.setInteractive({ useHandCursor: true }) .setInteractive({ useHandCursor: true })
.setStrokeStyle(1, 0x888888); .setStrokeStyle(1, 0x888888);
this.add.text(80, 45, 'Back', { fontSize: '18px', color: '#ffffff' }).setOrigin(0.5); this.add.text(80, 45, 'Back', { fontSize: '18px', color: '#ffffff', fontFamily: 'Audiowide' }).setOrigin(0.5);
bg.on('pointerdown', () => { bg.on('pointerdown', () => {
this.sound.play('sfx_menu_select', { volume: 0.7 }); this.sound.play('sfx_menu_select', { volume: 0.7 });
this.scene.start('MainMenuScene'); this.scene.start('MainMenuScene');

View File

@ -35,13 +35,13 @@ export class StoreScene extends Phaser.Scene {
scanlines.fillStyle(0x000000, 0.22); scanlines.fillStyle(0x000000, 0.22);
scanlines.fillRect(0, y, width, 1); scanlines.fillRect(0, y, width, 1);
} }
this.add.text(width / 2, 45, 'Card Store', { fontSize: '42px', color: '#d4af37' }).setOrigin(0.5); this.add.text(width / 2, 45, 'Card Store', { fontSize: '42px', color: '#d4af37', fontFamily: 'RaiderCrusader' }).setOrigin(0.5);
this.add.text(width / 2, 90, 'Buy packs to expand your collection', { this.add.text(width / 2, 90, 'Buy packs to expand your collection', {
fontSize: '20px', color: '#888888' fontSize: '20px', color: '#888888', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
this.goldText = this.add.text(width - 20, 20, `Gold: ${save.gold}`, { this.goldText = this.add.text(width - 20, 20, `Gold: ${save.gold}`, {
fontSize: '24px', color: '#ffd700' fontSize: '24px', color: '#ffd700', fontFamily: 'Audiowide'
}).setOrigin(1, 0); }).setOrigin(1, 0);
const packs = packManager.getAllPacks(); const packs = packManager.getAllPacks();
@ -61,24 +61,24 @@ export class StoreScene extends Phaser.Scene {
// Pack art (procedural) // Pack art (procedural)
this.add.rectangle(x, y - 60, 180, 150, 0x0d2240).setStrokeStyle(1, 0x4488ff); 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 - 60, 'PACK', { fontSize: '38px', color: '#4488ff', fontFamily: 'RaiderCrusader' }).setOrigin(0.5);
this.add.text(x, y + 45, pack.name, { fontSize: '24px', color: '#ffffff' }).setOrigin(0.5); this.add.text(x, y + 45, pack.name, { fontSize: '24px', color: '#ffffff', fontFamily: 'Audiowide' }).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 + 75, `${pack.cardCount} cards per pack`, { fontSize: '18px', color: '#aaaaaa', fontFamily: 'Audiowide' }).setOrigin(0.5);
this.add.text(x, y + 100, `Cost: ${pack.cost} Gold`, { fontSize: '20px', color: '#ffd700' }).setOrigin(0.5); this.add.text(x, y + 100, `Cost: ${pack.cost} Gold`, { fontSize: '20px', color: '#ffd700', fontFamily: 'Audiowide' }).setOrigin(0.5);
// Drop rates display // Drop rates display
const rateLines = Object.entries(pack.dropRates).map(([r, v]) => const rateLines = Object.entries(pack.dropRates).map(([r, v]) =>
`${r.charAt(0).toUpperCase() + r.slice(1)}: ${Math.floor(v * 100)}%` `${r.charAt(0).toUpperCase() + r.slice(1)}: ${Math.floor(v * 100)}%`
).join(' '); ).join(' ');
this.add.text(x, y + 128, rateLines, { this.add.text(x, y + 128, rateLines, {
fontSize: '14px', color: '#888888', wordWrap: { width: 360 }, align: 'center' fontSize: '14px', color: '#888888', wordWrap: { width: 360 }, align: 'center', fontFamily: 'Audiowide'
}).setOrigin(0.5); }).setOrigin(0.5);
const buyBtn = this.add.rectangle(x, y + 170, 240, 55, 0x224422) const buyBtn = this.add.rectangle(x, y + 170, 240, 55, 0x224422)
.setInteractive({ useHandCursor: true }) .setInteractive({ useHandCursor: true })
.setStrokeStyle(2, 0x44aa44); .setStrokeStyle(2, 0x44aa44);
const buyTxt = this.add.text(x, y + 170, 'Buy Pack', { fontSize: '22px', color: '#ffffff' }).setOrigin(0.5); const buyTxt = this.add.text(x, y + 170, 'Buy Pack', { fontSize: '22px', color: '#ffffff', fontFamily: 'Audiowide' }).setOrigin(0.5);
buyBtn.on('pointerover', () => buyBtn.setFillStyle(0x336633)); buyBtn.on('pointerover', () => buyBtn.setFillStyle(0x336633));
buyBtn.on('pointerout', () => buyBtn.setFillStyle(0x224422)); buyBtn.on('pointerout', () => buyBtn.setFillStyle(0x224422));
@ -116,7 +116,7 @@ export class StoreScene extends Phaser.Scene {
// Label // Label
const label = this.add.text(width / 2, 700, 'You received:', { const label = this.add.text(width / 2, 700, 'You received:', {
fontSize: '22px', color: '#ffffff' fontSize: '22px', color: '#ffffff', fontFamily: 'Audiowide'
}).setOrigin(0.5).setAlpha(0); }).setOrigin(0.5).setAlpha(0);
this.revealArea.push(label); this.revealArea.push(label);
this.tweens.add({ targets: label, alpha: 1, duration: 300 }); this.tweens.add({ targets: label, alpha: 1, duration: 300 });
@ -129,21 +129,22 @@ export class StoreScene extends Phaser.Scene {
.setStrokeStyle(3, rarityColors[card.rarity] || 0x888888) .setStrokeStyle(3, rarityColors[card.rarity] || 0x888888)
.setAlpha(0); .setAlpha(0);
const nameT = this.add.text(x, y - 70, card.name, { const nameT = this.add.text(x, y - 70, card.name, {
fontSize: '20px', color: '#ffffff', wordWrap: { width: 260 }, align: 'center' fontSize: '20px', color: '#ffffff', wordWrap: { width: 260 }, align: 'center', fontFamily: 'Audiowide'
}).setOrigin(0.5).setAlpha(0); }).setOrigin(0.5).setAlpha(0);
const rarityT = this.add.text(x, y - 30, card.rarity.toUpperCase(), { const rarityT = this.add.text(x, y - 30, card.rarity.toUpperCase(), {
fontSize: '16px', fontSize: '16px',
color: '#' + (rarityColors[card.rarity] || 0x888888).toString(16).padStart(6, '0') color: '#' + (rarityColors[card.rarity] || 0x888888).toString(16).padStart(6, '0'),
fontFamily: 'Audiowide'
}).setOrigin(0.5).setAlpha(0); }).setOrigin(0.5).setAlpha(0);
const lv1 = card.levels[0]; const lv1 = card.levels[0];
const statsT = this.add.text(x, y + 4, `ATK:${lv1.attack} HP:${lv1.health} ARM:${lv1.armor}`, { const statsT = this.add.text(x, y + 4, `ATK:${lv1.attack} HP:${lv1.health} ARM:${lv1.armor}`, {
fontSize: '16px', color: '#aaaaff' fontSize: '16px', color: '#aaaaff', fontFamily: 'Audiowide'
}).setOrigin(0.5).setAlpha(0); }).setOrigin(0.5).setAlpha(0);
const skillT = this.add.text(x, y + 34, lv1.skills.map(s => s.name).join(', '), { const skillT = this.add.text(x, y + 34, lv1.skills.map(s => s.name).join(', '), {
fontSize: '14px', color: '#ffcc44' fontSize: '14px', color: '#ffcc44', fontFamily: 'Audiowide'
}).setOrigin(0.5).setAlpha(0); }).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]}`, { 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' fontSize: '16px', color: (save.collection[card.id] || 0) === 1 ? '#44ff44' : '#aaaaaa', fontFamily: 'Audiowide'
}).setOrigin(0.5).setAlpha(0); }).setOrigin(0.5).setAlpha(0);
this.revealArea.push(bg, nameT, rarityT, statsT, skillT, newT); this.revealArea.push(bg, nameT, rarityT, statsT, skillT, newT);
@ -158,7 +159,7 @@ export class StoreScene extends Phaser.Scene {
_showMsg(msg, color) { _showMsg(msg, color) {
const { width } = this.scale; const { width } = this.scale;
const t = this.add.text(width / 2, 660, msg, { fontSize: '24px', color }).setOrigin(0.5); const t = this.add.text(width / 2, 660, msg, { fontSize: '24px', color, fontFamily: 'Audiowide' }).setOrigin(0.5);
this.time.delayedCall(2000, () => t.destroy()); this.time.delayedCall(2000, () => t.destroy());
} }
@ -166,7 +167,7 @@ export class StoreScene extends Phaser.Scene {
const bg = this.add.rectangle(80, 1040, 160, 45, 0x333333) const bg = this.add.rectangle(80, 1040, 160, 45, 0x333333)
.setInteractive({ useHandCursor: true }) .setInteractive({ useHandCursor: true })
.setStrokeStyle(1, 0x888888); .setStrokeStyle(1, 0x888888);
this.add.text(80, 1040, 'Back', { fontSize: '18px', color: '#ffffff' }).setOrigin(0.5); this.add.text(80, 1040, 'Back', { fontSize: '18px', color: '#ffffff', fontFamily: 'Audiowide' }).setOrigin(0.5);
bg.on('pointerdown', () => this.scene.start('MainMenuScene')); bg.on('pointerdown', () => this.scene.start('MainMenuScene'));
} }
} }