66 lines
2.7 KiB
JavaScript
66 lines
2.7 KiB
JavaScript
import { resolveGameAssets } from '../data/assetManifest.js';
|
|
|
|
// Lazy per-game asset loading. PreloadScene only loads shared assets at
|
|
// startup; each game's own art (see data/assetManifest.js) is loaded here,
|
|
// from GameRoomScene, the first time the user enters that game.
|
|
|
|
function isLoaded(scene, d) {
|
|
if (d.type === 'audio') return scene.cache.audio.exists(d.key);
|
|
if (d.type === 'json') return scene.cache.json.exists(d.key);
|
|
// Video lives in its own cache, not the texture manager.
|
|
if (d.type === 'video') return !!scene.cache.video?.exists(d.key);
|
|
return scene.textures.exists(d.key);
|
|
}
|
|
|
|
export function missingGameAssets(scene, slug) {
|
|
return resolveGameAssets(scene, slug).filter((d) => !isLoaded(scene, d));
|
|
}
|
|
|
|
function queueDescriptor(scene, d) {
|
|
if (d.type === 'spritesheet') {
|
|
scene.load.spritesheet(d.key, d.path, { frameWidth: d.frameWidth, frameHeight: d.frameHeight });
|
|
} else if (d.type === 'audio') {
|
|
scene.load.audio(d.key, d.path);
|
|
} else if (d.type === 'json') {
|
|
scene.load.json(d.key, d.path);
|
|
} else if (d.type === 'video') {
|
|
// noAudio: true — these are ambient portrait loops. It also lets them
|
|
// autoplay, which browsers refuse for anything with an audio track.
|
|
scene.load.video(d.key, d.path, true);
|
|
} else {
|
|
scene.load.image(d.key, d.path);
|
|
}
|
|
}
|
|
|
|
// Queue every missing asset for `slug` on the scene's loader without waiting
|
|
// for the load to finish. For use from a Scene's own preload() — a level
|
|
// editor booting straight out of PreloadScene, say — where Phaser starts the
|
|
// queued load automatically once preload() returns, so there's no need for
|
|
// the completion Promise below.
|
|
export function queueGameAssets(scene, slug) {
|
|
missingGameAssets(scene, slug).forEach((d) => queueDescriptor(scene, d));
|
|
}
|
|
|
|
// Queue and load every missing asset for `slug` on the scene's loader. Call
|
|
// from create() only (the loader is idle there). Resolves once the load pass
|
|
// completes; a failed file logs a warning and the game's usual
|
|
// textures.exists fallback applies.
|
|
export function ensureGameAssets(scene, slug, { onProgress } = {}) {
|
|
const missing = missingGameAssets(scene, slug);
|
|
if (missing.length === 0) return Promise.resolve(false);
|
|
|
|
for (const d of missing) queueDescriptor(scene, d);
|
|
|
|
return new Promise((resolve) => {
|
|
const onError = (file) => console.warn(`[assets] failed to load ${file.key} (${file.src})`);
|
|
if (onProgress) scene.load.on('progress', onProgress);
|
|
scene.load.on('loaderror', onError);
|
|
scene.load.once('complete', () => {
|
|
if (onProgress) scene.load.off('progress', onProgress);
|
|
scene.load.off('loaderror', onError);
|
|
resolve(true);
|
|
});
|
|
scene.load.start();
|
|
});
|
|
}
|