Dentro la Pieve in penombra con le candele accese che tremolano; al tennis della chiesa si entra solo dal cancello verde
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ApqNBvNbNCwXqR2RLo8QJh
This commit is contained in:
+35
-1
@@ -139,7 +139,7 @@ function drawSprite(ctx, { atlas, img }, frame, x, y, scale, facing, size = 1) {
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
export function render(ctx, game, { hover, spots, debug } = {}) {
|
||||
export function render(ctx, game, { hover, spots, debug, time = performance.now() } = {}) {
|
||||
const scene = game.scene, s = game.state, bg = backgrounds.get(scene.background);
|
||||
if (!bg && scene.background) loadBackground(scene.background);
|
||||
ctx.imageSmoothingEnabled = false;
|
||||
@@ -158,6 +158,7 @@ export function render(ctx, game, { hover, spots, debug } = {}) {
|
||||
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();
|
||||
drawLights(ctx, scene, time);
|
||||
if (spots) drawSpots(ctx, game);
|
||||
if (debug) drawDebug(ctx, game, debug);
|
||||
if (hover) {
|
||||
@@ -168,6 +169,39 @@ export function render(ctx, game, { hover, spots, debug } = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
export function flameFrame(time, i) {
|
||||
const n = Math.floor(time / FLAME_STEP) * 31 + i * 17;
|
||||
return ((n * 2654435761) >>> 0) % 7 < 3 ? 1 : 0;
|
||||
}
|
||||
function drawLights(ctx, scene, time) {
|
||||
if (scene.shade) {
|
||||
ctx.fillStyle = scene.shade;
|
||||
ctx.fillRect(0, 0, WIDTH, HEIGHT);
|
||||
}
|
||||
if (!scene.lights?.length) return;
|
||||
ctx.save();
|
||||
ctx.globalCompositeOperation = 'lighter';
|
||||
scene.lights.forEach(({ at: [x, y], glow = 30 }, i) => {
|
||||
const pulse = 0.85 + 0.15 * Math.sin(time / 260 + i * 1.7);
|
||||
const g = ctx.createRadialGradient(x, y - 2, 0, x, y - 2, glow * pulse);
|
||||
g.addColorStop(0, 'rgba(255, 170, 70, 0.4)');
|
||||
g.addColorStop(1, 'rgba(255, 120, 40, 0)');
|
||||
ctx.fillStyle = g;
|
||||
ctx.fillRect(x - glow, y - 2 - glow, glow * 2, glow * 2);
|
||||
});
|
||||
ctx.restore();
|
||||
scene.lights.forEach(({ at: [x, y] }, i) => {
|
||||
const tall = flameFrame(time, i);
|
||||
ctx.fillStyle = '#ff9a2e';
|
||||
ctx.fillRect(x - 1, y - 3 - tall, 2, 3 + tall);
|
||||
ctx.fillStyle = '#ffe9a0';
|
||||
ctx.fillRect(tall ? x - 1 : x, y - 2 - tall, 1, 2);
|
||||
});
|
||||
}
|
||||
|
||||
// Il pulsante «?»: un segno su ogni cosa che si può toccare, col suo nome. Le uscite in giallo, il resto in bianco.
|
||||
// I nomi non si sovrappongono: placeLabels cerca per ognuno un posto libero vicino al suo segno.
|
||||
function drawSpots(ctx, game) {
|
||||
|
||||
Reference in New Issue
Block a user