diff --git a/js/render.js b/js/render.js index 3b269e0..31a410d 100644 --- a/js/render.js +++ b/js/render.js @@ -66,7 +66,7 @@ function render() { // Reset world moved flag after rendering worldMoved = false; - // Update cloud position animation only (not colors) + // Update cloud position animation only (not colors or shapes) skyAnimationTime += skyAnimationSpeed; if (skyAnimationTime > 1) skyAnimationTime -= 1; @@ -125,53 +125,69 @@ function renderSky() { ctx.fillStyle = gradient; ctx.fillRect(0, 0, canvas.width, canvas.height); - // Add some clouds (bigger clouds made of more, smaller circles) + // Add some clouds (made of pixel squares instead of circles) const cloudCount = 5; ctx.fillStyle = 'rgba(255, 255, 255, 0.5)'; for (let i = 0; i < cloudCount; i++) { // Use animation time to move clouds slowly across the sky + // Only the position is animated, not the shape 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 = 40 + (i % 3) * 25; // Bigger overall cloud size + const cloudSize = 40 + (i % 3) * 25; // Overall cloud size - // Draw cloud (group of many overlapping smaller circles) - // Create a more complex cloud shape with more circles - const circleCount = 12; // More circles for more detail + // Use a deterministic pattern for each cloud based on its index + // This ensures the cloud shape doesn't change every frame + const seed = i * 1000; // Different seed for each cloud + // Create a pixelated cloud shape // Main cloud body (center) - ctx.beginPath(); - ctx.arc(cloudX, cloudY, cloudSize * 0.25, 0, Math.PI * 2); - ctx.fill(); + const centerSize = Math.floor(cloudSize * 0.25); + drawPixelSquare(cloudX, cloudY, centerSize); - // Surrounding smaller circles to create fluffy edges - for (let j = 0; j < circleCount; j++) { - // Calculate position around the main circle - const angle = (j / circleCount) * Math.PI * 2; - const distance = cloudSize * 0.4; // Distance from center + // Create a pixelated cloud pattern with squares + // Use fixed positions based on cloud index instead of random values + const squareCount = 24; // More squares for more detail + + for (let j = 0; j < squareCount; j++) { + // Use deterministic values based on j and seed + const angle = (j / squareCount) * Math.PI * 2; + const distance = cloudSize * 0.4; const offsetX = Math.cos(angle) * distance; const offsetY = Math.sin(angle) * distance * 0.6; // Flatten vertically - // Vary the size of each circle - const circleSize = cloudSize * (0.15 + Math.random() * 0.1); + // Size is deterministic based on position in the cloud + const squareSize = Math.floor(cloudSize * (0.15 + (((j * seed) % 100) / 1000))); - ctx.beginPath(); - ctx.arc(cloudX + offsetX, cloudY + offsetY, circleSize, 0, Math.PI * 2); - ctx.fill(); + drawPixelSquare(cloudX + offsetX, cloudY + offsetY, squareSize); } - // Add some random smaller circles for extra fluffiness - for (let j = 0; j < 8; j++) { - const offsetX = (Math.random() - 0.5) * cloudSize * 1.2; - const offsetY = (Math.random() - 0.5) * cloudSize * 0.6; - const circleSize = cloudSize * (0.1 + Math.random() * 0.1); + // Add some additional squares for extra fluffiness + for (let j = 0; j < 12; j++) { + // Use deterministic offsets based on j and seed + const offsetX = ((((j * seed) % 200) / 100) - 1) * cloudSize * 0.8; + const offsetY = ((((j * seed + 50) % 200) / 100) - 1) * cloudSize * 0.4; + const squareSize = Math.floor(cloudSize * (0.1 + (((j * seed + 100) % 100) / 1000))); - ctx.beginPath(); - ctx.arc(cloudX + offsetX, cloudY + offsetY, circleSize, 0, Math.PI * 2); - ctx.fill(); + drawPixelSquare(cloudX + offsetX, cloudY + offsetY, squareSize); } } + // Helper function to draw a pixelated square + function drawPixelSquare(x, y, size) { + // Round to nearest pixel to avoid sub-pixel rendering + const pixelX = Math.round(x); + const pixelY = Math.round(y); + const pixelSize = Math.max(1, Math.round(size)); + + ctx.fillRect( + pixelX - Math.floor(pixelSize/2), + pixelY - Math.floor(pixelSize/2), + pixelSize, + pixelSize + ); + } + // 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)');