120 lines
6.1 KiB
JavaScript
120 lines
6.1 KiB
JavaScript
import * as Phaser from 'phaser';
|
||
import { GAME_HEIGHT, GAME_WIDTH, COLORS } from '../config.js';
|
||
import { auth } from '../services/auth.js';
|
||
|
||
export default class PreloadScene extends Phaser.Scene {
|
||
constructor() { super('Preload'); }
|
||
|
||
preload() {
|
||
const w = GAME_WIDTH;
|
||
const h = GAME_HEIGHT;
|
||
const barWidth = 600;
|
||
const bg = this.add.rectangle(w / 2, h / 2, barWidth + 8, 28, COLORS.panel)
|
||
.setStrokeStyle(2, COLORS.accent);
|
||
const bar = this.add.rectangle(w / 2 - barWidth / 2, h / 2, 0, 20, COLORS.accent)
|
||
.setOrigin(0, 0.5);
|
||
this.add.text(w / 2, h / 2 - 60, 'Loading…', {
|
||
fontFamily: '"Julius Sans One"',
|
||
fontSize: '32px',
|
||
color: COLORS.textHex,
|
||
}).setOrigin(0.5);
|
||
|
||
this.load.on('progress', (p) => bar.width = barWidth * p);
|
||
this.load.on('complete', () => { bg.destroy(); bar.destroy(); });
|
||
|
||
this.load.spritesheet('opponents', '/assets/images/opponents.png', {
|
||
frameWidth: 300,
|
||
frameHeight: 300,
|
||
});
|
||
this.load.spritesheet('cardbacks', '/assets/images/cardbacks.png', {
|
||
frameWidth: 320,
|
||
frameHeight: 420,
|
||
});
|
||
this.load.spritesheet('catan-cards', '/assets/images/catancards.png', {
|
||
frameWidth: 270,
|
||
frameHeight: 390,
|
||
});
|
||
this.load.spritesheet('catan-tiles', '/assets/images/catantiles.png', {
|
||
frameWidth: 312,
|
||
frameHeight: 312,
|
||
});
|
||
this.load.image('catan-robber', '/assets/images/catan-robber.png');
|
||
this.load.image('catan-pirate', '/assets/images/catan-pirate.png');
|
||
this.load.image('bg-menu', '/assets/images/background-menu.png');
|
||
this.load.image('bg-room', '/assets/images/background-room.png');
|
||
this.load.image('bg-casino', '/assets/images/background-casino.png');
|
||
this.load.image('main-title', '/assets/images/main-title.png');
|
||
this.load.json('playfields', '/data/playfields.json');
|
||
this.load.json('card-backs', '/data/card-backs.json');
|
||
this.load.json('music', '/data/music.json');
|
||
|
||
this.load.audio('sfx-card-deal', '/assets/fx/card-deal.mp3');
|
||
this.load.audio('sfx-card-place', '/assets/fx/card-place.mp3');
|
||
this.load.audio('sfx-card-show', '/assets/fx/card-show.mp3');
|
||
this.load.audio('sfx-card-shuffle', '/assets/fx/card-shuffle.mp3');
|
||
this.load.audio('sfx-coins', '/assets/fx/coins.mp3');
|
||
this.load.audio('sfx-purchase', '/assets/fx/purchase.mp3');
|
||
this.load.audio('sfx-casino-blackjack', '/assets/fx/casino-blackjack.mp3');
|
||
this.load.audio('sfx-casino-lose', '/assets/fx/casino-lose.mp3');
|
||
this.load.audio('sfx-casino-win', '/assets/fx/casino-win.mp3');
|
||
this.load.audio('sfx-chip-bet', '/assets/fx/chip-bet.mp3');
|
||
this.load.audio('sfx-dice-roll', '/assets/fx/dice-roll.mp3');
|
||
this.load.audio('sfx-bingo-balls', '/assets/fx/bingo-balls.mp3');
|
||
this.load.audio('sfx-pencil-write', '/assets/fx/pencil-write.mp3');
|
||
this.load.audio('sfx-piece-click', '/assets/fx/piece-click.mp3');
|
||
this.load.audio('sfx-mastermind-glitch-1', '/assets/fx/mastermind-glitch-01.mp3');
|
||
this.load.audio('sfx-mastermind-glitch-2', '/assets/fx/mastermind-glitch-02.mp3');
|
||
this.load.audio('sfx-mastermind-place', '/assets/fx/mastermind-place.mp3');
|
||
this.load.audio('sfx-mastermind-access-granted', '/assets/fx/mastermind-access-granted.mp3');
|
||
this.load.audio('sfx-mastermind-access-denied', '/assets/fx/mastermind-access-denied.mp3');
|
||
this.load.audio('sfx-mastermind-color', '/assets/fx/mastermind-color.mp3');
|
||
this.load.audio('sfx-mastermind-match', '/assets/fx/mastermind-match.mp3');
|
||
this.load.audio('sfx-mastermind-calculate', '/assets/fx/mastermind-calculate.mp3');
|
||
this.load.audio('sfx-roulette', '/assets/fx/roulette.mp3');
|
||
this.load.audio('sfx-battleship-hit', '/assets/fx/battleship-hit.mp3');
|
||
this.load.audio('sfx-battleship-miss', '/assets/fx/battleship-miss.mp3');
|
||
this.load.audio('sfx-battleship-launch', '/assets/fx/battleship-launch.mp3');
|
||
|
||
this.load.spritesheet('catan-special-cards', '/assets/images/catan-special-cards.png', { frameWidth: 270, frameHeight: 390 });
|
||
|
||
// Dominion card art. One 270×390 cell per card (art fills the top ~60%;
|
||
// the title/icon band is drawn at runtime). Optional — the scene falls back
|
||
// to procedural placeholders when the sheet is absent.
|
||
this.load.spritesheet('dominion-cards', '/assets/images/dominioncards.png', { frameWidth: 270, frameHeight: 390 });
|
||
// Prosperity expansion art (frame order documented in expansions/prosperity.js).
|
||
// Optional — same procedural fallback applies when the sheet is absent.
|
||
this.load.spritesheet('dominion-prosperity', '/assets/images/dominion-prosperity.png', { frameWidth: 270, frameHeight: 390 });
|
||
// Prosperity token sprites (1 VP, 5 VP, Gold) — 150×150 each.
|
||
this.load.spritesheet('dominion-tokens', '/assets/images/dominion-tokens.png', { frameWidth: 150, frameHeight: 150 });
|
||
this.load.spritesheet('ttr-cards', '/assets/images/tickettoride-cards.png', { frameWidth: 270, frameHeight: 390 });
|
||
this.load.spritesheet('gofish-cards', '/assets/images/gofish-cards.png', { frameWidth: 270, frameHeight: 390 });
|
||
this.load.spritesheet('tab-icons', '/assets/images/tab-icons.png', { frameWidth: 128, frameHeight: 128 });
|
||
}
|
||
|
||
async create() {
|
||
// Collect all image assets that need loading from JSON configs
|
||
const pfd = this.cache.json.get('playfields');
|
||
const cbd = this.cache.json.get('card-backs');
|
||
|
||
const toLoad = [
|
||
...(pfd?.playfields ?? []).filter((pf) => pf.path && !this.textures.exists(pf.key)),
|
||
...(cbd?.cardBacks ?? []).filter((cb) => cb.path && !this.textures.exists(cb.key)),
|
||
];
|
||
|
||
if (toLoad.length > 0) {
|
||
for (const asset of toLoad) this.load.image(asset.key, asset.path);
|
||
await new Promise((resolve) => {
|
||
this.load.once('complete', resolve);
|
||
this.load.start();
|
||
});
|
||
}
|
||
|
||
// Warm the handwritten Scrabble notepad font so its first paint isn't a
|
||
// fallback face. Best effort — never block startup on it.
|
||
try { await Promise.race([document.fonts.load('48px YummyCupcakes'), new Promise(r => setTimeout(r, 1500))]); } catch { /* ignore */ }
|
||
|
||
await auth.refresh();
|
||
this.scene.start('Landing');
|
||
}
|
||
}
|