diff --git a/package.json b/package.json index 2f7da23..b27813d 100644 --- a/package.json +++ b/package.json @@ -9,9 +9,13 @@ "check": "tsc --noEmit --project . && prettier --check ." }, "devDependencies": { + "@types/howler": "^2.2.2", "@vitejs/plugin-legacy": "^1.4.3", "prettier": "2.3.2", "typescript": "^4.3.4", "vite": "^2.3.8" + }, + "dependencies": { + "howler": "^2.2.3" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a2b9f7e..b8487b8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,12 +1,18 @@ lockfileVersion: 5.3 specifiers: + '@types/howler': ^2.2.2 '@vitejs/plugin-legacy': ^1.4.3 + howler: ^2.2.3 prettier: 2.3.2 typescript: ^4.3.4 vite: ^2.3.8 +dependencies: + howler: 2.2.3 + devDependencies: + '@types/howler': 2.2.2 '@vitejs/plugin-legacy': 1.4.3_vite@2.3.8 prettier: 2.3.2 typescript: 4.3.4 @@ -19,6 +25,10 @@ packages: engines: {node: '>=6.9.0'} dev: true + /@types/howler/2.2.2: + resolution: {integrity: sha512-/znab/CjipQ25epk7YcsoEsR96rB77Y/fCLMaNtIzV5oPeUeilc7dYGyMjYi+OQklkllADLM+jGZRSt3d6lhiA==} + dev: true + /@vitejs/plugin-legacy/1.4.3_vite@2.3.8: resolution: {integrity: sha512-lxZUJaMWYMQuqvZM1wPzDP6KABQgA/drVL5fnaygEPcz9adc2OHhfFNN/SvvHQ1V0rP8gybIc7uA+iI1gAdkVQ==} engines: {node: '>=12.0.0'} @@ -66,6 +76,10 @@ packages: function-bind: 1.1.1 dev: true + /howler/2.2.3: + resolution: {integrity: sha512-QM0FFkw0LRX1PR8pNzJVAY25JhIWvbKMBFM4gqk+QdV+kPXOhleWGCB6AiAF/goGjIHK2e/nIElplvjQwhr0jg==} + dev: false + /is-core-module/2.4.0: resolution: {integrity: sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==} dependencies: diff --git a/src/assets.ts b/src/assets.ts index c5e4962..3d17332 100644 --- a/src/assets.ts +++ b/src/assets.ts @@ -1,3 +1,5 @@ +import { Howl } from "howler"; + import botonComenzar from "./assets/Comenzar.png"; import botonSiguiente from "./assets/Siguiente.png"; import botonCompartirPerdiste from "./assets/Comparti_2.png"; @@ -39,13 +41,16 @@ function loadImage(url: string): Promise { img.src = url; }); } -function loadAudio(url: string): Promise { +function loadAudio(url: string): Promise { return new Promise((resolve, reject) => { - let audio = new Audio(); - audio.oncanplaythrough = () => resolve(audio); - audio.onerror = (e) => reject(e); - audio.src = url; - audio.load(); + const sound = new Howl({ + src: [url], + loop: true, + }); + + sound.once("load", () => resolve(sound)); + sound.once("loaderror", (e) => reject(e)); + sound.load(); }); } @@ -89,7 +94,7 @@ export const audioAssetUrls = { export type Assets = { [key in keyof typeof imageAssetUrls]: HTMLImageElement; } & - { [key in keyof typeof audioAssetUrls]: HTMLAudioElement }; + { [key in keyof typeof audioAssetUrls]: Howl }; const imageAssets = Object.fromEntries( Object.entries(imageAssetUrls).map(([name, url]) => [name, loadImage(url)]) diff --git a/src/jugando.ts b/src/jugando.ts index 081b8e9..bdbc4f8 100644 --- a/src/jugando.ts +++ b/src/jugando.ts @@ -27,6 +27,7 @@ type Citizen = { x: number; sprite: Sprite }; export type State = { current: "jugando"; has: "lost" | "won" | null; + playing: boolean; pos: { x: number }; view: { x: number }; side: "left" | "right"; @@ -55,6 +56,7 @@ export function createJugandoState(juego: Juego): State { return { current: "jugando", has: null, + playing: false, pos: { x: MAP_MIN + 100 }, view: { x: 0 }, side: "right", @@ -131,7 +133,10 @@ export function update(juego: Juego, dt: number) { return; } - juego.assets.fondo.play(); + if (!juego.state.playing) { + juego.assets.fondo.play(); + juego.state.playing = true; + } juego.state.time -= dt; if (juego.state.time < 0) {