Al Trebbio parla lo spirito del castello: compare accanto alla torre, semitrasparente, con la lanterna

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ApqNBvNbNCwXqR2RLo8QJh
This commit is contained in:
2026-10-24 22:33:24 +02:00
co-authored by Claude Opus 5.5
parent fd8150305e
commit 73a8be39c5
4 changed files with 38 additions and 2 deletions
+24
View File
@@ -160,6 +160,7 @@ export function render(ctx, game, { hover, spots, debug, time = performance.now(
if (sheet) queue.push({ y: p.at[1], draw: () => drawSprite(ctx, sheet, game.personPose(p), ...p.at, game.scaleAt(p.at[1]), p.facing ?? 1, p.size) });
}
for (const q of queue.sort((a, b) => a.y - b.y)) q.draw();
drawApparitions(ctx, game, time);
drawLights(ctx, scene, time);
for (const shape of art) if (shape.top) drawShape(ctx, shape);
if (spots) drawSpots(ctx, game);
@@ -172,6 +173,29 @@ export function render(ctx, game, { hover, spots, debug, time = performance.now(
}
}
// Le apparizioni (`apparitions`): uno spirito che compare solo mentre parla (un dialogo suo, o una sua battuta),
// semitrasparente, che ondeggia piano, con un alone freddo intorno e il caldo della lanterna.
function drawApparitions(ctx, game, time) {
for (const a of game.scene.apparitions ?? []) {
if (game.dialogue?.id !== a.who && game.speech?.who !== a.who) continue;
const img = backgrounds.get(a.src);
if (!img) { loadBackground(a.src); continue; }
const h = a.height, w = Math.round(img.width * h / img.height), bob = Math.round(Math.sin(time / 600) * 2);
const x = Math.round(a.at[0] - w / 2), y = a.at[1] - h + bob;
ctx.save();
const halo = ctx.createRadialGradient(a.at[0], y + h * 0.45, 0, a.at[0], y + h * 0.45, h * 0.7);
halo.addColorStop(0, 'rgba(180, 230, 255, 0.28)');
halo.addColorStop(1, 'rgba(180, 230, 255, 0)');
ctx.globalCompositeOperation = 'lighter';
ctx.fillStyle = halo;
ctx.fillRect(a.at[0] - h, y - h * 0.3, h * 2, h * 1.6);
ctx.globalCompositeOperation = 'source-over';
ctx.globalAlpha = 0.82 + 0.08 * Math.sin(time / 380);
ctx.drawImage(img, x, y, w, h);
ctx.restore();
}
}
// Le scene buie (`shade`: il velo scuro sopra tutto, Andrea compreso) e le fiammelle (`lights`: candele accese).
// Ogni fiamma ha due disegni che si alternano a caso, e intorno un alone caldo che pulsa piano.
const FLAME_STEP = 140;