Il Regolo del futuro con la musica di Andrea (flipper-futuro.mp3, la musica cambia con la tavola: tableMusic) al posto del battito sintetico
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GiECd9RWGMKV7n3K1mdy8T
This commit is contained in:
@@ -109,7 +109,7 @@ export function futureLayout() {
|
||||
}
|
||||
function openFuture(c) {
|
||||
Object.assign(c, futureLayout()); c.table = 'future'; c.resets = {}; c.fx = [];
|
||||
c.future = { hits: { orbita: 0, ponte: 0, spira: 0 }, beatAt: c.sim };
|
||||
c.future = { hits: { orbita: 0, ponte: 0, spira: 0 } };
|
||||
// La trasformazione parcheggia le tre palline al sicuro, poi le serve una alla volta.
|
||||
activeBalls(c).forEach((b, i) => Object.assign(b, { x: i === 1 ? 411 : 229, y: 220 - i * 32, vx: 0, vy: 160,
|
||||
ramp: null, contacts: [], trail: [], releaseAt: c.transform.until + i * 0.55, releasedFrom: i === 1 ? 'spira' : 'orbita' }));
|
||||
@@ -243,7 +243,6 @@ function step(c) {
|
||||
}
|
||||
if (c.table === 'future') {
|
||||
c.regolo.x = 320 + Math.sin(c.sim * 1.6) * 24;
|
||||
if (c.sim >= c.future.beatAt) { c.future.beatAt = c.sim + 0.5; c.events.push({ kind: `flipper-futuro-beat-${Math.floor(c.sim * 2) % 4}`, power: 0.4 }); }
|
||||
}
|
||||
for (const r of c.ramps) r.lit = Math.max(0, r.lit - STEP);
|
||||
if (c.lastRamp && c.sim - c.lastRamp.at > RAMP.combo) c.lastRamp = null;
|
||||
|
||||
+4
-2
@@ -13,12 +13,14 @@ import { versioned } from '../version.js';
|
||||
// suona il suo, più forte quanto più Andrea (`at`) le è vicino (mix). Le console possono stare anche fuori dal quadro:
|
||||
// è la musica della piazza accanto, che arriva da lontano.
|
||||
// `ok(cond)` dice se una condizione della storia vale adesso (game.js, check).
|
||||
export function trackFor(story, { screen, scene, phase, closeup, at, ok = () => false }) {
|
||||
// `table`: la tavola del primo piano, se ne ha più d'una (il flipper: 'classic' o 'future'), che può avere la sua musica.
|
||||
export function trackFor(story, { screen, scene, phase, closeup, table, at, ok = () => false }) {
|
||||
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;
|
||||
if (closeup && story.closeups?.[closeup]?.music) return story.closeups[closeup].music;
|
||||
const cu = closeup && story.closeups?.[closeup];
|
||||
if (cu?.music) return cu.tableMusic?.[table] ?? cu.music;
|
||||
const sc = story.scenes[scene];
|
||||
const stages = (sc?.stages ?? []).filter(st => ok(st.when));
|
||||
if (stages.length) return mix(stages, at ?? sc.entry ?? [320, 300]);
|
||||
|
||||
@@ -175,9 +175,8 @@ export class Soundscape {
|
||||
else if (kind === 'flipper-jackpot') { for (const [i, f] of [523, 659, 784, 1046, 1318, 1568].entries()) this.tone(f, f, 0.14, 0.06, i * 0.07, pan); for (const [i, f] of [1046, 1318, 1568].entries()) this.tone(f, f * 1.01, 0.7, 0.05, 0.5 + i * 0.04, pan); }
|
||||
else if (kind === 'flipper-super-open') { this.noiseSound(0.45, 1600, 0.04, { pan }); this.tone(180, 1200, 0.65, 0.06, 0, pan); for (const [i, f] of [659, 880, 1318].entries()) this.tone(f, f, 0.18, 0.05, 0.5 + i * 0.12, pan); }
|
||||
else if (kind === 'flipper-super') { for (const [i, f] of [392, 523, 659, 784, 1046, 1318, 1568, 2093].entries()) this.tone(f, f * 1.005, 0.24, 0.055, i * 0.08, pan); for (const [i, f] of [523, 784, 1046].entries()) this.tone(f, f, 0.9, 0.045, 0.65 + i * 0.04, pan); }
|
||||
// Timbri originali della tavola nascosta: botto grave, scintille, arpeggio pulsante in simulazione.
|
||||
// Timbri originali della tavola nascosta: botto grave e scintille (la musica è flipper-futuro.mp3, di Andrea).
|
||||
else if (kind === 'flipper-esplosione') { this.noiseSound(1.1, 700, 0.14, { pan }); this.tone(130, 32, 1.2, 0.13, 0, pan); this.tone(90, 1800, 1.6, 0.06, 0.7, pan); }
|
||||
else if (kind.startsWith('flipper-futuro-beat-')) { const f = [196, 294, 247, 370][Number(kind.at(-1))]; this.tone(85, 42, 0.12, 0.035, 0, pan); this.tone(f, f * 1.005, 0.18, 0.025, 0, pan); this.tone(f * 2, f * 2, 0.1, 0.018, 0.25, pan); }
|
||||
else if (kind === 'flipper-futuro-giro') { this.tone(390, 1560, 0.38, 0.065, 0, pan); this.tone(1174, 1174, 0.25, 0.04, 0.25, pan); }
|
||||
else if (kind === 'flipper-futuro-finale') { this.noiseSound(0.7, 1600, 0.07, { pan }); for (const [i, f] of [196, 294, 494, 740, 988, 1480].entries()) this.tone(f, f, 0.5, 0.055, i * 0.12, pan); }
|
||||
else if (kind === 'flipper-rampa') { this.noiseSound(0.25, 2400, 0.04, { pan }); this.tone(300, 900, 0.3, 0.04, 0, pan); }
|
||||
|
||||
+1
-1
@@ -1194,7 +1194,7 @@ function frame(now) {
|
||||
const searching = game?.closeup?.id === 'fessura';
|
||||
music.duck = searching ? game.closeup.found >= 2 ? 0.05 : 0.25 : game?.state.flags.occhi_regolo ? 0.12 : voices.playing ? 0.45 : 1;
|
||||
music.update(trackFor(story, { screen, scene: game?.state.scene, phase: game?.phase(), closeup: game?.closeup?.id,
|
||||
at: game && [game.state.x, game.state.y], ok: cond => !!game && check(cond, game.state) }), dt);
|
||||
table: game?.closeup?.table, at: game && [game.state.x, game.state.y], ok: cond => !!game && check(cond, game.state) }), 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();
|
||||
ambience.configure({ active: screen === 'game' && running && !document.hidden && $('credits').hidden, muted: music.muted, duck: voices.playing ? 0.4 : 1 });
|
||||
|
||||
+2
-1
@@ -363,7 +363,8 @@ export const story = {
|
||||
// Il flipper del River (Andrea, 31 ottobre: «una tavola bellissima, con San Piero dentro»): la tavola di Codex,
|
||||
// fisica e parti meccaniche in flipper.js. [DA ANDREA: le battute sono provvisorie]
|
||||
flipper: {
|
||||
type: 'flipper', music: 'assets/audio/flipper.mp3', // di Andrea (Suno, 1 novembre)
|
||||
// Le musiche di Andrea (Suno, 1 novembre): la classica, e quella del Regolo del futuro dopo la SUPER SPECIAL.
|
||||
type: 'flipper', music: 'assets/audio/flipper.mp3', tableMusic: { future: 'assets/audio/flipper-futuro.mp3' },
|
||||
picture: 'assets/closeups/river-flipper.png',
|
||||
backglass: 'assets/closeups/river-flipper-tabellone.png', // il fondale luminoso del tabellone (Codex: Trebbio, Fortezza, Regolo, fuochi)
|
||||
names: { player: 'Andrea', cpu: 'il flipper' },
|
||||
|
||||
@@ -562,7 +562,7 @@ test('il ball save nel futuro salva una sola volta, conserva campo e sigilli, po
|
||||
test('i tre percorsi del futuro sono raggiungibili con il colpo fisico della paletta', () => {
|
||||
for (const [id, x, y] of [['orbita', 288, 300], ['ponte', 290, 306], ['spira', 308, 320]]) {
|
||||
const c = m.newFlipper(9);
|
||||
Object.assign(c, m.futureLayout(), { table: 'future', future: { hits: { orbita: 0, ponte: 0, spira: 0 }, beatAt: 0 } });
|
||||
Object.assign(c, m.futureLayout(), { table: 'future', future: { hits: { orbita: 0, ponte: 0, spira: 0 } } });
|
||||
m.launch(c, 0.8); c.saveUntil = 0;
|
||||
put(c, { x, y, vx: 0, vy: 180, inPlay: true }); m.hold(c, 'left', 'test', true);
|
||||
let entered = null;
|
||||
|
||||
@@ -24,10 +24,13 @@ test('il brano giusto per titolo, fine e scena', () => {
|
||||
assert.equal(trackFor({ ...s, scenes: { ...s.scenes, i: { indoor: true } } }, { screen: 'game', scene: 'i', phase: sera }), 'g.mp3');
|
||||
});
|
||||
|
||||
test('il flipper del River ha la sua musica, e il file c\'è', () => {
|
||||
test('il flipper del River ha la sua musica, e un\'altra la tavola del futuro', () => {
|
||||
const track = trackFor(story, { screen: 'game', scene: 'river', closeup: 'flipper' });
|
||||
assert.equal(track, 'assets/audio/flipper.mp3');
|
||||
assert.ok(existsSync(track));
|
||||
assert.equal(trackFor(story, { screen: 'game', scene: 'river', closeup: 'flipper', table: 'classic' }), track);
|
||||
const future = trackFor(story, { screen: 'game', scene: 'river', closeup: 'flipper', table: 'future' });
|
||||
assert.equal(future, 'assets/audio/flipper-futuro.mp3', 'il Regolo del futuro ha la sua musica');
|
||||
for (const f of [track, future]) assert.ok(existsSync(f), f);
|
||||
});
|
||||
|
||||
test('volume e muto', () => {
|
||||
|
||||
Reference in New Issue
Block a user