From 656927eee167f01d095f1c084db721ae5dba8308 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Norman=20K=C3=B6hring?= Date: Sat, 18 Feb 2023 18:31:39 +0100 Subject: [PATCH] draw light instead of shadows --- src/util/useLightMap.ts | 63 ++++++++++++++++++++++++++++++++++------- 1 file changed, 52 insertions(+), 11 deletions(-) diff --git a/src/util/useLightMap.ts b/src/util/useLightMap.ts index 26bcd6a..11873bd 100644 --- a/src/util/useLightMap.ts +++ b/src/util/useLightMap.ts @@ -12,10 +12,11 @@ export default function useLightMap( ) { const W = ((STAGE_WIDTH + 2) * BLOCK_SIZE) const H = ((STAGE_HEIGHT + 2) * BLOCK_SIZE) + const B = BLOCK_SIZE - 4 // no idea why there is a difference, but it is 4px - const playerX = (W - BLOCK_SIZE) / 2 + BLOCK_SIZE / 4 - const playerY = H / 2 - BLOCK_SIZE / 2 - const playerLightSize = BLOCK_SIZE * 1.8 + const playerX = (W - B) / 2 + B / 4 + const playerY = H / 2 - B / 2 + const playerLightSize = B * 1.8 function getAmbientLightColor() { const t = time.value @@ -45,7 +46,7 @@ export default function useLightMap( playerX - tx.value, playerY - ty.value, playerLightSize * sizeMul ) - // Add three color stops + // Add color stops: white in the center to transparent white playerLight.addColorStop(0.0, "#FFFF"); playerLight.addColorStop(1, "#FFF0"); @@ -58,12 +59,12 @@ export default function useLightMap( const barrier = lightBarrier.value ctx.fillStyle = '#000A' - for (let col = 0; col < W / BLOCK_SIZE; col++) { - const level = (barrier[col] - y.value) * BLOCK_SIZE - const sw = BLOCK_SIZE * 0.935 + for (let col = 0; col < W / B; col++) { + const level = (barrier[col] - y.value) * B + const sw = B const sh = H - level const sx = col * sw - const sy = level * 0.995 + const sy = level ctx.fillRect(sx, sy, sw, sh) ctx.fillRect(sx, sy + 20, sw, sh) @@ -71,11 +72,51 @@ export default function useLightMap( } } + function drawLights() { + // used for everything above ground + const ambientLight = getAmbientLightColor() + const reflectedLight = ambientLight.slice(0, -1) + ', 50%)' + const surroundingLight = ambientLight.slice(-2) + const barrier = lightBarrier.value + // make light columns wider to illuminate surrounding blocks + const extra = Math.floor(B / 2) + + ctx.fillStyle = ambientLight + for (let col = 0; col < W / B; col++) { + const level = (barrier[col] - y.value) * B + const sw = B + const sh = level + const sx = col * sw + const sy = 0 + + ctx.fillRect(sx, sy, sw, sh) + } + + ctx.fillStyle = reflectedLight + for (let col = 0; col < W / B; col+=2) { + const level = (barrier[col] - y.value) * B + const sw = B + const sh = level + const sx = col * sw + const sy = 0 + + ctx.fillRect(sx - extra, sy - extra, sw + extra * 2, sh + extra * 2) + } + + // TODO: draw light for candles and torches + } + return function update() { - ctx.fillStyle = getAmbientLightColor() + // first, throw the world in complete darkness + ctx.fillStyle = '#000' ctx.fillRect(0, 0, W, H) - // TODO: switch from drawing shadows to drawing lights - drawShadows() + + // second, find and bring light into the world + drawLights() + + // finally, draw the players light + // with a size multiplicator which might be later used to + // simulate greater illumination with candles or torches drawPlayerLight(1) } }