diff --git a/assets/audio/fortezza.mp3 b/assets/audio/fortezza.mp3 new file mode 100644 index 0000000..c9bd1e0 Binary files /dev/null and b/assets/audio/fortezza.mp3 differ diff --git a/assets/audio/sera.mp3 b/assets/audio/sera.mp3 new file mode 100644 index 0000000..49239a0 Binary files /dev/null and b/assets/audio/sera.mp3 differ diff --git a/src/engine/music.js b/src/engine/music.js index 5399671..d997a47 100644 --- a/src/engine/music.js +++ b/src/engine/music.js @@ -4,12 +4,15 @@ // Il brano del momento: titolo, fine, oppure quello della scena (o quello comune del gioco). Sotto il cartello // d'apertura nessuno: lì suona la sua musichetta, una volta sola (main.js). -export function trackFor(story, { screen, scene }) { +// Quale brano: quello della scena se ce l'ha; altrimenti, all'aperto, quello della fase del giorno (la sera ha il suo); +// altrimenti quello generale del paese. +export function trackFor(story, { screen, scene, phase }) { const m = story.music ?? {}; if (screen === 'splash') return null; if (screen === 'title' || screen === 'intro') return m.title ?? null; if (screen === 'ending') return m.ending ?? m.game ?? null; - return story.scenes[scene]?.music ?? m.game ?? null; + const sc = story.scenes[scene]; + return sc?.music ?? (sc?.indoor ? null : phase?.music) ?? m.game ?? null; } const FADE = 1.2; diff --git a/src/main.js b/src/main.js index bdc5bdc..ca11b2b 100644 --- a/src/main.js +++ b/src/main.js @@ -547,8 +547,9 @@ function frame(now) { last = now; const screen = !$('title').hidden ? 'title' : !$('splash').hidden ? 'splash' : !$('intro').hidden || !$('rione').hidden ? 'intro' : !$('ending').hidden ? 'ending' : 'game'; document.body.classList.toggle('full', screen === 'title' || screen === 'splash' || screen === 'intro' || !$('credits').hidden); - music.duck = voices.playing ? 0.45 : 1; - music.update(trackFor(story, { screen, scene: game?.state.scene }), dt); + // Mentre si parla la musica si abbassa; quando compaiono gli occhi del Regolo quasi si spegne, per la sorpresa. + music.duck = game?.state.flags.occhi_regolo ? 0.12 : voices.playing ? 0.45 : 1; + music.update(trackFor(story, { screen, scene: game?.state.scene, phase: game?.phase() }), dt); // Un minuto senza toccare niente, a gioco fermo: pausa da sola. if (running && now - idleSince > IDLE_PAUSE && !game.speech && !game.walking && !game.queue.length) openPause(); // A gioco fermo (titolo, pausa, fine) la scena non cambia: un ultimo disegno e poi niente, per la batteria del diff --git a/src/story/story.js b/src/story/story.js index 59da63f..dcc049f 100644 --- a/src/story/story.js +++ b/src/story/story.js @@ -50,7 +50,7 @@ export const story = { phases: [ { id: 'pomeriggio' }, { id: 'tramonto', when: 'indizio_regolo', tint: 'rgba(255, 110, 40, 0.16)' }, - { id: 'sera', when: 'casetta_aperta', tint: 'rgba(24, 28, 90, 0.42)' }, + { id: 'sera', when: 'casetta_aperta', tint: 'rgba(24, 28, 90, 0.42)', music: 'assets/audio/sera.mp3' }, ], // Il taccuino (pulsante «Taccuino», tasto N): le tappe del capitolo in ordine. Una tappa è fatta quando la sua // condizione `done` è vera; la prima non fatta è l'obiettivo di adesso. Solo testo: non si sente a voce. @@ -338,6 +338,7 @@ export const story = { name: 'Sotto le mura della Fortezza', map: [36, 6], background: 'assets/scenes/fortezza-esterno.png', + music: 'assets/audio/fortezza.mp3', // «Sotto i nove bastioni» (Andrea con Suno, 25 ottobre) // Nella fessura, con la torcia: il pulviscolo nel fascio di luce, e gli occhi gialli che sbattono. effects: [ { type: 'dust', when: 'luce_fessura', area: [494, 278, 14, 22], count: 7 }, diff --git a/tests/music.test.mjs b/tests/music.test.mjs index 8cbe043..32e0da1 100644 --- a/tests/music.test.mjs +++ b/tests/music.test.mjs @@ -13,6 +13,11 @@ test('il brano giusto per titolo, fine e scena', () => { assert.equal(trackFor(s, { screen: 'game', scene: 'a' }), 'g.mp3'); assert.equal(trackFor(s, { screen: 'game', scene: 'b' }), 'b.mp3'); assert.equal(trackFor({ scenes: {} }, { screen: 'game', scene: 'x' }), null); + // La sera ha la sua musica all'aperto; la scena col suo brano e gli interni non cambiano. + const sera = { id: 'sera', music: 's.mp3' }; + assert.equal(trackFor({ ...s, scenes: { ...s.scenes, i: { indoor: true } } }, { screen: 'game', scene: 'a', phase: sera }), 's.mp3'); + assert.equal(trackFor(s, { screen: 'game', scene: 'b', phase: sera }), 'b.mp3'); + assert.equal(trackFor({ ...s, scenes: { ...s.scenes, i: { indoor: true } } }, { screen: 'game', scene: 'i', phase: sera }), 'g.mp3'); }); test('volume e muto', () => {