diff --git a/assets/closeups/gp/casco-tozzino.png b/assets/closeups/gp/casco-tozzino.png index 8aef00b..4a91d25 100644 Binary files a/assets/closeups/gp/casco-tozzino.png and b/assets/closeups/gp/casco-tozzino.png differ diff --git a/assets/closeups/gp/puntella.png b/assets/closeups/gp/puntella.png new file mode 100644 index 0000000..d2323d4 Binary files /dev/null and b/assets/closeups/gp/puntella.png differ diff --git a/assets/closeups/gp/sr.png b/assets/closeups/gp/sr.png index 8c6cfe4..9fd8db1 100644 Binary files a/assets/closeups/gp/sr.png and b/assets/closeups/gp/sr.png differ diff --git a/docs/STATO.md b/docs/STATO.md index 6de61d5..0710c51 100644 --- a/docs/STATO.md +++ b/docs/STATO.md @@ -256,10 +256,10 @@ I prompt fissi (stile, scene, foglio sprite) sono in `prompts/STILE.md`, escluso `assets/closeups/gp-fortezza.png` (prompt `prompts/closeups/gp-fortezza.txt`, guida dalla planimetria `assets/raw/fortezza-planimetria.png`, satellite in `assets/raw/fortezza-satellite.png`); il tracciato è ricalcato sulla strada dipinta. Disegno `gara-render.js`, test `tests/gara.test.mjs`. I piloti sono dati in - `src/story/piloti.js`: una riga per amico, `motore` e `testa` da 1 a 5, colori dalle foto. Corrono Puntella (SR, - colori Aprilia da GP provvisori), Cistola (CR 50 Z), Andrea (Malaguti Fifty rosso e nero), Tozzino (Booster blu + `src/story/piloti.js`: una riga per amico, `motore` e `testa` da 1 a 5, colori dalle foto. Corrono Puntella (SR + truccatissimo, motore 6, viola e giallo dalla sua foto, ritratto di Codex), Cistola (CR 50 Z), Andrea (Malaguti Fifty rosso e nero), Tozzino (Booster blu scuro, di serie, casco alla Damon Hill di Codex: `prompts/personaggi/casco-tozzino.txt`), l'Arcu (Betino). Col telefono - si guida con un dito: premuto è gas, lo swipe indica dove andare sullo schermo (Codex, 28 ottobre). **Puntella (Marco Villani) non corre finché manca il suo consenso** (`consenso: null` in piloti.js: quando arriva, la data). Mancano: quanto erano + si guida con un dito: premuto è gas, lo swipe indica dove andare sullo schermo (Codex, 28 ottobre). Puntella (Marco Villani) ha dato il consenso il 28 ottobre; chi ha `consenso: null` in piloti.js non corre. Mancano: quanto erano truccati gli altri, le battute di Andrea, il rumore del motore (c'è solo quello dell'arrivo in griglia); i confini della paglia non si vedono sul quadro (revisione di Codex, punto 9). - Strade attorno a casa (Andrea, 28 ottobre): la scena `area_camper` ora si chiama «Le villette del Giannini» (ci abita diff --git a/src/engine/gara-render.js b/src/engine/gara-render.js index 4aa8c1e..bbf650f 100644 --- a/src/engine/gara-render.js +++ b/src/engine/gara-render.js @@ -174,7 +174,8 @@ function card(ctx, c, look, sheet) { for (const [k, [label, value]] of [['MOTORE', r.motore], ['TESTA', r.testa]].entries()) { const yy = y + 116 + k * 12; text(ctx, label, x + 222, yy, 5, '#c5c6b6'); - for (let i = 0; i < 5; i++) { ctx.fillStyle = i < value ? (k ? '#b9d392' : '#e0583a') : '#3a3f3c'; ctx.fillRect(x + 262 + i * 13, yy - 3, 10, 6); } + // Cinque caselle; il motore truccatissimo (6) ne accende una sesta, gialla. + for (let i = 0; i < Math.max(5, value); i++) { ctx.fillStyle = i >= 5 ? '#ffe28a' : i < value ? (k ? '#b9d392' : '#e0583a') : '#3a3f3c'; ctx.fillRect(x + 262 + i * 12, yy - 3, 9, 6); } } text(ctx, 'TOCCA: IL PROSSIMO', x + w / 2, y + h - 6, 5, '#8f9488', 'center'); } diff --git a/src/engine/gara.js b/src/engine/gara.js index cdd959a..580c8ea 100644 --- a/src/engine/gara.js +++ b/src/engine/gara.js @@ -35,10 +35,11 @@ const clamp = (v, lo, hi) => Math.max(lo, Math.min(hi, v)); const wrapAngle = a => Math.atan2(Math.sin(a), Math.cos(a)); // I piloti sono dati (story.closeups.gara.riders, da piloti.js): `motore` da 1 (di serie) a 5 (truccato da far -// paura), `testa` da 1 (matto) a 5 (prudente). Ne vengono velocità massima e accelerazione in px/s, tenuta, e per gli +// paura, 6 truccatissimo), `testa` da 1 (matto) a 5 (prudente). Ne vengono velocità massima e accelerazione in px/s, tenuta, e per gli // altri quanto si fidano delle curve (`caution`) e quanto spesso rischiano troppo (`slip`). export function rider({ motore = 3, testa = 3, ...r }) { - const m = clamp(motore, 1, 5), t = clamp(testa, 1, 5); + // Il 6 è il truccatissimo: lo SR di Puntella (Andrea, 28 ottobre). + const m = clamp(motore, 1, 6), t = clamp(testa, 1, 5); return { ...r, motore: m, testa: t, vmax: 74 + 6.5 * m, accel: 40 + 5 * m, grip: 1.1 - 0.03 * m, caution: 1.0025 - 0.0125 * t, slip: 0.4275 - 0.0775 * t }; } // Il gruppo di prova, quando la storia non ne dà uno. diff --git a/src/story/piloti.js b/src/story/piloti.js index 80c2dc4..4b93be3 100644 --- a/src/story/piloti.js +++ b/src/story/piloti.js @@ -1,21 +1,22 @@ // La gara dei cinquantini (idea di Andrea, 28 ottobre): chi corre, in ordine di griglia (due per fila). // Ogni amico che manda la foto del suo motorino si aggiunge con una riga. `motore`: da 1 (di serie) a 5 (truccato da -// far paura); `testa`: da 1 (matto, in curva rischia) a 5 (prudente). `color` e `trim`: i colori del motorino in pista. +// far paura; 6 truccatissimo, solo lo SR di Puntella); `testa`: da 1 (matto, in curva rischia) a 5 (prudente). `color` e `trim`: i colori del motorino in pista. // Per la presentazione: `moto`, il disegno del motorino (Codex, dalla foto); `sprite`, il personaggio del gioco (un // nome di story.characters), oppure `face`, un ritratto quadrato; senza nessuno dei due, una sagoma. `casco`: il disegno // del casco per il cartellino, `helmet` e `stripe` i suoi colori visti dall'alto in pista. // Persone vere solo col loro consenso (`consenso`: chi l'ha dato e quando). export const piloti = [ - // Lo SR di Puntella era il più truccato di tutti; per ora i colori dell'Aprilia SR 50 da GP (foto di Andrea). - { id: 'puntella', name: 'Puntella', bike: 'lo SR', motore: 5, testa: 1, color: '#5a3fb5', trim: '#e8442e', moto: 'assets/closeups/gp/sr.png', consenso: null }, // [DA ANDREA: consenso di Marco Villani] + // Puntella (Marco Villani, consenso del 28 ottobre) con lo SR truccatissimo, viola e giallo come il suo (foto di + // Andrea); il ritratto dalla sua foto. + { id: 'puntella', name: 'Puntella', bike: 'lo SR truccatissimo', motore: 6, testa: 1, color: '#5b2a9e', trim: '#f2c81e', moto: 'assets/closeups/gp/sr.png', face: 'assets/closeups/gp/puntella.png', consenso: '2026-10-28' }, // Cistola (Davide Poggi) col suo CR 50 Z, blu notte e argento, dalla foto che ha mandato; il volto dal suo murale. { id: 'cistola', name: 'Cistola', bike: 'il CR 50 Z', motore: 4, testa: 3, color: '#1d2440', trim: '#a9adb5', moto: 'assets/closeups/gp/cr50z.png', face: 'assets/closeups/gp/cistola.png', consenso: '2026-10-27' }, // Il Malaguti Fifty di Andrea: rosso con le rifiniture nere. { id: 'andrea', name: 'Andrea', bike: 'il Fifty', motore: 3, testa: 3, color: '#d8402f', trim: '#1c1c1c', moto: 'assets/closeups/gp/fifty.png', sprite: 'andrea' }, // Tozzino (Francesco Tozzi) col suo Booster blu scuro, di serie, dalle foto che ha mandato (l'adesivo sul manubrio compreso). { id: 'tozzino', name: 'Tozzino', bike: 'il Booster', motore: 1, testa: 3, color: '#1a2a52', trim: '#111318', moto: 'assets/closeups/gp/booster.png', sprite: 'tozzino', - // Il casco alla Damon Hill: blu scuro con le righe bianche dei remi (Andrea, 28 ottobre). - casco: 'assets/closeups/gp/casco-tozzino.png', helmet: '#1b2a5c', stripe: '#f4f4f4' }, + // Il casco alla Damon Hill: blu notte con poche pale di remo bianche, strette e a punta (foto di Andrea, 28 ottobre). + casco: 'assets/closeups/gp/casco-tozzino.png', helmet: '#131c3c', stripe: '#f4f4f4' }, // Il Betino dell'Arcu: verde e crema, lento ma non cade mai. { id: 'arcu', name: 'L\'Arcu', bike: 'il Betino', motore: 1, testa: 5, color: '#2f7a3a', trim: '#e8d9a0', moto: 'assets/closeups/gp/betino.png', sprite: 'arcu' }, ]; diff --git a/tests/gara.test.mjs b/tests/gara.test.mjs index 765af3d..f79a16e 100644 --- a/tests/gara.test.mjs +++ b/tests/gara.test.mjs @@ -39,11 +39,12 @@ const careful = c => { return c.holding; }; -test('i piloti sono dati: motore e testa da 1 a 5 danno velocità, accelerazione e prudenza', () => { +test('i piloti sono dati: motore da 1 a 6 e testa da 1 a 5 danno velocità, accelerazione e prudenza', () => { const slow = rider({ motore: 1, testa: 5 }), fast = rider({ motore: 5, testa: 1 }); assert.ok(fast.vmax > slow.vmax && fast.accel > slow.accel && fast.grip < slow.grip); assert.ok(fast.slip > slow.slip && fast.caution > slow.caution); - assert.deepEqual(rider({ motore: 9, testa: -2 }).motore, 5, 'fuori scala si ferma ai bordi'); + assert.deepEqual(rider({ motore: 9, testa: -2 }).motore, 6, 'fuori scala si ferma ai bordi (6, il truccatissimo)'); + assert.equal(rider({ motore: 9, testa: -2 }).testa, 1); // Ogni pilota della storia ha nome, motorino e colore; Andrea c'è una volta sola. for (const p of piloti) { assert.ok(p.id && p.name && p.bike && /^#[0-9a-f]{6}$/i.test(p.color), p.id); } assert.equal(piloti.filter(p => p.id === 'andrea').length, 1); @@ -250,7 +251,7 @@ test('nella storia: dal Trappola l\'Arcu scherza sul Betino, poi la sfida; prima assert.ok(before.some(t => t.includes('prendo la rincorsa'))); assert.equal(g.closeup?.id, 'gara'); assert.equal(g.closeup.level, 'seria'); assert.deepEqual(g.closeup.riders.map(r => r.id), piloti.filter(p => p.consenso !== null).map(p => p.id)); - assert.ok(!g.closeup.riders.some(r => r.id === 'puntella'), 'senza consenso non corre'); + assert.ok(!g.closeup.riders.some(r => r.consenso === null), 'senza consenso non corre'); g.closeup.result = { winner: 'player', place: 1, times: {}, order: ['andrea'], offs: 0 }; g.closeup.step = 'result'; g.closeupClose(); const after = settle(g).map(s => s.text); assert.ok(g.state.flags.gara_vinta);