95 lines
2.4 KiB
TypeScript
95 lines
2.4 KiB
TypeScript
import { type SpriteSpec, SPRITE_SPECS } from ".";
|
|
import { SOUND_SPECS, SoundSpec } from "./sounds";
|
|
|
|
let BASE_URL = import.meta.env.BASE_URL || document.location;
|
|
BASE_URL = BASE_URL.endsWith("/") ? BASE_URL.slice(0, -1) : BASE_URL;
|
|
|
|
export const FONT = new FontFace(
|
|
"scientifica",
|
|
`url(${BASE_URL}/fonts/scientifica.ttf)`
|
|
);
|
|
FONT.load().then((font) => {
|
|
document.fonts.add(font);
|
|
});
|
|
|
|
export const IMAGES = new Map<string, HTMLImageElement>();
|
|
export const SOUNDS = new Map<string, HTMLAudioElement>();
|
|
|
|
export const loadSpritesIntoImageElements = (
|
|
spriteSpecs: Partial<SpriteSpec>[]
|
|
): Promise<void>[] => {
|
|
const spritePromises: Promise<void>[] = [];
|
|
|
|
for (const spriteSpec of spriteSpecs) {
|
|
if (spriteSpec.sheet) {
|
|
const img = new Image();
|
|
img.src = BASE_URL + spriteSpec.sheet;
|
|
IMAGES.set(spriteSpec.sheet, img);
|
|
|
|
spritePromises.push(
|
|
new Promise((resolve) => {
|
|
img.onload = () => resolve();
|
|
})
|
|
);
|
|
}
|
|
|
|
if (spriteSpec.states) {
|
|
spritePromises.push(
|
|
...loadSpritesIntoImageElements(Array.from(spriteSpec.states.values()))
|
|
);
|
|
}
|
|
}
|
|
|
|
return spritePromises;
|
|
};
|
|
|
|
export const loadSoundsIntoAudioElements = (
|
|
soundSpecs: SoundSpec[]
|
|
): Promise<void>[] => {
|
|
const soundPromises: Promise<void>[] = [];
|
|
|
|
for (const soundSpec of soundSpecs) {
|
|
if (soundSpec.url) {
|
|
const promise = fetch(BASE_URL + soundSpec.url)
|
|
.then((response) => response.blob())
|
|
.then((blob) => {
|
|
const audio = new Audio();
|
|
audio.src = URL.createObjectURL(blob);
|
|
audio.volume = soundSpec.volume ?? 1;
|
|
|
|
SOUNDS.set(soundSpec.name, audio);
|
|
return new Promise<void>((resolve, rej) => {
|
|
audio.oncanplaythrough = () => {
|
|
resolve();
|
|
};
|
|
|
|
audio.onerror = (e) => {
|
|
console.error(soundSpec);
|
|
rej(e);
|
|
};
|
|
});
|
|
});
|
|
soundPromises.push(promise);
|
|
}
|
|
|
|
if (soundSpec.states) {
|
|
soundPromises.push(
|
|
...loadSoundsIntoAudioElements(Array.from(soundSpec.states.values()))
|
|
);
|
|
}
|
|
}
|
|
|
|
return soundPromises;
|
|
};
|
|
|
|
export const loadAssets = () =>
|
|
Promise.all([
|
|
...loadSpritesIntoImageElements(
|
|
Array.from(SPRITE_SPECS.keys()).map(
|
|
(key) => SPRITE_SPECS.get(key) as SpriteSpec
|
|
)
|
|
),
|
|
FONT.load(),
|
|
...loadSoundsIntoAudioElements(Array.from(SOUND_SPECS.values())),
|
|
]);
|