- Dalla Pieve a destra il forno e, a sinistra, la stazione; dal portone centrale si entra nella Pieve (foto di Mariano Mirannalti, nei crediti alla voce «Fotografie»). - Via Calimara: in fondo la Piazza, verso chi guarda la farmacia. Rotonda del River: a sinistra il campo sportivo, in basso l'area feste, dietro la farmacia la Pieve, a destra il Comune, in basso a destra Calimara. - Polisportiva: dal ponte prima il campo principale, poi il secondario col padel; dietro, l'area feste. - Andrea ha 27 anni nel 2007: battute, documento e CLAUDE.md corretti. - Mappa su una griglia ordinata, senza etichette sovrapposte. - Doppio clic: Andrea va al doppio della velocità. In pausa la musica sfuma e si ferma; dopo un minuto senza toccare niente il gioco va in pausa da solo. - Crediti: scorre solo l'elenco, dedica e Chiudi sempre in vista. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017egeN2amL84ErjfgQFtEDn
61 lines
3.1 KiB
JavaScript
61 lines
3.1 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { existsSync } from 'node:fs';
|
|
import { trackFor, Music } from '../src/engine/music.js';
|
|
import { story } from '../src/story/story.js';
|
|
|
|
test('il brano giusto per titolo, fine e scena', () => {
|
|
const s = { music: { title: 't.mp3', game: 'g.mp3', ending: 'e.mp3' }, scenes: { a: {}, b: { music: 'b.mp3' } } };
|
|
assert.equal(trackFor(s, { screen: 'splash', scene: 'a' }), null, 'sotto il cartello suona solo la sua musichetta');
|
|
assert.equal(trackFor(s, { screen: 'title', scene: 'a' }), 't.mp3');
|
|
assert.equal(trackFor(s, { screen: 'intro', scene: 'a' }), 't.mp3');
|
|
assert.equal(trackFor(s, { screen: 'ending', scene: 'a' }), 'e.mp3');
|
|
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);
|
|
});
|
|
|
|
test('volume e muto', () => {
|
|
const m = new Music({ volume: 0.5, muted: true });
|
|
assert.equal(m.setVolume(1.4), 1);
|
|
assert.equal(m.muted, false, 'alzare il volume toglie il muto');
|
|
assert.equal(m.toggle(), true);
|
|
assert.equal(m.setVolume(-1), 0);
|
|
assert.deepEqual(m.settings(), { volume: 0, muted: true });
|
|
});
|
|
|
|
test('i brani della storia esistono', () => {
|
|
const files = [...Object.values(story.music ?? {}), ...Object.values(story.scenes).map(s => s.music).filter(Boolean)];
|
|
assert.ok(files.length);
|
|
for (const f of files) assert.ok(existsSync(new URL('../' + f, import.meta.url)), `manca ${f}`);
|
|
});
|
|
|
|
test('mentre parla qualcuno la musica si abbassa, poi risale', () => {
|
|
globalThis.Audio ??= class { constructor(src) { this.src = src; this.volume = 0; this.paused = true; } play() { this.paused = false; return Promise.resolve(); } pause() { this.paused = true; } };
|
|
const m = new Music({ volume: 0.6 });
|
|
for (let i = 0; i < 40; i++) m.update('g.mp3', 0.1);
|
|
assert.equal(m.current.audio.volume, 0.6);
|
|
m.duck = 0.45;
|
|
for (let i = 0; i < 40; i++) m.update('g.mp3', 0.1);
|
|
assert.ok(Math.abs(m.current.audio.volume - 0.27) < 1e-9, 'abbassata sotto la voce');
|
|
m.duck = 1;
|
|
for (let i = 0; i < 40; i++) m.update('g.mp3', 0.1);
|
|
assert.equal(m.current.audio.volume, 0.6);
|
|
});
|
|
|
|
test('in pausa la musica sfuma fino a zero e si ferma', () => {
|
|
const played = [], paused = [];
|
|
globalThis.Audio = class { constructor(src) { this.src = src; this.volume = 0; this.paused = true; }
|
|
play() { this.paused = false; played.push(this.src); return Promise.resolve(); } pause() { this.paused = true; paused.push(this.src); } };
|
|
const m = new Music({ volume: 0.5 });
|
|
for (let i = 0; i < 40; i++) m.update('a.mp3', 0.1);
|
|
assert.equal(m.current.audio.volume, 0.5);
|
|
m.hold = true;
|
|
for (let i = 0; i < 40; i++) m.update('a.mp3', 0.1);
|
|
assert.ok(m.current.audio.paused && m.current.audio.volume === 0, 'ferma a volume zero');
|
|
m.hold = false;
|
|
m.update('a.mp3', 0.1);
|
|
assert.ok(!m.current.audio.paused && played.length === 2, 'riprende lo stesso brano');
|
|
delete globalThis.Audio;
|
|
});
|