Si sceglie il rione all'inizio: Piazza, Pieve, Cardetole o Campomigliaio
Dopo «Nuova partita» la domanda «Per chi corri quest'anno?» con i quattro rioni nei loro colori; la scelta resta nella partita (rione:<id>) e cambia la riga dell'introduzione e le battute sul rione di Andrea. Voci nuove. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ApqNBvNbNCwXqR2RLo8QJh
This commit is contained in:
+35
-10
@@ -1,6 +1,6 @@
|
||||
// Avvio nel browser: collega motore, disegno e interfaccia HTML (verbi, inventario, dialoghi, fumetti).
|
||||
import { story } from './story/story.js';
|
||||
import { Game, VERBS, VERB_LABELS, checkSave } from './engine/game.js';
|
||||
import { Game, VERBS, VERB_LABELS, checkSave, introText } from './engine/game.js';
|
||||
import { Command } from './engine/command.js';
|
||||
import { render, loadAssets, hasBackground, WIDTH, HEIGHT } from './engine/render.js';
|
||||
import { readSave, writeSave, clearSave, readAudio, writeAudio, saveFile, saveFileName, readSaveFile } from './engine/storage.js';
|
||||
@@ -45,9 +45,11 @@ window.voices = voices;
|
||||
let voiced = null;
|
||||
const say = (who, text) => voices.play(who, text, music.muted);
|
||||
|
||||
function start(state) {
|
||||
// Una partita salvata (state) o nuova; la nuova col rione scelto, che resta nei flag (`rione:<id>`).
|
||||
function start(state, rione = null) {
|
||||
game = new Game(story, { state, onSave: data => storage && writeSave(storage, data), voiceTime: (who, text) => voices.seconds(who, text) });
|
||||
command = new Command(game);
|
||||
if (!state && rione) game.state.flags['rione:' + rione] = true;
|
||||
if (!state) game.go(story.start.scene, story.start.at);
|
||||
$('title').hidden = true;
|
||||
$('ending').hidden = true;
|
||||
@@ -56,9 +58,28 @@ function start(state) {
|
||||
}
|
||||
|
||||
// --- Introduzione: le righe di story.intro una alla volta sopra il panorama; poi comincia la partita.
|
||||
// --- Il rione: dopo «Nuova partita», per chi corre Andrea (story.rioni); poi l'introduzione con la sua riga.
|
||||
let rione = null;
|
||||
$('rione-buttons').replaceChildren(...Object.entries(story.rioni ?? {}).map(([id, r]) => {
|
||||
const b = document.createElement('button');
|
||||
b.type = 'button';
|
||||
b.dataset.rione = id;
|
||||
b.style.setProperty('--rione', r.color);
|
||||
b.innerHTML = '<span class="rione-name"></span><span class="rione-colors"></span>';
|
||||
b.querySelector('.rione-name').textContent = r.name;
|
||||
b.querySelector('.rione-colors').textContent = r.colors;
|
||||
b.addEventListener('click', () => { rione = id; $('rione').hidden = true; showIntro(); });
|
||||
return b;
|
||||
}));
|
||||
function chooseRione() {
|
||||
if (!story.rioni) return showIntro();
|
||||
$('title').hidden = true;
|
||||
$('rione').hidden = false;
|
||||
}
|
||||
|
||||
let introLine = -1;
|
||||
function showIntro() {
|
||||
if (!story.intro?.length) return start(null);
|
||||
if (!story.intro?.length) return start(null, rione);
|
||||
$('title').hidden = true;
|
||||
$('intro').hidden = false;
|
||||
introLine = -1;
|
||||
@@ -66,10 +87,10 @@ function showIntro() {
|
||||
}
|
||||
function nextIntro() {
|
||||
introLine++;
|
||||
if (introLine >= story.intro.length) { voices.stop(); $('intro').hidden = true; return start(null); }
|
||||
const p = $('intro-text');
|
||||
p.textContent = story.intro[introLine];
|
||||
say('andrea', story.intro[introLine]);
|
||||
if (introLine >= story.intro.length) { voices.stop(); $('intro').hidden = true; return start(null, rione); }
|
||||
const p = $('intro-text'), text = introText(story.intro[introLine], rione);
|
||||
p.textContent = text;
|
||||
say('andrea', text);
|
||||
p.style.animation = 'none';
|
||||
void p.offsetWidth; // riavvia la comparsa
|
||||
p.style.animation = '';
|
||||
@@ -419,7 +440,7 @@ function frame(now) {
|
||||
// sotto zero, il browser lancerebbe un errore e il ciclo dei fotogrammi si fermerebbe (gioco congelato).
|
||||
const dt = Math.max(0, Math.min(0.1, (now - last) / 1000));
|
||||
last = now;
|
||||
const screen = !$('title').hidden ? 'title' : !$('splash').hidden ? 'splash' : !$('intro').hidden ? 'intro' : !$('ending').hidden ? 'ending' : 'game';
|
||||
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);
|
||||
@@ -437,9 +458,13 @@ function frame(now) {
|
||||
requestAnimationFrame(frame);
|
||||
}
|
||||
|
||||
$('new-game').addEventListener('click', () => { if (storage) clearSave(storage); showIntro(); });
|
||||
$('new-game').addEventListener('click', () => { if (storage) clearSave(storage); chooseRione(); });
|
||||
$('continue').addEventListener('click', () => start(readSave(storage)));
|
||||
$('restart').addEventListener('click', () => { if (storage) clearSave(storage); start(null); });
|
||||
// Ricomincia: stessa scelta di rione della partita appena finita.
|
||||
$('restart').addEventListener('click', () => {
|
||||
if (storage) clearSave(storage);
|
||||
start(null, Object.keys(game.state.flags).find(f => f.startsWith('rione:'))?.slice(6) ?? rione);
|
||||
});
|
||||
|
||||
// Dietro il titolo si vede già la piazza.
|
||||
// --- Cartello d'apertura «Manzolo (Poca) Art Presents»: 5 secondi (un clic o un tasto lo salta), poi il titolo.
|
||||
|
||||
Reference in New Issue
Block a user