Biliardo più bello (Codex): tavolo in pixel art visto dall'alto con cornice a fasce e diamanti, sala in penombra e luce delle lampade sul panno, segnapunti a cifre rosse, steccata e birilli che cadono animati, biglie in pixel, l'Ing. Tozzi a bordo tavolo che dà il gesso, esulta o allarga le braccia. Più: scritte a 8 punti (a 6 la B sembrava una D) e la stecca che torna a seguire il mouse finché un clic non fissa la mira (Andrea: «non riesco più a girare la stecca»)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018ks2K99uqCZjAxvy7Rdj1R
This commit is contained in:
@@ -41,6 +41,8 @@ export function newBiliardo(seed = Date.now() >>> 0, def = {}) {
|
||||
holding: false, holdTime: 0, accumulator: 0, events: [], points: { player: 0, cpu: 0 }, last: null, shot: null, plan: null };
|
||||
c.balls = { player: ball('player', LEN * 0.18, WID * 0.5), cpu: ball('cpu', LEN * 0.81, WID * 0.25), pallino: ball('pallino', LEN * 0.88, WID * 0.7) };
|
||||
c.pins = castle();
|
||||
// Cronologia di sola presentazione: non entra in urti, guida, regole o scelte della CPU.
|
||||
c.visual = { time: 0, shot: null, frames: [] };
|
||||
c.angle = angleTo(c.balls.player, c.balls.cpu);
|
||||
return c;
|
||||
}
|
||||
@@ -158,6 +160,8 @@ function step(w, dt) {
|
||||
|
||||
function strike(c, who, angle, power) {
|
||||
const b = c.balls[who], v = speedFor(power);
|
||||
c.visual.shot = { at: c.visual.time, angle, power, x: b.x, y: b.y };
|
||||
c.visual.frames = [{ at: c.visual.time, balls: list(c).map(b => ({ ...b })), pins: c.pins.map(p => ({ ...p })) }];
|
||||
b.vx = Math.cos(angle) * v; b.vy = Math.sin(angle) * v;
|
||||
c.shot = { shooter: who, first: null, pallino: false, pins: [] };
|
||||
c.step = 'rolling'; c.t = c.accumulator = 0; c.angle = angle; c.power = power; c.plan = null;
|
||||
@@ -176,6 +180,7 @@ export function simulate(c, who, angle, power) {
|
||||
|
||||
// I birilli si rialzano; una biglia ferma sopra il posto di un birillo si sposta appena quanto basta.
|
||||
function reset(c) {
|
||||
for (const p of c.pins) delete p.visualDownAt;
|
||||
for (const p of c.pins) { p.down = false; delete p.by; delete p.dir; }
|
||||
for (let pass = 0; pass < 4; pass++) {
|
||||
for (const b of list(c)) for (const p of c.pins) {
|
||||
@@ -224,6 +229,7 @@ function cpuThink(c, budget = 12) {
|
||||
export function update(c, dt) {
|
||||
if (!Number.isFinite(dt) || dt <= 0) return;
|
||||
dt = Math.min(dt, 0.25); c.t += dt;
|
||||
c.visual.time += dt;
|
||||
if (c.last) c.last.age += dt;
|
||||
if (c.holding) { c.holdTime += dt; c.power = powerAt(c.holdTime); }
|
||||
if (c.step === 'rolling') {
|
||||
@@ -236,6 +242,11 @@ export function update(c, dt) {
|
||||
if (!c.plan && c.t >= CPU_THINK) cpuThink(c);
|
||||
if (c.plan && c.t >= CPU_SHOT) strike(c, 'cpu', c.plan.angle, c.plan.power);
|
||||
}
|
||||
if (c.step === 'rolling' || c.step === 'settle') {
|
||||
for (const p of c.pins) if (p.down && p.visualDownAt === undefined) p.visualDownAt = c.visual.time;
|
||||
c.visual.frames.push({ at: c.visual.time, balls: list(c).map(b => ({ ...b })), pins: c.pins.map(p => ({ ...p })) });
|
||||
while (c.visual.frames.length > 2 && c.visual.frames[1].at < c.visual.time - 0.4) c.visual.frames.shift();
|
||||
}
|
||||
}
|
||||
|
||||
// --- Comandi del giocatore: gli stessi delle bocce.
|
||||
|
||||
Reference in New Issue
Block a user