Files
bworld/client/assets.ts
T
2026-02-24 15:36:10 -03:00

60 lines
1.3 KiB
TypeScript

type Asset = HTMLImageElement | HTMLAudioElement;
export class AssetManager {
static instance = new AssetManager();
assets: Record<string, Asset> = {};
loading_promises: Promise<void>[] = [];
constructor() {}
load(key: string, src: string) {
if (this.assets[key]) {
return;
}
if (src.endsWith(".png")) {
const img = new Image();
const promise = new Promise<void>((resolve, reject) => {
img.onload = () => resolve();
img.onerror = () => reject(new Error(`Failed to load image: ${src}`));
});
img.src = src;
this.assets[key] = img;
this.loading_promises.push(promise);
} else if (src.endsWith(".ogg")) {
const audio = new Audio();
const promise = new Promise<void>((resolve, reject) => {
audio.addEventListener(
"canplaythrough",
() => resolve(),
{ once: true },
);
audio.addEventListener(
"error",
() => reject(new Error(`Failed to load audio: ${src}`)),
{ once: true },
);
});
audio.src = src;
audio.load();
this.assets[key] = audio;
this.loading_promises.push(promise);
}
}
async load_all() {
await Promise.all(this.loading_promises);
this.loading_promises = [];
}
get<T>(key: string): T {
const asset = this.assets[key];
if (!asset) {
throw new Error(`Asset not found: ${key}`);
}
return asset as T;
}
}