diff --git a/js/main.js b/js/main.js index de4486f..8ee525e 100644 --- a/js/main.js +++ b/js/main.js @@ -5,6 +5,16 @@ let lastFrameTime = 0; let fps = 0; let debugMode = false; +// Sky background variables +const SKY_COLORS = [ + '#1a2980', // Deep blue + '#2980b9', // Medium blue + '#6dd5fa', // Light blue + '#2980b9', // Medium blue +]; +let skyAnimationTime = 0; +let skyAnimationSpeed = 0.0005; // Controls how fast the sky animates + // Initialize the simulation window.onload = function() { canvas = document.getElementById('simulation-canvas'); diff --git a/js/render.js b/js/render.js index d9cf3b0..b3fd3b3 100644 --- a/js/render.js +++ b/js/render.js @@ -6,6 +6,9 @@ function render() { // Clear the canvas ctx.clearRect(0, 0, canvas.width, canvas.height); + // Draw animated sky background + renderSky(); + // Get visible chunks const visibleChunks = getVisibleChunks(); @@ -63,6 +66,10 @@ function render() { // Reset world moved flag after rendering worldMoved = false; + // Update sky animation + skyAnimationTime += skyAnimationSpeed; + if (skyAnimationTime > 1) skyAnimationTime -= 1; + // Render physics objects renderPhysicsObjects(ctx, worldOffsetX, worldOffsetY); @@ -104,6 +111,58 @@ function render() { } } +// Render the animated sky background +function renderSky() { + // Create a gradient that cycles through sky colors + const gradient = ctx.createLinearGradient(0, 0, 0, canvas.height); + + // Calculate color indices based on animation time + const colorIndex1 = Math.floor(skyAnimationTime * SKY_COLORS.length) % SKY_COLORS.length; + const colorIndex2 = (colorIndex1 + 1) % SKY_COLORS.length; + const colorIndex3 = (colorIndex2 + 1) % SKY_COLORS.length; + + // Calculate blend factor between colors + const blendFactor = (skyAnimationTime * SKY_COLORS.length) % 1; + + // Add color stops to create a smooth transition + gradient.addColorStop(0, SKY_COLORS[colorIndex1]); + gradient.addColorStop(0.5, SKY_COLORS[colorIndex2]); + gradient.addColorStop(1, SKY_COLORS[colorIndex3]); + + // Fill the background with the gradient + ctx.fillStyle = gradient; + ctx.fillRect(0, 0, canvas.width, canvas.height); + + // Add some clouds (simple white circles with varying opacity) + const cloudCount = 5; + ctx.fillStyle = 'rgba(255, 255, 255, 0.4)'; + + for (let i = 0; i < cloudCount; i++) { + // Use animation time to move clouds slowly across the sky + const cloudX = ((i * canvas.width / cloudCount) + (skyAnimationTime * canvas.width * 2)) % (canvas.width * 1.5) - canvas.width * 0.25; + const cloudY = canvas.height * (0.1 + (i % 3) * 0.1); + const cloudSize = 50 + (i % 3) * 30; + + // Draw cloud (group of overlapping circles) + for (let j = 0; j < 5; j++) { + const offsetX = (j % 3) * cloudSize * 0.3; + const offsetY = Math.floor(j / 3) * cloudSize * 0.2; + ctx.beginPath(); + ctx.arc(cloudX + offsetX, cloudY + offsetY, cloudSize * 0.5, 0, Math.PI * 2); + ctx.fill(); + } + } + + // Add a subtle horizon line to separate sky from world + const horizonGradient = ctx.createLinearGradient(0, canvas.height * 0.4, 0, canvas.height * 0.6); + horizonGradient.addColorStop(0, 'rgba(255, 255, 255, 0)'); + horizonGradient.addColorStop(0.5, 'rgba(255, 255, 255, 0.1)'); + horizonGradient.addColorStop(1, 'rgba(255, 255, 255, 0)'); + + ctx.fillStyle = horizonGradient; + ctx.fillRect(0, canvas.height * 0.4, canvas.width, canvas.height * 0.2); +} + // Render a chunk to an offscreen canvas and cache it function renderChunkToCache(chunkX, chunkY, key) { const chunk = chunks.get(key);