Bocce: il clic fissa la mira come al biliardo, così andando verso la forza o «Lancia» il puntatore non la sposta più (scoperto girando il video: la boccia partiva a due passi). Copioni dei video «Come si gioca» di scopa, tressette, bocce e biliardo, e video/sovrapposte.py per controllare che il narratore non parli sopra i personaggi
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01A1dxvtsZx8NE9fwjXUNDBr
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
// Copione del video «Come si gioca: le bocce» (video/SCALETTA-CARTE.md, clip 4).
|
||||
// Giro: video/narra.py, poi rec.mjs come in video/SCALETTA.md, poi video/monta.py <cartella> --tutorial.
|
||||
import { c, sleep, setup as base, regista } from "./tutorial-comune.mjs";
|
||||
|
||||
export const title = { it: "Come si gioca · le bocce", en: "Come si gioca · le bocce" };
|
||||
export const cues = [
|
||||
c("dove", "Le bocce si giocano al pallaio, accanto al tennis della chiesa. Mariano, il campione, sfida chiunque"),
|
||||
c("livello", "Si sceglie quanto deve impegnarsi: alla bona, seria, o a fassi male"),
|
||||
c("campo", "Il campo visto da dietro: in fondo c'è il pallino, e a sinistra il dettaglio, per vedere da vicino chi è più accosto"),
|
||||
c("mira", "Per mirare si tocca il campo, o il dettaglio vicino al pallino. Il cerchio azzurro dice dove si fermerebbe la boccia"),
|
||||
c("forza", "Poi si regola la forza col cursore, e si preme Lancia"),
|
||||
c("turno", "Tira sempre chi non ha il punto. Chi è dietro può accostare, oppure bocciare: colpire la boccia dell'altro per toglierla di lì"),
|
||||
c("tieni", "C'è anche un altro modo: si tiene premuto sul campo, la forza sale, e lasciando parte la boccia. Vanno bene anche le frecce e la barra spaziatrice"),
|
||||
c("punti", "Tre bocce a testa. Alla fine fa un punto ogni boccia più vicina al pallino della migliore dell'avversario"),
|
||||
c("fine", "E se batti Mariano, ti porta a Brento Sanico. Buona partita!"),
|
||||
];
|
||||
|
||||
export const setup = base;
|
||||
|
||||
export async function run(d) {
|
||||
const p = d.page, r = regista(d, "tutorial-bocce");
|
||||
await r.ascolta();
|
||||
await r.vaiA("tennis_chiesa", [430, 310]);
|
||||
await r.cue("dove");
|
||||
await r.parlaCon("mariano");
|
||||
await r.scegli("Facciamo una partita");
|
||||
await r.cue("livello");
|
||||
await r.scegli("Alla bona.");
|
||||
// Una mano fissa: accostando bene, Andrea fa tre punti (anche se il tiro a pressione viene un po' corto o lungo).
|
||||
await p.evaluate(async () => {
|
||||
const { newBocce } = await import("/src/engine/bocce.js");
|
||||
game.closeup = { id: "bocce", ...newBocce(9, { level: "bona" }) };
|
||||
});
|
||||
await sleep(800);
|
||||
await p.waitForFunction(() => window.music?.want === "assets/audio/bocce.mp3", null, { timeout: 10000 });
|
||||
await r.cue("campo");
|
||||
await r.muovi([300, 200], 1.0); await sleep(400); await r.muovi([90, 170], 1.0);
|
||||
|
||||
// Dove mirare: poco prima del pallino, così la boccia si ferma accosto (il cerchio azzurro ci finisce sopra).
|
||||
const mira = () => p.evaluate(async () => {
|
||||
const B = await import("/src/engine/bocce.js"), c = game.closeup, u = c.jack.u - 0.55, w = c.jack.w;
|
||||
const s = B.project(u, w);
|
||||
return { at: [s.x, s.y], u, w, power: B.powerFor(Math.hypot(u, w) - 0.29) };
|
||||
});
|
||||
const tocca = async () => {
|
||||
for (let i = 0; i < 600; i++) {
|
||||
const s = await p.evaluate(async () => {
|
||||
const { canThrow } = await import("/src/engine/bocce.js");
|
||||
return game.closeup.step === "result" ? "fine" : canThrow(game.closeup) && !game.speech ? "tocca" : "aspetta";
|
||||
});
|
||||
if (s !== "aspetta") return s === "tocca";
|
||||
await sleep(150);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
let tiro = 0;
|
||||
while (await tocca()) {
|
||||
tiro++;
|
||||
const m = await mira();
|
||||
if (tiro === 1) await r.cue("mira");
|
||||
if (tiro < 3) {
|
||||
// Mira col clic, forza col cursore, poi Lancia.
|
||||
await r.clicca(m.at, 0.8);
|
||||
await p.evaluate(async ({ u, w }) => (await import("/src/engine/bocce.js")).aim(game.closeup, u, w), m);
|
||||
if (tiro === 1) await r.cue("forza");
|
||||
await d.hover(p.locator("#bocce-power"), 0.6);
|
||||
await p.locator("#bocce-power").fill(String(Math.round(m.power * 100)));
|
||||
await p.evaluate(async (v) => (await import("/src/engine/bocce.js")).setPower(game.closeup, v), m.power);
|
||||
await sleep(600);
|
||||
await d.click(p.locator("#bocce-throw"), 0.6);
|
||||
if (tiro === 1) await r.cue("turno");
|
||||
} else {
|
||||
// L'ultima tenendo premuto: la forza sale finché non si lascia.
|
||||
await r.cue("tieni");
|
||||
await r.muovi(m.at, 0.8);
|
||||
const [a, b] = await r.punto(...m.at);
|
||||
d.vm(`DISPLAY=:0 xdotool mousemove ${Math.round(a)} ${Math.round(b)} mousedown 1 sleep ${(m.power * 1.6).toFixed(2)} mouseup 1`);
|
||||
}
|
||||
await p.locator("#scene").scrollIntoViewIfNeeded();
|
||||
}
|
||||
await p.waitForFunction(() => game.closeup.step === "result", null, { timeout: 90000 });
|
||||
await sleep(1000);
|
||||
await r.cue("punti");
|
||||
await r.cue("fine");
|
||||
await r.aspetta();
|
||||
await d.click(p.locator("#closeup-close"), 0.6);
|
||||
await r.fermi(800);
|
||||
await r.fine();
|
||||
await r.salvaAudio();
|
||||
}
|
||||
Reference in New Issue
Block a user