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:
parent
4c0e7eb77c
commit
c4e967c72c
Binary file not shown.
Binary file not shown.
28
index.html
28
index.html
|
|
@ -1,17 +1,35 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Tyrant's Edge</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body { background: #1a1a2e; display: flex; justify-content: center; align-items: center; height: 100vh; overflow: hidden; }
|
||||
canvas { display: block; }
|
||||
* {
|
||||
margin: 0;
|
||||
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>
|
||||
</head>
|
||||
|
||||
<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>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
</html>
|
||||
|
|
@ -60,7 +60,7 @@ export class CardObject extends Phaser.GameObjects.Container {
|
|||
this.atkText = this.scene.add.text(
|
||||
-w / 2 + Math.round(5 * scale), topBannerCY,
|
||||
`${this.cardData.currentAttack}`,
|
||||
{ fontSize: fs(9), color: '#ff8877', fontStyle: 'bold' }
|
||||
{ fontSize: fs(9), color: '#ff8877', fontStyle: 'bold', fontFamily: 'Audiowide' }
|
||||
).setOrigin(0, 0.5);
|
||||
this.add(this.atkText);
|
||||
|
||||
|
|
@ -68,7 +68,7 @@ export class CardObject extends Phaser.GameObjects.Container {
|
|||
this.atkLabel = this.scene.add.text(
|
||||
this.atkText.x + this.atkText.width + Math.round(2 * scale), topBannerCY,
|
||||
'ATK',
|
||||
{ fontSize: fs(5.5), color: '#886666' }
|
||||
{ fontSize: fs(5.5), color: '#886666', fontFamily: 'Audiowide' }
|
||||
).setOrigin(0, 0.5);
|
||||
this.add(this.atkLabel);
|
||||
|
||||
|
|
@ -76,7 +76,7 @@ export class CardObject extends Phaser.GameObjects.Container {
|
|||
this.armText = this.scene.add.text(
|
||||
w / 2 - Math.round(5 * scale), topBannerCY,
|
||||
`${this.cardData.currentArmor}`,
|
||||
{ fontSize: fs(9), color: '#88aaff', fontStyle: 'bold' }
|
||||
{ fontSize: fs(9), color: '#88aaff', fontStyle: 'bold', fontFamily: 'Audiowide' }
|
||||
).setOrigin(1, 0.5);
|
||||
this.add(this.armText);
|
||||
|
||||
|
|
@ -84,7 +84,7 @@ export class CardObject extends Phaser.GameObjects.Container {
|
|||
this.armLabel = this.scene.add.text(
|
||||
this.armText.x - this.armText.width - Math.round(2 * scale), topBannerCY,
|
||||
'ARM',
|
||||
{ fontSize: fs(5.5), color: '#667799' }
|
||||
{ fontSize: fs(5.5), color: '#667799', fontFamily: 'Audiowide' }
|
||||
).setOrigin(1, 0.5);
|
||||
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, {
|
||||
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);
|
||||
this.add(this.nameText);
|
||||
|
||||
|
|
@ -133,7 +133,7 @@ export class CardObject extends Phaser.GameObjects.Container {
|
|||
const skillY = contentTop + contentH * 0.72;
|
||||
this.skillText = this.scene.add.text(0, skillY, skillStr, {
|
||||
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);
|
||||
this.add(this.skillText);
|
||||
}
|
||||
|
|
@ -146,7 +146,7 @@ export class CardObject extends Phaser.GameObjects.Container {
|
|||
this.hpText = this.scene.add.text(
|
||||
-w / 2 + Math.round(5 * scale), bottomBannerCY,
|
||||
`${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);
|
||||
this.add(this.hpText);
|
||||
|
||||
|
|
@ -154,7 +154,7 @@ export class CardObject extends Phaser.GameObjects.Container {
|
|||
this.hpLabel = this.scene.add.text(
|
||||
this.hpText.x + this.hpText.width + Math.round(2 * scale), bottomBannerCY,
|
||||
'HP',
|
||||
{ fontSize: fs(5.5), color: '#337755' }
|
||||
{ fontSize: fs(5.5), color: '#337755', fontFamily: 'Audiowide' }
|
||||
).setOrigin(0, 0.5);
|
||||
this.add(this.hpLabel);
|
||||
|
||||
|
|
@ -162,7 +162,7 @@ export class CardObject extends Phaser.GameObjects.Container {
|
|||
this.dlyText = this.scene.add.text(
|
||||
w / 2 - Math.round(5 * scale), bottomBannerCY,
|
||||
`${this.cardData.currentDelay}`,
|
||||
{ fontSize: fs(9), color: '#aaaaaa', fontStyle: 'bold' }
|
||||
{ fontSize: fs(9), color: '#aaaaaa', fontStyle: 'bold', fontFamily: 'Audiowide' }
|
||||
).setOrigin(1, 0.5);
|
||||
this.add(this.dlyText);
|
||||
|
||||
|
|
@ -170,7 +170,7 @@ export class CardObject extends Phaser.GameObjects.Container {
|
|||
const dlyLabel = this.scene.add.text(
|
||||
w / 2 - Math.round(19 * scale), bottomBannerCY,
|
||||
'DLY',
|
||||
{ fontSize: fs(5.5), color: '#777777' }
|
||||
{ fontSize: fs(5.5), color: '#777777', fontFamily: 'Audiowide' }
|
||||
).setOrigin(1, 0.5);
|
||||
this.add(dlyLabel);
|
||||
|
||||
|
|
@ -183,7 +183,8 @@ export class CardObject extends Phaser.GameObjects.Container {
|
|||
{
|
||||
fontSize: fs(6), color: '#ffffff', fontStyle: 'bold',
|
||||
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);
|
||||
this.add(lvBadge);
|
||||
|
|
@ -251,7 +252,8 @@ export class CardObject extends Phaser.GameObjects.Container {
|
|||
color: '#4488ff',
|
||||
fontStyle: 'bold',
|
||||
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);
|
||||
this.add(lossText);
|
||||
|
|
@ -307,7 +309,8 @@ export class CardObject extends Phaser.GameObjects.Container {
|
|||
color: '#88aaff',
|
||||
fontStyle: 'bold',
|
||||
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);
|
||||
this.add(bonusText);
|
||||
|
|
@ -365,7 +368,8 @@ export class CardObject extends Phaser.GameObjects.Container {
|
|||
color: '#ffaa00',
|
||||
fontStyle: 'bold',
|
||||
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);
|
||||
this.add(bonusText);
|
||||
|
|
@ -430,7 +434,8 @@ export class CardObject extends Phaser.GameObjects.Container {
|
|||
color: '#ff4444',
|
||||
fontStyle: 'bold',
|
||||
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);
|
||||
this.add(lossText);
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ export class CardTooltip extends Phaser.GameObjects.Container {
|
|||
// Card name
|
||||
lines.push({
|
||||
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'
|
||||
});
|
||||
|
||||
|
|
@ -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)}`;
|
||||
lines.push({
|
||||
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'
|
||||
});
|
||||
|
||||
|
|
@ -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}`;
|
||||
lines.push({
|
||||
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'
|
||||
});
|
||||
|
||||
|
|
@ -80,9 +80,9 @@ export class CardTooltip extends Phaser.GameObjects.Container {
|
|||
const valStr = skill.value != null ? ` ${skill.value}` : '';
|
||||
lines.push({
|
||||
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',
|
||||
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
|
||||
|
|
@ -94,7 +94,7 @@ export class CardTooltip extends Phaser.GameObjects.Container {
|
|||
: rawDesc;
|
||||
lines.push({
|
||||
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'
|
||||
});
|
||||
}
|
||||
|
|
@ -106,7 +106,7 @@ export class CardTooltip extends Phaser.GameObjects.Container {
|
|||
lines.push({ divider: true, marginTop: 14 });
|
||||
lines.push({
|
||||
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'
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ export class HealthBar {
|
|||
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.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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -129,8 +129,8 @@ export class BattleScene extends Phaser.Scene {
|
|||
this.add.rectangle(280, height / 2, 1, height, 0x222244);
|
||||
|
||||
// Side labels
|
||||
this.add.text(14, 95, 'OPPONENT', { fontSize: '17px', color: '#ff8888' });
|
||||
this.add.text(14, 520, 'PLAYER', { fontSize: '17px', color: '#88aaff' });
|
||||
this.add.text(14, 95, 'OPPONENT', { fontSize: '17px', color: '#ff8888', fontFamily: 'Audiowide' });
|
||||
this.add.text(14, 520, 'PLAYER', { fontSize: '17px', color: '#88aaff', fontFamily: 'Audiowide' });
|
||||
|
||||
this.battlefield = new BattleField(this, {
|
||||
playerY: 715, opponentY: 305,
|
||||
|
|
@ -161,7 +161,7 @@ export class BattleScene extends Phaser.Scene {
|
|||
|
||||
if (!this.playerDeckData) {
|
||||
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);
|
||||
this._makeBackButton();
|
||||
return;
|
||||
|
|
@ -175,23 +175,23 @@ export class BattleScene extends Phaser.Scene {
|
|||
|
||||
// ── Top bar ──────────────────────────────────────────────────────────────
|
||||
this.turnText = this.add.text(960, 30, 'Turn 0', {
|
||||
fontSize: '20px', color: '#ffffff'
|
||||
fontSize: '20px', color: '#ffffff', fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5);
|
||||
|
||||
const battleLabel = this.missionData ? this.missionData.name : 'Skirmish Battle';
|
||||
this.add.text(960, 58, battleLabel, {
|
||||
fontSize: '14px', color: '#888888'
|
||||
fontSize: '14px', color: '#888888', fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5);
|
||||
|
||||
// ── Combat log — bottom strip ────────────────────────────────────────────
|
||||
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);
|
||||
|
||||
this.logLines = [];
|
||||
for (let i = 0; i < 6; i++) {
|
||||
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 })
|
||||
.setStrokeStyle(1, 0x44aa44);
|
||||
this.autoBtnText = this.add.text(1680, 35, 'Auto: OFF', {
|
||||
fontSize: '18px', color: '#ffffff'
|
||||
fontSize: '18px', color: '#ffffff', fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5);
|
||||
autoBtn.on('pointerdown', () => this._toggleAuto());
|
||||
|
||||
|
|
@ -215,7 +215,7 @@ export class BattleScene extends Phaser.Scene {
|
|||
.setInteractive({ useHandCursor: true })
|
||||
.setStrokeStyle(1, 0x4488ff);
|
||||
this.add.text(1840, 35, 'Next Turn', {
|
||||
fontSize: '18px', color: '#ffffff'
|
||||
fontSize: '18px', color: '#ffffff', fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5);
|
||||
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)
|
||||
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
|
||||
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.oDeckText = this.add.text(14, 115, '', { fontSize: '15px', color: '#aaaaaa' });
|
||||
this.pDeckText = this.add.text(14, 540, '', { 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', fontFamily: 'Audiowide' });
|
||||
}
|
||||
|
||||
_beginTurn() {
|
||||
|
|
@ -1481,7 +1481,7 @@ export class BattleScene extends Phaser.Scene {
|
|||
const dmgText = this.add.text(
|
||||
dmgAnchorX, dmgAnchorY - 100,
|
||||
`-${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);
|
||||
|
||||
this.tweens.add({
|
||||
|
|
@ -2463,7 +2463,8 @@ export class BattleScene extends Phaser.Scene {
|
|||
color: '#ff8877',
|
||||
fontStyle: 'bold',
|
||||
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);
|
||||
|
||||
|
|
@ -2664,7 +2665,8 @@ export class BattleScene extends Phaser.Scene {
|
|||
fontStyle: 'bold',
|
||||
stroke: '#000000',
|
||||
strokeThickness: 3,
|
||||
align: 'center'
|
||||
align: 'center',
|
||||
fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5, 0.5).setDepth(55);
|
||||
|
||||
this.tweens.add({
|
||||
|
|
@ -2750,7 +2752,7 @@ export class BattleScene extends Phaser.Scene {
|
|||
this.pickerObjects.push(panel);
|
||||
|
||||
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);
|
||||
this.pickerObjects.push(title);
|
||||
|
||||
|
|
@ -2792,7 +2794,7 @@ export class BattleScene extends Phaser.Scene {
|
|||
.setInteractive({ useHandCursor: true })
|
||||
.setDepth(11);
|
||||
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);
|
||||
passBtn.on('pointerdown', () => {
|
||||
this._destroyCardPicker();
|
||||
|
|
@ -2908,11 +2910,11 @@ export class BattleScene extends Phaser.Scene {
|
|||
|
||||
this.add.text(width / 2, height / 2 - 120, won ? 'VICTORY!' : 'DEFEAT', {
|
||||
fontSize: '72px', color: won ? '#44ff44' : '#ff4444',
|
||||
stroke: '#000000', strokeThickness: 6
|
||||
stroke: '#000000', strokeThickness: 6, fontFamily: 'RaiderCrusader'
|
||||
}).setOrigin(0.5);
|
||||
|
||||
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);
|
||||
|
||||
if (won && this.missionData) {
|
||||
|
|
@ -2938,7 +2940,7 @@ export class BattleScene extends Phaser.Scene {
|
|||
this.registry.set('save', save);
|
||||
|
||||
this.add.text(width / 2, height / 2 + 20, `+${rewards.gold} Gold`, {
|
||||
fontSize: '36px', color: '#ffd700'
|
||||
fontSize: '36px', color: '#ffd700', fontFamily: 'RaiderCrusader'
|
||||
}).setOrigin(0.5);
|
||||
|
||||
if (rewards.cards && rewards.cards.length > 0) {
|
||||
|
|
@ -2948,7 +2950,7 @@ export class BattleScene extends Phaser.Scene {
|
|||
return c ? c.name : id;
|
||||
}).join(', ');
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
@ -2957,12 +2959,12 @@ export class BattleScene extends Phaser.Scene {
|
|||
const cmdCard = cardManager.getCard(unlockedCommander);
|
||||
const cmdName = cmdCard ? cmdCard.name : unlockedCommander;
|
||||
this.add.text(width / 2, height / 2 + 110, `Commander unlocked: ${cmdName}!`, {
|
||||
fontSize: '22px', color: '#ffdd44'
|
||||
fontSize: '22px', color: '#ffdd44', fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5);
|
||||
}
|
||||
} else if (!won) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
@ -2970,7 +2972,7 @@ export class BattleScene extends Phaser.Scene {
|
|||
.setInteractive({ useHandCursor: true })
|
||||
.setStrokeStyle(2, 0x4488ff);
|
||||
this.add.text(width / 2, height / 2 + 160, 'Continue', {
|
||||
fontSize: '28px', color: '#ffffff'
|
||||
fontSize: '28px', color: '#ffffff', fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5);
|
||||
backBtn.on('pointerdown', () => {
|
||||
if (this.missionData) {
|
||||
|
|
@ -3011,7 +3013,7 @@ export class BattleScene extends Phaser.Scene {
|
|||
const bg = this.add.rectangle(80, 35, 180, 44, 0x333333)
|
||||
.setInteractive({ useHandCursor: true })
|
||||
.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', () => {
|
||||
if (this.autoTimer) this.autoTimer.remove();
|
||||
this.scene.start('MainMenuScene');
|
||||
|
|
|
|||
|
|
@ -7,6 +7,10 @@ export class BootScene extends Phaser.Scene {
|
|||
constructor() { super('BootScene'); }
|
||||
|
||||
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
|
||||
this.load.image('vs', 'assets/images/ui/vs.png');
|
||||
this.load.image('attacksFirst', 'assets/images/ui/attacksFirst.png');
|
||||
|
|
@ -51,7 +55,7 @@ export class BootScene extends Phaser.Scene {
|
|||
|
||||
// Loading text
|
||||
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);
|
||||
|
||||
this.load.on('progress', (value) => {
|
||||
|
|
|
|||
|
|
@ -18,12 +18,12 @@ export class CampaignScene extends Phaser.Scene {
|
|||
|
||||
this.add.rectangle(width / 2, height / 2, width, height, 0x0d1b2a);
|
||||
this.add.text(width / 2, 45, campaign ? campaign.name : 'Campaign', {
|
||||
fontSize: '42px', color: '#d4af37'
|
||||
fontSize: '42px', color: '#d4af37', fontFamily: 'RaiderCrusader'
|
||||
}).setOrigin(0.5);
|
||||
|
||||
if (campaign) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
@ -56,32 +56,32 @@ export class CampaignScene extends Phaser.Scene {
|
|||
|
||||
this.add.text(x, y - 70, mission.name, {
|
||||
fontSize: '20px', color: isUnlocked ? '#ffffff' : '#666666',
|
||||
wordWrap: { width: 270 }, align: 'center'
|
||||
wordWrap: { width: 270 }, align: 'center', fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5);
|
||||
|
||||
this.add.text(x, y - 35, `Mission ${i + 1}`, {
|
||||
fontSize: '16px', color: '#888888'
|
||||
fontSize: '16px', color: '#888888', fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5);
|
||||
|
||||
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);
|
||||
|
||||
// Rewards
|
||||
this.add.text(x, y + 30, `+${mission.rewards.gold} gold`, {
|
||||
fontSize: '14px', color: '#ffd700'
|
||||
fontSize: '14px', color: '#ffd700', fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5);
|
||||
|
||||
if (mission.rewards.cards && mission.rewards.cards.length > 0) {
|
||||
this.add.text(x, y + 55, `Card reward available`, {
|
||||
fontSize: '14px', color: '#aaffaa'
|
||||
fontSize: '14px', color: '#aaffaa', fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5);
|
||||
}
|
||||
});
|
||||
|
||||
// Mission lore panel
|
||||
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);
|
||||
|
||||
this._makeBackButton();
|
||||
|
|
@ -91,7 +91,7 @@ export class CampaignScene extends Phaser.Scene {
|
|||
const save = this.registry.get('save');
|
||||
if (!save.decks || save.decks.length === 0) {
|
||||
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);
|
||||
return;
|
||||
}
|
||||
|
|
@ -133,7 +133,7 @@ export class CampaignScene extends Phaser.Scene {
|
|||
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' }).setOrigin(0.5);
|
||||
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('CampaignSelectScene');
|
||||
|
|
|
|||
|
|
@ -13,11 +13,11 @@ export class CampaignSelectScene extends Phaser.Scene {
|
|||
this.add.rectangle(width / 2, height / 2, width, height, 0x0d1b2a);
|
||||
|
||||
this.add.text(width / 2, 45, 'Select Campaign', {
|
||||
fontSize: '42px', color: '#d4af37'
|
||||
fontSize: '42px', color: '#d4af37', fontFamily: 'RaiderCrusader'
|
||||
}).setOrigin(0.5);
|
||||
|
||||
this.add.text(width / 2, 95, `Player Level: ${save.level || 1}`, {
|
||||
fontSize: '20px', color: '#88aaff'
|
||||
fontSize: '20px', color: '#88aaff', fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5);
|
||||
|
||||
const FACTION_COLORS = {
|
||||
|
|
@ -50,25 +50,25 @@ export class CampaignSelectScene extends Phaser.Scene {
|
|||
const nameColor = isUnlocked ? '#ffffff' : '#666666';
|
||||
this.add.text(x, y - 150, campaign.name, {
|
||||
fontSize: '22px', color: nameColor, fontStyle: 'bold',
|
||||
wordWrap: { width: 270 }, align: 'center'
|
||||
wordWrap: { width: 270 }, align: 'center', fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5);
|
||||
|
||||
// Faction label
|
||||
const fColor = FACTION_COLORS[campaign.faction] || '#888888';
|
||||
this.add.text(x, y - 115, campaign.faction.toUpperCase(), {
|
||||
fontSize: '14px', color: fColor
|
||||
fontSize: '14px', color: fColor, fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5);
|
||||
|
||||
// Level requirement
|
||||
this.add.text(x, y - 85, `Level ${campaign.level}`, {
|
||||
fontSize: '16px', color: '#aaaaaa'
|
||||
fontSize: '16px', color: '#aaaaaa', fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5);
|
||||
|
||||
// Progress or lock status
|
||||
if (isUnlocked) {
|
||||
if (campaign.missions.length === 0) {
|
||||
this.add.text(x, y, 'Coming Soon', {
|
||||
fontSize: '18px', color: '#888844'
|
||||
fontSize: '18px', color: '#888844', fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5);
|
||||
} else {
|
||||
const progressStr = isComplete
|
||||
|
|
@ -76,7 +76,7 @@ export class CampaignSelectScene extends Phaser.Scene {
|
|||
: `${completedMissions.length} / ${campaign.missions.length} missions`;
|
||||
const progressColor = isComplete ? '#44ff44' : '#aaffaa';
|
||||
this.add.text(x, y - 20, progressStr, {
|
||||
fontSize: '16px', color: progressColor
|
||||
fontSize: '16px', color: progressColor, fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5);
|
||||
|
||||
// Click to play
|
||||
|
|
@ -89,23 +89,23 @@ export class CampaignSelectScene extends Phaser.Scene {
|
|||
});
|
||||
|
||||
this.add.text(x, y + 30, 'Click to play', {
|
||||
fontSize: '14px', color: '#88aaff'
|
||||
fontSize: '14px', color: '#88aaff', fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5);
|
||||
}
|
||||
|
||||
// Starter reward info
|
||||
if (campaign.starterReward?.cards?.length > 0 && !isComplete) {
|
||||
this.add.text(x, y + 80, 'Completion Reward:', {
|
||||
fontSize: '13px', color: '#ffd700'
|
||||
fontSize: '13px', color: '#ffd700', fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5);
|
||||
this.add.text(x, y + 100, `${campaign.starterReward.cards.length} cards`, {
|
||||
fontSize: '13px', color: '#ffeeaa'
|
||||
fontSize: '13px', color: '#ffeeaa', fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5);
|
||||
}
|
||||
} else {
|
||||
// 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);
|
||||
|
||||
// Unlock requirement
|
||||
|
|
@ -114,7 +114,7 @@ export class CampaignSelectScene extends Phaser.Scene {
|
|||
: `Requires Level ${campaign.requiredLevel}`;
|
||||
this.add.text(x, y + 20, reqText, {
|
||||
fontSize: '13px', color: '#666666',
|
||||
wordWrap: { width: 260 }, align: 'center'
|
||||
wordWrap: { width: 260 }, align: 'center', fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5);
|
||||
}
|
||||
});
|
||||
|
|
@ -126,7 +126,7 @@ export class CampaignSelectScene extends Phaser.Scene {
|
|||
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' }).setOrigin(0.5);
|
||||
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('MainMenuScene');
|
||||
|
|
|
|||
|
|
@ -110,14 +110,14 @@ export class CollectionScene extends Phaser.Scene {
|
|||
|
||||
// Title
|
||||
this.add.text(30, 22, 'COLLECTION', {
|
||||
fontSize: '32px', color: '#d4af37', fontStyle: 'bold'
|
||||
fontSize: '32px', color: '#d4af37', fontStyle: 'bold', fontFamily: 'Audiowide'
|
||||
}).setOrigin(0, 0);
|
||||
|
||||
// Owned count
|
||||
const totalCards = this.cardManager.getAllCards().length;
|
||||
const ownedCards = Object.keys(this.save.collection).length;
|
||||
this.ownedText = this.add.text(320, 30, `Owned: ${ownedCards}/${totalCards}`, {
|
||||
fontSize: '18px', color: '#888888'
|
||||
fontSize: '18px', color: '#888888', fontFamily: 'Audiowide'
|
||||
}).setOrigin(0, 0);
|
||||
|
||||
// Faction filters
|
||||
|
|
@ -157,7 +157,7 @@ export class CollectionScene extends Phaser.Scene {
|
|||
const padX = 14;
|
||||
const h = 24;
|
||||
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;
|
||||
tmpText.destroy();
|
||||
const w = textW + padX * 2;
|
||||
|
|
@ -166,7 +166,7 @@ export class CollectionScene extends Phaser.Scene {
|
|||
.setInteractive({ useHandCursor: true })
|
||||
.setStrokeStyle(1, 0x666688);
|
||||
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);
|
||||
|
||||
bg.on('pointerdown', onClick);
|
||||
|
|
@ -276,7 +276,7 @@ export class CollectionScene extends Phaser.Scene {
|
|||
const emptyText = this.add.text(
|
||||
GRID_PAD_X + GRID_W / 2, GRID_PAD_Y + GRID_H / 2,
|
||||
'No cards match the current filter.',
|
||||
{ fontSize: '22px', color: '#666666' }
|
||||
{ fontSize: '22px', color: '#666666', fontFamily: 'Audiowide' }
|
||||
).setOrigin(0.5);
|
||||
this.gridContainer.add(emptyText);
|
||||
this._gridCards.push(emptyText);
|
||||
|
|
@ -404,11 +404,11 @@ export class CollectionScene extends Phaser.Scene {
|
|||
.setStrokeStyle(1, 0x222244);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
@ -742,7 +742,7 @@ export class CollectionScene extends Phaser.Scene {
|
|||
const bg = this.add.rectangle(80, 1040, 140, 40, 0x333333)
|
||||
.setInteractive({ useHandCursor: true })
|
||||
.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('pointerover', () => bg.setStrokeStyle(2, 0xaaaaaa));
|
||||
bg.on('pointerout', () => bg.setStrokeStyle(1, 0x888888));
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ export class DeckBuilderScene extends Phaser.Scene {
|
|||
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');
|
||||
this.cardManager = this.registry.get('cardManager');
|
||||
|
|
@ -118,7 +118,7 @@ export class DeckBuilderScene extends Phaser.Scene {
|
|||
// ── Commander section ──
|
||||
if (commanders.length > 0) {
|
||||
const cmdLabel = this.add.text(this.GRID_LEFT, cursorY, 'Commanders', {
|
||||
fontSize: '18px', color: '#d4af37'
|
||||
fontSize: '18px', color: '#d4af37', fontFamily: 'Audiowide'
|
||||
});
|
||||
this.scrollContainer.add(cmdLabel);
|
||||
|
||||
|
|
@ -139,7 +139,7 @@ export class DeckBuilderScene extends Phaser.Scene {
|
|||
// ── Assault section ──
|
||||
if (assaults.length > 0) {
|
||||
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);
|
||||
|
||||
|
|
@ -160,7 +160,7 @@ export class DeckBuilderScene extends Phaser.Scene {
|
|||
// Show empty message if all filtered out
|
||||
if (commanders.length === 0 && assaults.length === 0) {
|
||||
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);
|
||||
this.scrollContainer.add(emptyTxt);
|
||||
}
|
||||
|
|
@ -194,7 +194,7 @@ export class DeckBuilderScene extends Phaser.Scene {
|
|||
// Owned/used count
|
||||
const countY = cy + this.CARD_H / 2 + 4;
|
||||
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);
|
||||
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)
|
||||
.setStrokeStyle(1, canAdd ? 0x44aa44 : 0x333333);
|
||||
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);
|
||||
this.scrollContainer.add(btnBg);
|
||||
this.scrollContainer.add(btnTxt);
|
||||
|
|
@ -255,7 +255,7 @@ export class DeckBuilderScene extends Phaser.Scene {
|
|||
this.deckPanelGroup.push(panelBg);
|
||||
|
||||
const title = this.add.text(panelCX, 90, 'Current Deck', {
|
||||
fontSize: '24px', color: '#d4af37'
|
||||
fontSize: '24px', color: '#d4af37', fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5);
|
||||
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)
|
||||
.setStrokeStyle(2, 0xffd700);
|
||||
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);
|
||||
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)
|
||||
.setInteractive({ useHandCursor: true }).setStrokeStyle(1, 0xff4444);
|
||||
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);
|
||||
rmBtn.on('pointerdown', () => {
|
||||
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)
|
||||
.setStrokeStyle(1, rarityColors[card.rarity] || 0x336699);
|
||||
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);
|
||||
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);
|
||||
const lv1 = card.levels[0];
|
||||
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);
|
||||
|
||||
const rmBtn = this.add.rectangle(panelCX + PANEL_W / 2 - 40, y, 34, 28, 0x662222)
|
||||
.setInteractive({ useHandCursor: true }).setStrokeStyle(1, 0xff4444);
|
||||
const rmTxt = this.add.text(panelCX + PANEL_W / 2 - 40, y, '-', {
|
||||
fontSize: '18px', color: '#ff4444'
|
||||
fontSize: '18px', color: '#ff4444', fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5);
|
||||
rmBtn.on('pointerdown', () => {
|
||||
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)
|
||||
.setStrokeStyle(1, 0x222244);
|
||||
const slotTxt = this.add.text(panelCX, y, '— empty slot —', {
|
||||
fontSize: '13px', color: '#333355'
|
||||
fontSize: '13px', color: '#333355', fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5);
|
||||
this.deckPanelGroup.push(slotBg, slotTxt);
|
||||
y += ENTRY_H;
|
||||
|
|
@ -346,14 +346,14 @@ export class DeckBuilderScene extends Phaser.Scene {
|
|||
// Card count
|
||||
const countColor = filled > 10 ? '#ff4444' : filled >= 3 ? '#aaaaff' : '#888888';
|
||||
const totalTxt = this.add.text(panelCX, y + 16, `Cards: ${filled} / 10`, {
|
||||
fontSize: '18px', color: countColor
|
||||
fontSize: '18px', color: countColor, fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5);
|
||||
this.deckPanelGroup.push(totalTxt);
|
||||
|
||||
// Validation
|
||||
const validation = DeckManager.validate(this.workingDeck, this.cardManager);
|
||||
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);
|
||||
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)
|
||||
.setInteractive({ useHandCursor: true }).setStrokeStyle(2, 0x44aa44);
|
||||
const saveTxt = this.add.text(panelCX - 110, saveBtnY, 'Save Deck', {
|
||||
fontSize: '18px', color: '#ffffff'
|
||||
fontSize: '18px', color: '#ffffff', fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5);
|
||||
saveBg.on('pointerdown', () => {
|
||||
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)
|
||||
.setInteractive({ useHandCursor: true }).setStrokeStyle(2, 0xaa4444);
|
||||
const clearTxt = this.add.text(panelCX + 110, saveBtnY, 'Clear Deck', {
|
||||
fontSize: '18px', color: '#ffffff'
|
||||
fontSize: '18px', color: '#ffffff', fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5);
|
||||
clearBg.on('pointerdown', () => {
|
||||
this.workingDeck.commander = null;
|
||||
|
|
@ -419,7 +419,7 @@ export class DeckBuilderScene extends Phaser.Scene {
|
|||
|
||||
// ── Faction header ──
|
||||
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);
|
||||
y += ROW_H;
|
||||
|
|
@ -433,7 +433,7 @@ export class DeckBuilderScene extends Phaser.Scene {
|
|||
|
||||
// ── Rarity header ──
|
||||
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);
|
||||
y += ROW_H;
|
||||
|
|
@ -458,14 +458,14 @@ export class DeckBuilderScene extends Phaser.Scene {
|
|||
let checkmark = null;
|
||||
if (active) {
|
||||
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);
|
||||
this.filterGroup.push(checkmark);
|
||||
}
|
||||
|
||||
// Label text
|
||||
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);
|
||||
|
||||
// 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)
|
||||
.setInteractive({ useHandCursor: true }).setStrokeStyle(1, 0x888888);
|
||||
this.add.text(80, this.scale.height - 40, 'Back', {
|
||||
fontSize: '18px', color: '#ffffff'
|
||||
fontSize: '18px', color: '#ffffff', fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5);
|
||||
backBtn.on('pointerdown', () => this.scene.start('MainMenuScene'));
|
||||
}
|
||||
|
|
@ -500,7 +500,7 @@ export class DeckBuilderScene extends Phaser.Scene {
|
|||
_showMsg(msg, color) {
|
||||
const { width } = this.scale;
|
||||
const t = this.add.text(width / 2, this.scale.height - 100, msg, {
|
||||
fontSize: '18px', color
|
||||
fontSize: '18px', color, fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5);
|
||||
this.time.delayedCall(2000, () => { if (t.scene) t.destroy(); });
|
||||
}
|
||||
|
|
|
|||
|
|
@ -104,10 +104,10 @@ export class FusionScene extends Phaser.Scene {
|
|||
|
||||
_buildHeader() {
|
||||
this.add.text(360, 28, 'FUSION LAB', {
|
||||
fontSize: '36px', color: '#d4af37', fontStyle: 'bold'
|
||||
fontSize: '36px', color: '#d4af37', fontStyle: 'bold', fontFamily: 'RaiderCrusader'
|
||||
}).setOrigin(0.5);
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
@ -115,7 +115,7 @@ export class FusionScene extends Phaser.Scene {
|
|||
|
||||
_buildStacksArea() {
|
||||
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);
|
||||
|
|
@ -148,7 +148,7 @@ export class FusionScene extends Phaser.Scene {
|
|||
|
||||
this._previewTitle = this.add.text(PREVIEW_LEFT + PREVIEW_W / 2, PREVIEW_TOP + 15,
|
||||
'POSSIBLE RESULTS', {
|
||||
fontSize: '18px', color: '#d4af37', fontStyle: 'bold'
|
||||
fontSize: '18px', color: '#d4af37', fontStyle: 'bold', fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5).setVisible(false);
|
||||
|
||||
this._previewContainer = this.add.container(0, 0);
|
||||
|
|
@ -161,12 +161,12 @@ export class FusionScene extends Phaser.Scene {
|
|||
.setStrokeStyle(1, 0x334466);
|
||||
|
||||
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);
|
||||
|
||||
this.add.text(DECK_LEFT + DECK_W / 2, DECK_TOP + 50,
|
||||
'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);
|
||||
|
||||
this._deckContainer = this.add.container(0, 0);
|
||||
|
|
@ -184,7 +184,7 @@ export class FusionScene extends Phaser.Scene {
|
|||
const save = this.save;
|
||||
if (!save.decks || save.decks.length === 0) {
|
||||
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);
|
||||
this._deckContainer.add(t);
|
||||
return;
|
||||
|
|
@ -202,7 +202,7 @@ export class FusionScene extends Phaser.Scene {
|
|||
const entries = Object.entries(counts);
|
||||
if (entries.length === 0) {
|
||||
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);
|
||||
return;
|
||||
}
|
||||
|
|
@ -231,7 +231,7 @@ export class FusionScene extends Phaser.Scene {
|
|||
if (count > 1) {
|
||||
const badge = this.add.text(x + thumbW / 2 - 2, y - thumbH / 2 + 2, `×${count}`, {
|
||||
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);
|
||||
this._deckContainer.add(badge);
|
||||
}
|
||||
|
|
@ -242,14 +242,14 @@ export class FusionScene extends Phaser.Scene {
|
|||
|
||||
_buildBottomBar() {
|
||||
// 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) => {
|
||||
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)
|
||||
this._fuseInfoText = this.add.text(1060, 855, '', {
|
||||
fontSize: '20px', color: '#ffffff'
|
||||
fontSize: '20px', color: '#ffffff', fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5).setVisible(false);
|
||||
|
||||
// Fuse button
|
||||
|
|
@ -258,7 +258,7 @@ export class FusionScene extends Phaser.Scene {
|
|||
.setInteractive({ useHandCursor: true })
|
||||
.setVisible(false);
|
||||
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);
|
||||
|
||||
this._fuseBtnBg.on('pointerover', () => {
|
||||
|
|
@ -333,7 +333,7 @@ export class FusionScene extends Phaser.Scene {
|
|||
if (stacks.length === 0) {
|
||||
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.', {
|
||||
fontSize: '20px', color: '#666666', align: 'center', lineSpacing: 6
|
||||
fontSize: '20px', color: '#666666', align: 'center', lineSpacing: 6, fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5);
|
||||
this.stacksContainer.add(t);
|
||||
return;
|
||||
|
|
@ -399,7 +399,8 @@ export class FusionScene extends Phaser.Scene {
|
|||
const badgeText = this.add.text(badgeX, badgeY, badgeLabel, {
|
||||
fontSize: stack.fusible ? '16px' : '13px',
|
||||
color: stack.fusible ? '#44ff44' : '#ff6666',
|
||||
fontStyle: 'bold'
|
||||
fontStyle: 'bold',
|
||||
fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5);
|
||||
container.add(badgeText);
|
||||
|
||||
|
|
@ -494,7 +495,7 @@ export class FusionScene extends Phaser.Scene {
|
|||
if (candidates.length === 0) {
|
||||
const t = this.add.text(PREVIEW_LEFT + PREVIEW_W / 2, PREVIEW_TOP + 100,
|
||||
'No cards of this rarity in this faction.', {
|
||||
fontSize: '16px', color: '#ff8800'
|
||||
fontSize: '16px', color: '#ff8800', fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5);
|
||||
this._previewContainer.add(t);
|
||||
this._previewCards.push(t);
|
||||
|
|
@ -703,7 +704,7 @@ export class FusionScene extends Phaser.Scene {
|
|||
// Card name text
|
||||
const nameText = this.add.text(width / 2, 630, resultCardDef.name, {
|
||||
fontSize: '28px', color: '#ffffff', fontStyle: 'bold',
|
||||
stroke: '#000000', strokeThickness: 3
|
||||
stroke: '#000000', strokeThickness: 3, fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5).setDepth(201).setAlpha(0);
|
||||
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 rarityText = this.add.text(width / 2, 665,
|
||||
resultCardDef.rarity.toUpperCase(), {
|
||||
fontSize: '18px', color: rarityHex, fontStyle: 'bold'
|
||||
fontSize: '18px', color: rarityHex, fontStyle: 'bold', fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5).setDepth(201).setAlpha(0);
|
||||
this.tweens.add({ targets: rarityText, alpha: 1, duration: 300, delay: 900 });
|
||||
|
||||
|
|
@ -721,7 +722,7 @@ export class FusionScene extends Phaser.Scene {
|
|||
.setInteractive({ useHandCursor: true })
|
||||
.setDepth(201).setAlpha(0);
|
||||
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);
|
||||
|
||||
this.tweens.add({
|
||||
|
|
@ -816,7 +817,7 @@ export class FusionScene extends Phaser.Scene {
|
|||
this._backBtn = 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);
|
||||
this.add.text(80, 1040, 'Back', { fontSize: '18px', color: '#ffffff', fontFamily: 'Audiowide' }).setOrigin(0.5);
|
||||
this._backBtn.on('pointerover', () => {
|
||||
this.sound.play('sfx_menu_hover', { volume: 0.5 });
|
||||
});
|
||||
|
|
@ -832,7 +833,7 @@ export class FusionScene extends Phaser.Scene {
|
|||
_showMsg(msg, color) {
|
||||
if (this._msgText) this._msgText.destroy();
|
||||
this._msgText = this.add.text(this.scale.width / 2, 990, msg, {
|
||||
fontSize: '22px', color
|
||||
fontSize: '22px', color, fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5).setDepth(10);
|
||||
this.time.delayedCall(2500, () => {
|
||||
if (this._msgText) { this._msgText.destroy(); this._msgText = null; }
|
||||
|
|
|
|||
|
|
@ -80,25 +80,26 @@ export class MainMenuScene extends Phaser.Scene {
|
|||
fontSize: '72px',
|
||||
color: '#d4af37',
|
||||
stroke: '#000000',
|
||||
strokeThickness: 6
|
||||
strokeThickness: 6,
|
||||
fontFamily: 'RaiderCrusader'
|
||||
}).setOrigin(0.5);
|
||||
|
||||
this.add.text(width / 2, 190, 'A Collectible Card Game', {
|
||||
fontSize: '24px', color: '#888888'
|
||||
fontSize: '24px', color: '#888888', fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5);
|
||||
|
||||
// Level & Gold display
|
||||
this.add.text(width - 30, 30, `Level: ${save.level || 1}`, {
|
||||
fontSize: '24px', color: '#88aaff'
|
||||
fontSize: '24px', color: '#88aaff', fontFamily: 'Audiowide'
|
||||
}).setOrigin(1, 0);
|
||||
|
||||
this.goldText = this.add.text(width - 30, 60, `Gold: ${save.gold}`, {
|
||||
fontSize: '24px', color: '#ffd700'
|
||||
fontSize: '24px', color: '#ffd700', fontFamily: 'Audiowide'
|
||||
}).setOrigin(1, 0);
|
||||
|
||||
// Version
|
||||
this.add.text(20, height - 20, 'v1.0', {
|
||||
fontSize: '14px', color: '#444444'
|
||||
fontSize: '14px', color: '#444444', fontFamily: 'Audiowide'
|
||||
}).setOrigin(0, 1);
|
||||
|
||||
const buttons = [
|
||||
|
|
@ -133,7 +134,7 @@ export class MainMenuScene extends Phaser.Scene {
|
|||
.setStrokeStyle(2, 0x4488ff);
|
||||
|
||||
const text = this.add.text(x, y, label, {
|
||||
fontSize: '28px', color: '#ffffff'
|
||||
fontSize: '28px', color: '#ffffff', fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5);
|
||||
|
||||
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 })
|
||||
.setStrokeStyle(1, 0x336633);
|
||||
this.add.text(x, 25, '💾 Save Game to Your Drive', {
|
||||
fontSize: '14px', color: '#669966'
|
||||
fontSize: '14px', color: '#669966', fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5);
|
||||
|
||||
saveBg.on('pointerover', () => saveBg.setStrokeStyle(1, 0x55aa55));
|
||||
|
|
@ -210,7 +211,7 @@ export class MainMenuScene extends Phaser.Scene {
|
|||
.setInteractive({ useHandCursor: true })
|
||||
.setStrokeStyle(1, 0x334466);
|
||||
this.add.text(x, 65, '📂 Restore Game from File', {
|
||||
fontSize: '14px', color: '#6688aa'
|
||||
fontSize: '14px', color: '#6688aa', fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5);
|
||||
|
||||
restoreBg.on('pointerover', () => restoreBg.setStrokeStyle(1, 0x5577bb));
|
||||
|
|
@ -251,7 +252,7 @@ export class MainMenuScene extends Phaser.Scene {
|
|||
_showStatusMsg(msg, color) {
|
||||
if (this._statusMsg) this._statusMsg.destroy();
|
||||
this._statusMsg = this.add.text(145, 95, msg, {
|
||||
fontSize: '13px', color
|
||||
fontSize: '13px', color, fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5, 0);
|
||||
this.time.delayedCall(3000, () => {
|
||||
if (this._statusMsg) { this._statusMsg.destroy(); this._statusMsg = null; }
|
||||
|
|
@ -266,7 +267,7 @@ export class MainMenuScene extends Phaser.Scene {
|
|||
.setStrokeStyle(2, 0x448844);
|
||||
|
||||
const text = this.add.text(x, y, getLabel(), {
|
||||
fontSize: '20px', color: '#88cc88'
|
||||
fontSize: '20px', color: '#88cc88', fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5);
|
||||
|
||||
bg.on('pointerover', () => { this.sound.play('sfx_menu_hover', { volume: 0.5 }); bg.setFillStyle(0x2a3f2a); });
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ export class SkirmishSetupScene extends Phaser.Scene {
|
|||
this.add.rectangle(width / 2, height / 2, width, height, 0x0d1b2a);
|
||||
|
||||
this.add.text(width / 2, 60, 'Skirmish Setup', {
|
||||
fontSize: '42px', color: '#d4af37'
|
||||
fontSize: '42px', color: '#d4af37', fontFamily: 'RaiderCrusader'
|
||||
}).setOrigin(0.5);
|
||||
|
||||
this.selectedLevel = save.level || 1;
|
||||
|
|
@ -20,11 +20,11 @@ export class SkirmishSetupScene extends Phaser.Scene {
|
|||
|
||||
// ── Level selector ────────────────────────────────────────────────
|
||||
this.add.text(width / 2, 180, 'Card Level', {
|
||||
fontSize: '24px', color: '#ffffff'
|
||||
fontSize: '24px', color: '#ffffff', fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5);
|
||||
|
||||
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);
|
||||
|
||||
this.levelButtons = [];
|
||||
|
|
@ -39,7 +39,7 @@ export class SkirmishSetupScene extends Phaser.Scene {
|
|||
.setStrokeStyle(2, isSelected ? 0x88ccff : (available ? 0x4488ff : 0x555555));
|
||||
|
||||
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);
|
||||
|
||||
if (available) {
|
||||
|
|
@ -56,11 +56,11 @@ export class SkirmishSetupScene extends Phaser.Scene {
|
|||
|
||||
// ── Difficulty selector ───────────────────────────────────────────
|
||||
this.add.text(width / 2, 380, 'Difficulty', {
|
||||
fontSize: '24px', color: '#ffffff'
|
||||
fontSize: '24px', color: '#ffffff', fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5);
|
||||
|
||||
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);
|
||||
|
||||
const difficulties = ['Easy', 'Medium', 'Hard', 'Legendary'];
|
||||
|
|
@ -82,7 +82,7 @@ export class SkirmishSetupScene extends Phaser.Scene {
|
|||
.setStrokeStyle(2, isSelected ? diffBorderColors[diff] : 0x444444);
|
||||
|
||||
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);
|
||||
|
||||
bg.on('pointerdown', () => {
|
||||
|
|
@ -99,7 +99,7 @@ export class SkirmishSetupScene extends Phaser.Scene {
|
|||
.setInteractive({ useHandCursor: true })
|
||||
.setStrokeStyle(2, 0x4488ff);
|
||||
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);
|
||||
|
||||
startBg.on('pointerover', () => startBg.setFillStyle(0x3366aa));
|
||||
|
|
@ -150,7 +150,7 @@ export class SkirmishSetupScene extends Phaser.Scene {
|
|||
_showError(msg) {
|
||||
const { width } = this.scale;
|
||||
this.add.text(width / 2, 720, msg, {
|
||||
fontSize: '20px', color: '#ff4444'
|
||||
fontSize: '20px', color: '#ff4444', fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5);
|
||||
}
|
||||
|
||||
|
|
@ -158,7 +158,7 @@ export class SkirmishSetupScene extends Phaser.Scene {
|
|||
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' }).setOrigin(0.5);
|
||||
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('MainMenuScene');
|
||||
|
|
|
|||
|
|
@ -35,13 +35,13 @@ export class StoreScene extends Phaser.Scene {
|
|||
scanlines.fillStyle(0x000000, 0.22);
|
||||
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', {
|
||||
fontSize: '20px', color: '#888888'
|
||||
fontSize: '20px', color: '#888888', fontFamily: 'Audiowide'
|
||||
}).setOrigin(0.5);
|
||||
|
||||
this.goldText = this.add.text(width - 20, 20, `Gold: ${save.gold}`, {
|
||||
fontSize: '24px', color: '#ffd700'
|
||||
fontSize: '24px', color: '#ffd700', fontFamily: 'Audiowide'
|
||||
}).setOrigin(1, 0);
|
||||
|
||||
const packs = packManager.getAllPacks();
|
||||
|
|
@ -61,24 +61,24 @@ export class StoreScene extends Phaser.Scene {
|
|||
|
||||
// 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 - 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 + 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);
|
||||
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', fontFamily: 'Audiowide' }).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
|
||||
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'
|
||||
fontSize: '14px', color: '#888888', wordWrap: { width: 360 }, align: 'center', fontFamily: 'Audiowide'
|
||||
}).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);
|
||||
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('pointerout', () => buyBtn.setFillStyle(0x224422));
|
||||
|
|
@ -116,7 +116,7 @@ export class StoreScene extends Phaser.Scene {
|
|||
|
||||
// Label
|
||||
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);
|
||||
this.revealArea.push(label);
|
||||
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)
|
||||
.setAlpha(0);
|
||||
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);
|
||||
const rarityT = this.add.text(x, y - 30, card.rarity.toUpperCase(), {
|
||||
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);
|
||||
const lv1 = card.levels[0];
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
|
||||
this.revealArea.push(bg, nameT, rarityT, statsT, skillT, newT);
|
||||
|
|
@ -158,7 +159,7 @@ export class StoreScene extends Phaser.Scene {
|
|||
|
||||
_showMsg(msg, color) {
|
||||
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());
|
||||
}
|
||||
|
||||
|
|
@ -166,7 +167,7 @@ export class StoreScene extends Phaser.Scene {
|
|||
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);
|
||||
this.add.text(80, 1040, 'Back', { fontSize: '18px', color: '#ffffff', fontFamily: 'Audiowide' }).setOrigin(0.5);
|
||||
bg.on('pointerdown', () => this.scene.start('MainMenuScene'));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue