Drawaria Sky Sanctuary Zone

Professional recreation of Sky Sanctuary Zone with detailed elements

// ==UserScript==
// @name         Drawaria Sky Sanctuary Zone
// @namespace    http://tampermonkey.net/
// @version      3.0
// @description  Professional recreation of Sky Sanctuary Zone with detailed elements
// @author       YouTubeDrawaria
// @match        https://drawaria.online/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=drawaria.online
// @grant        none
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    function waitForCanvas() {
        if (document.querySelector('canvas')) {
            initSkySanctuary();
        } else {
            setTimeout(waitForCanvas, 1000);
        }
    }

    function initSkySanctuary() {
        const canvas = document.querySelector('canvas');
        const ctx = canvas.getContext('2d');

        const colors = {
            skyTop: '#4080c0',        // Darker, more realistic sky
            skyBottom: '#80b0e0',     // Lighter blue
            clouds: '#ffffff',
            cloudShadow: '#e0e0e0',   // Grayer shadow
            pillarLight: '#f0e68c',    // Khaki
            pillarMid: '#d4c4a8',     // Light Brown
            pillarShade: '#a08060',    // Darker Brown
            pillarDark: '#604020',    // Very Dark Brown
            grass: '#30a040',         // Darker, richer green
            grassShade: '#208030',    // Even darker green
            stone: '#c0c0c0',        // Silver
            stoneDark: '#808080',     // Gray
            decorGold: '#ffd700',
            ruins: '#b0a080',        // More muted ruins
            vineGreen: '#2e8b57',     // Sea Green
            vineDark: '#196127',      // Darker Sea Green
            castleLight: 'rgba(200, 190, 170, 0.4)',  // Slightly more opaque
            castleDark: 'rgba(150, 140, 120, 0.3)',   // Darker and more opaque
            leaves: '#388e3c',       // Darker Green
            flowerGold: '#ffd700',
            flowerWhite: '#ffffff',
            particle: 'rgba(255, 255, 255, 0.6)' // White with some opacity
        };

        // Utility function for creating gradients
        function createVerticalGradient(ctx, topColor, bottomColor, startY, endY) {
            const gradient = ctx.createLinearGradient(0, startY, 0, endY);
            gradient.addColorStop(0, topColor);
            gradient.addColorStop(1, bottomColor);
            return gradient;
        }



        class ParallaxElement {
            constructor(x, y, speed, depth) {
                this.x = x;
                this.y = y;
                this.speed = speed;
                this.depth = depth;
                this.originalX = x;  // Store original X for resetting
                this.originalY = y;  // Store original Y for parallax relative to the canvas bottom.
            }

            update(deltaTime, cameraX = 0) {
                // Parallax scrolling.
                this.x = this.originalX - cameraX * this.depth;

                // Wrap around when going off-screen.
                if (this.x + 1000 < cameraX * this.depth ) {
                    this.x = this.originalX + canvas.width;  // Reset at the far right.
                    this.originalX = this.x;  // *Important*: Update originalX
                }
            }

            reset() {
              this.x = this.originalX;
              this.y = this.originalY;
            }
        }



        class DetailedPillar extends ParallaxElement {
            constructor(x, y, width, height, depth) {
                super(x, y, 0.04, depth); // Increased speed slightly
                this.width = width;
                this.height = height;
                this.decorations = this.generateDecorations();
                this.cracks = this.generateCracks(); // Add cracks
            }

            generateDecorations() {
                const decorations = [];
                const numDecorations = Math.floor(5 + Math.random() * 5); // More decorations
                for (let i = 0; i < numDecorations; i++) {
                    decorations.push({
                        x: Math.random() * this.width,
                        y: Math.random() * this.height,
                        size: 7 + Math.random() * 8, // Slightly larger sizes
                        type: Math.random() < 0.7 ? 'circle' : 'square' // Different shapes
                    });
                }
                return decorations;
            }

            generateCracks() {
                const cracks = [];
                const numCracks = Math.floor(2 + Math.random() * 4); // Add a few cracks
                for (let i = 0; i < numCracks; i++) {
                    cracks.push({
                        startX: this.width * (0.2 + Math.random() * 0.6), // Random within pillar
                        startY: this.height * (0.1 + Math.random() * 0.8),
                        length: 20 + Math.random() * 40,
                        angle: (Math.random() - 0.5) * Math.PI / 4 // +/- 45 degrees
                    });
                }
                return cracks;
            }

            draw(ctx) {
                const perspective = 0.4 * this.depth; // Increased perspective
                const topWidth = this.width * (1 - perspective);

                this.drawPillarBody(ctx, topWidth);
                this.drawPillarDetails(ctx, topWidth);
                this.drawDecorations(ctx);
                this.drawCracks(ctx); // Draw cracks
                this.drawCapital(ctx, topWidth);
            }


            drawPillarBody(ctx, topWidth) {
              //  console.log(`Pillar: x=${this.x}, y=${this.y}, width=${this.width}, height=${this.height}`);
                ctx.beginPath();
                ctx.moveTo(this.x, this.y); // Start from the top-left
                ctx.lineTo(this.x + this.width, this.y); // Top-right
                ctx.lineTo(this.x + this.width/2 + topWidth/2, this.y - this.height); // Top perspective point
                ctx.lineTo(this.x + this.width/2 - topWidth/2, this.y- this.height); // Bottom perspective point
                ctx.closePath();


                const gradient = ctx.createLinearGradient(this.x, this.y - this.height, this.x, this.y);
                gradient.addColorStop(0, colors.pillarLight); // Lighter at the top
                gradient.addColorStop(0.5, colors.pillarMid);
                gradient.addColorStop(1, colors.pillarShade); // Darker at the bottom
                ctx.fillStyle = gradient;
                ctx.globalAlpha = 0.8; // Slightly more opaque
                ctx.fill();
                ctx.globalAlpha = 1;

                // Add shadow
                ctx.fillStyle = 'rgba(0, 0, 0, 0.2)'; // Dark, semi-transparent shadow
                ctx.beginPath();
                ctx.moveTo(this.x + this.width, this.y);
                ctx.lineTo(this.x + this.width * 1.1, this.y - 20); // Shadow extends slightly
                ctx.lineTo(this.x + this.width/2 + topWidth/2 + 20, this.y - this.height - 10);
                ctx.lineTo(this.x + this.width/2 + topWidth/2, this.y - this.height);
                ctx.closePath();
                ctx.fill();
            }

            drawPillarDetails(ctx, topWidth) {
                for (let i = 0.2; i <= 0.8; i += 0.2) {
                    ctx.fillStyle = colors.pillarShade;
                    ctx.beginPath();
                    ctx.moveTo(this.x + this.width * i, this.y);
                    ctx.lineTo(this.x + this.width * (i + 0.05), this.y);
                    ctx.lineTo(this.x + this.width/2 + topWidth * (i - 0.5) + topWidth * 0.025, this.y-this.height);
                    ctx.lineTo(this.x + this.width/2 + topWidth * (i - 0.5), this.y-this.height);
                    ctx.closePath();
                    ctx.fill();
                }
            }

            drawDecorations(ctx) {

                this.decorations.forEach(dec => {
                    ctx.fillStyle = colors.decorGold;
                    if (dec.type === 'circle') {
                        ctx.beginPath();
                        ctx.arc(this.x + dec.x, this.y - this.height + dec.y, dec.size, 0, Math.PI * 2);
                        ctx.fill();
                    } else { // Square
                        ctx.fillRect(this.x + dec.x - dec.size / 2, this.y - this.height + dec.y - dec.size / 2, dec.size, dec.size);
                    }
                });
            }


            drawCracks(ctx) {
                ctx.strokeStyle = colors.pillarDark;
                ctx.lineWidth = 2;
                this.cracks.forEach(crack => {
                    ctx.beginPath();
                    ctx.moveTo(this.x + crack.startX, this.y - this.height + crack.startY);
                    ctx.lineTo(this.x + crack.startX + Math.cos(crack.angle) * crack.length,
                               this.y - this.height + crack.startY + Math.sin(crack.angle) * crack.length);
                    ctx.stroke();
                });
            }

            drawCapital(ctx, topWidth) {
                const capitalHeight = this.height * 0.15; // Larger capital
                ctx.fillStyle = colors.stone;

                ctx.beginPath();
                ctx.moveTo(this.x - this.width * 0.3, this.y - this.height); // Wider
                ctx.lineTo(this.x + this.width * 1.3, this.y - this.height); // Wider
                ctx.lineTo(this.x + this.width / 2 + topWidth *1.2, this.y - this.height - capitalHeight);
                ctx.lineTo(this.x + this.width / 2 - topWidth*1.2, this.y - this.height - capitalHeight);
                ctx.closePath();
                ctx.fill();

                // Add detailed carvings to the capital
                ctx.fillStyle = colors.decorGold;
                for (let i = 0; i < 7; i++) { // More carvings
                    const carvingX = this.x + this.width * (-0.2 + i * 0.2);
                    const carvingY = this.y - this.height - capitalHeight / 2;
                    ctx.beginPath();

                    if(i % 2 === 0){
                        ctx.arc(carvingX, carvingY, capitalHeight / 5, 0, Math.PI * 2);
                    } else {
                        ctx.moveTo(carvingX - capitalHeight/6, carvingY);
                        ctx.lineTo(carvingX, carvingY - capitalHeight/4);
                        ctx.lineTo(carvingX + capitalHeight/6, carvingY);
                        ctx.closePath();

                    }
                    ctx.fill();
                }
            }
        }



        class Cloud extends ParallaxElement {
            constructor(x, y, size, depth) {
                super(x, y, 0.015, depth); // Slightly faster clouds
                this.size = size;
                this.segments = this.generateSegments();
            }

            generateSegments() {
                const segments = [];
                const numSegments = Math.floor(4 + Math.random() * 3); // Varying number of segments
                for (let i = 0; i < numSegments; i++) {
                    segments.push({
                        xOffset: (Math.random() - 0.5) * this.size * 2.5, // Wider spread
                        yOffset: (Math.random() - 0.5) * this.size * 1.5, // More vertical variation
                        size: this.size * (0.6 + Math.random() * 0.4) // Slightly larger segments
                    });
                }
                return segments;
            }

            draw(ctx) {
                // Shadow first (darker and offset)
                ctx.fillStyle = colors.cloudShadow;
                this.segments.forEach(seg => {
                    ctx.beginPath();
                    ctx.arc(this.x + seg.xOffset + 10, this.y + seg.yOffset + 15, // Shadow offset
                           seg.size * 1.1, 0, Math.PI * 2); // Slightly larger shadow
                    ctx.fill();
                });

                // Then the cloud itself
                ctx.fillStyle = colors.clouds;
                this.segments.forEach(seg => {
                    ctx.beginPath();
                    ctx.arc(this.x + seg.xOffset, this.y + seg.yOffset,
                           seg.size, 0, Math.PI * 2);
                    ctx.fill();
                });
            }
        }


       class BackgroundCastle extends ParallaxElement {
          constructor(x, y, width, height, depth) {
            super(x, y, 0.008, depth);  //Slightly increased speed
            this.width = width;
            this.height = height;
            this.towers = this.generateTowers(); // Generate towers
            this.windows = this.generateWindows();  // Generate windows
          }
          generateTowers() {
            const towers = [];
            const numTowers = Math.floor(4 + Math.random() * 3); // 4-6 towers
            for (let i = 0; i < numTowers; i++) {
              towers.push({
                x: this.width * (0.1 + i * 0.2 + (Math.random() - 0.5) * 0.1), // Some x variation
                height: this.height * (0.4 + Math.random() * 0.3), // Varying heights
                width: 20 + Math.random() * 20, // Varying widths
                roofType: Math.random() < 0.6 ? 'pointed' : 'flat' // Different roof types
              });
            }
              return towers;
          }

           generateWindows(){
              const windows = [];
              const numWindows = Math.floor(10 + Math.random() * 15);
               for(let i = 0; i < numWindows; i++){
                  windows.push({
                    x: this.width * Math.random(),
                    y: this.height * (0.2 + Math.random() * 0.6),
                    size: 4 + Math.random() * 4
                  });
               }
             return windows;
           }

          draw(ctx) {

            this.drawMainStructure(ctx);
            this.drawTowers(ctx);
            this.drawDetails(ctx);
            this.drawWindows(ctx);
          }


            drawMainStructure(ctx) {
              ctx.fillStyle = colors.castleLight;
              ctx.beginPath();
              ctx.moveTo(this.x, this.y);
              ctx.lineTo(this.x + this.width, this.y);
              ctx.lineTo(this.x + this.width, this.y - this.height * 0.7); // Increased height
              ctx.lineTo(this.x + this.width * 0.8, this.y - this.height * 0.8);
              ctx.lineTo(this.x + this.width * 0.6, this.y - this.height);  //Main point
              ctx.lineTo(this.x + this.width * 0.4, this.y - this.height * 0.9);
              ctx.lineTo(this.x + this.width * 0.2, this.y - this.height * 0.8);
              ctx.lineTo(this.x, this.y - this.height * 0.7);
              ctx.closePath();
              ctx.fill();


              // Add a subtle gradient for depth
              const gradient = ctx.createLinearGradient(this.x, this.y - this.height, this.x, this.y);
              gradient.addColorStop(0, 'rgba(255, 255, 255, 0.2)'); // Lighter at the top
              gradient.addColorStop(1, 'rgba(0, 0, 0, 0.1)');    // Darker at the bottom
              ctx.fillStyle = gradient;
              ctx.fill();
          }

          drawTowers(ctx) {
                ctx.fillStyle = colors.castleLight;
                this.towers.forEach(tower => {
                const towerX = this.x + tower.x;
                ctx.beginPath();
                ctx.moveTo(towerX, this.y);
                ctx.lineTo(towerX + tower.width, this.y);
                ctx.lineTo(towerX + tower.width, this.y - tower.height);
                if (tower.roofType === 'pointed') {
                    ctx.lineTo(towerX + tower.width / 2, this.y - tower.height * 1.2); // Pointed roof
                    ctx.lineTo(towerX, this.y - tower.height);
                } else {
                    ctx.lineTo(towerX, this.y - tower.height); // Flat roof
                    // Add battlements for flat roofs
                    for (let i = 0; i < tower.width; i += 10) {
                        ctx.fillRect(towerX + i, this.y - tower.height - 5, 5, 5);
                    }
                }

                ctx.closePath();
                ctx.fill();
            });
          }

          drawDetails(ctx) {
            ctx.fillStyle = colors.castleDark;
            for (let i = 0; i < this.width; i += 40) { // More details
              ctx.fillRect(this.x + i, this.y - this.height * 0.4, 30, this.height * 0.3);
            }
          }

           drawWindows(ctx){
              ctx.fillStyle = 'rgba(255, 255, 0, 0.4)'; // Yellowish glow
              this.windows.forEach(window => {
                  ctx.fillRect(this.x + window.x, this.y - window.y, window.size, window.size);
              });
           }
        }

        class Vegetation {
            constructor(x, y, type) {
                this.x = x;
                this.y = y;
                this.type = type;
                this.swayOffset = Math.random() * Math.PI * 2;
                this.leafDetails = this.generateLeafDetails(); // For vines
            }

            generateLeafDetails() {
                if (this.type !== 'vine') return [];
                return Array(5).fill().map(() => ({
                    offset: Math.random() * 20 - 10, // x offset for each leaf
                    size: 4 + Math.random() * 4 // Leaf size variation
                }));
            }

            draw(ctx, time) {
                switch(this.type) {
                    case 'vine':
                        this.drawVine(ctx, time);
                        break;
                    case 'flower':
                        this.drawFlower(ctx);
                        break;
                    case 'bush':
                        this.drawBush(ctx);
                        break;
                }
            }

            drawVine(ctx, time) {
                const sway = Math.sin(time * 0.0015 + this.swayOffset) * 8; // Increased sway
                ctx.strokeStyle = colors.vineGreen;
                ctx.lineWidth = 3;
                ctx.beginPath();
                ctx.moveTo(this.x, this.y);

                // More realistic vine curves
                for (let i = 0; i < 5; i++) {
                    const curveX = this.x + sway * (i % 2 ? 1.2 : -0.8); // More variation in sway
                    const curveY = this.y - i * 25; // Taller vines
                    ctx.quadraticCurveTo(
                        curveX, curveY,
                        this.x + sway * (i % 2 ? 0.5 : -0.3), this.y - (i + 1) * 25 // Vary next point
                    );
                }
                ctx.stroke();


                // Leaves with more detail
                 for (let i = 1; i < 5; i++) {
                    ctx.fillStyle = colors.leaves;
                    const leafX = this.x + sway * (i % 2 ? 1 : -1) + this.leafDetails[i-1].offset;
                    const leafY = this.y - i * 25;

                    ctx.beginPath();
                    ctx.ellipse(leafX, leafY,
                                8, this.leafDetails[i-1].size * 2, // Use generated size
                                Math.PI / 4 * (i % 2 ? 1 : -1), 0, Math.PI * 2);
                    ctx.fill();

                    // Add a small line for leaf vein
                    ctx.strokeStyle = colors.vineDark;
                    ctx.lineWidth = 1;
                    ctx.beginPath();
                    ctx.moveTo(leafX, leafY);
                    ctx.lineTo(leafX + 4 * (i % 2 ? 1 : -1), leafY - 4);
                    ctx.stroke();
                }
            }

            drawFlower(ctx) {
                // More detailed flower center
                ctx.fillStyle = colors.flowerGold;
                ctx.beginPath();
                ctx.arc(this.x, this.y, 6, 0, Math.PI * 2); // Larger center
                ctx.fill();

                // More detailed petals
                ctx.fillStyle = colors.flowerWhite;
                for (let i = 0; i < 8; i++) { // More petals
                    const angle = (i / 8) * Math.PI * 2; // Evenly spaced
                    ctx.beginPath();
                    ctx.ellipse(
                        this.x + Math.cos(angle) * 10, // Larger petals
                        this.y + Math.sin(angle) * 10,
                        8, 5, // More elongated petals
                        angle,
                        0, Math.PI * 2
                    );
                    ctx.fill();

                     // Add a small line for petal detail
                    ctx.strokeStyle = colors.vineDark;
                    ctx.lineWidth = 1;
                    ctx.beginPath();
                    ctx.moveTo(this.x + Math.cos(angle) * 10, this.y + Math.sin(angle) * 10);
                    ctx.lineTo(this.x + Math.cos(angle) * 15, this.y + Math.sin(angle) * 15);
                    ctx.stroke();
                }
            }

            drawBush(ctx) {
                ctx.fillStyle = colors.grass;
                for (let i = 0; i < 7; i++) { // More bush segments
                    ctx.beginPath();
                    ctx.arc(
                        this.x + (i - 3) * 12, // Wider bush
                        this.y - Math.abs(i - 3) * 6, // Taller
                        12, // Larger segments
                        0, Math.PI * 2
                    );
                    ctx.fill();
                }

                // Add darker spots for depth
                ctx.fillStyle = colors.grassShade;
                for (let i = 0; i < 3; i++) {
                    ctx.beginPath();
                    ctx.arc(
                        this.x + (Math.random() - 0.5) * 30,
                        this.y - Math.random() * 10,
                        5 + Math.random() * 5, // Random size and position
                        0, Math.PI * 2
                    );
                    ctx.fill();
                }
            }
        }

        class Particle {
            constructor(x, y, size, speed, depth) {
                this.x = x;
                this.y = y;
                this.size = size;
                this.speed = speed;
                this.depth = depth;
                this.alpha = 0.2 + Math.random() * 0.6;  // Random initial opacity.
            }

            update(deltaTime, cameraX) {
                this.x -= this.speed * deltaTime * this.depth;
                this.y += Math.sin(this.x * 0.01) * 0.5;  // Slight wavy movement.
                this.alpha -= 0.005 * deltaTime; // Fade out over time.

                if (this.x < cameraX - this.size || this.alpha <= 0) {
                    this.reset(cameraX);
                }
            }

            reset(cameraX) {
                this.x = cameraX + canvas.width + Math.random() * 200; // Reset beyond the right edge.
                this.y = Math.random() * canvas.height;
                this.size = 2 + Math.random() * 3;
                this.speed = 0.01 + Math.random() * 0.02;
                this.alpha = 0.2 + Math.random() * 0.6;
                this.depth = 0.5 + Math.random() * 0.8;
            }

            draw(ctx) {
              ctx.fillStyle = `rgba(255, 255, 255, ${this.alpha})`;  // Use dynamic alpha.
                ctx.beginPath();
                ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
                ctx.fill();
            }
        }



        const pillars = [];
        const clouds = [];
        const castles = [];
        const vegetation = [];
        const particles = [];
        let lastTime = 0;
        let cameraX = 0; // Camera position for parallax

        function initializeScene() {
           // Clear existing elements (important for reset)
            pillars.length = 0;
            clouds.length = 0;
            castles.length = 0;
            vegetation.length = 0;
            particles.length = 0;

            for (let i = 0; i < 8; i++) {
                const depth = 0.6 + Math.random() * 0.4; // Deeper pillars
                pillars.push(new DetailedPillar(
                    200 + i * 500,  // Wider spacing
                    canvas.height - 150, // Pillars anchored to a consistent y-position
                    150,          // Wider pillars
                    400 - depth * 50,
                    depth
                ));
            }

            for (let i = 0; i < 15; i++) { // More clouds
                const depth = 0.3 + Math.random() * 0.4; // Wider depth range
                clouds.push(new Cloud(
                    Math.random() * canvas.width,
                    50 + Math.random() * 250, // Taller cloud area
                    40 + Math.random() * 30, // Larger clouds
                    depth
                ));
            }

            for (let i = 0; i < 3; i++) {
              const depth = 0.2 + (i * 0.15); // Increased depth difference
              castles.push(new BackgroundCastle(
                300 + i * 1200, // Increased spacing
                canvas.height - 150,  // Consistent y-position for the castle base
                600,        // Much wider castles
                450,        // Taller castles
                depth
              ));
            }


            for (let i = 0; i < 40; i++) { // More vegetation
                vegetation.push(new Vegetation(
                    Math.random() * canvas.width,
                    canvas.height - 100 + Math.random() * 30, // Consistent y-range
                    ['vine', 'flower', 'bush'][Math.floor(Math.random() * 3)]
                ));
            }

            for (let i = 0; i < 50; i++) { // Add particles
                particles.push(new Particle(
                    Math.random() * canvas.width,
                    Math.random() * canvas.height,
                    2 + Math.random() * 3,
                    0.01 + Math.random() * 0.02,
                    0.5 + Math.random()* 0.8
                ));
            }
            // Reset camera
            cameraX = 0;
        }

       function drawBackground(ctx) {
            const gradient = createVerticalGradient(ctx, colors.skyTop, colors.skyBottom, 0, canvas.height);
            ctx.fillStyle = gradient;
            ctx.fillRect(0, 0, canvas.width, canvas.height);
        }

        function drawGround(ctx) {
            const platformHeight = 120; // Slightly taller
            const gradient = createVerticalGradient(ctx, colors.stone, colors.stoneDark, canvas.height - platformHeight, canvas.height);
            ctx.fillStyle = gradient;
            ctx.fillRect(0, canvas.height - platformHeight, canvas.width, platformHeight);

            // Ground details (more detailed and varied)
            for (let i = 0; i < canvas.width; i += 25) {
                ctx.fillStyle = colors.grass;
                ctx.beginPath();
                ctx.moveTo(i, canvas.height - platformHeight);
                ctx.lineTo(i + 15 + Math.random() * 10, canvas.height - platformHeight); // Varying widths
                ctx.lineTo(i + 7.5 + Math.random() * 5, canvas.height - platformHeight - (20 + Math.random() * 10)); // Varying heights
                ctx.closePath();
                ctx.fill();
            }

             // Add some cracks in the stone
            ctx.strokeStyle = colors.stoneDark;
            ctx.lineWidth = 2;
            for (let i = 0; i < canvas.width; i += 50 + Math.random() * 50) {
                ctx.beginPath();
                ctx.moveTo(i, canvas.height - platformHeight + 5);
                ctx.lineTo(i + (Math.random() - 0.5) * 20, canvas.height - platformHeight + 20 + Math.random() * 10);
                ctx.stroke();
            }
        }



        function drawScene(timestamp) {
            const deltaTime = timestamp - lastTime;
            lastTime = timestamp;

             // Camera movement (smooth)
            cameraX += deltaTime * 0.05;

            ctx.clearRect(0, 0, canvas.width, canvas.height);

            // Background and elements, with parallax
            drawBackground(ctx);

             castles.forEach(castle => {
                castle.update(deltaTime, cameraX);
                castle.draw(ctx);
            });

            clouds.forEach(cloud => {
                cloud.update(deltaTime, cameraX);
                cloud.draw(ctx);
            });


            pillars.sort((a, b) => b.depth - a.depth); // Depth sorting
            pillars.forEach(pillar => {
                pillar.update(deltaTime, cameraX);  // Pass cameraX for parallax.
                pillar.draw(ctx);
            });

             drawGround(ctx);

             vegetation.forEach(plant => {
                plant.x = plant.x - cameraX * 0.1;
                plant.draw(ctx, timestamp);
                plant.x = plant.x + cameraX * 0.1;
            });


            particles.forEach(particle => {
                particle.update(deltaTime, cameraX);
                particle.draw(ctx);
            });


            requestAnimationFrame(drawScene);
        }


        // UI controls
        function createControls() {
            const controlPanel = document.createElement('div');
            controlPanel.style.cssText = `
                position: fixed;
                top: 10px;
                right: 10px;
                z-index: 9999;
                background: rgba(0, 0, 0, 0.7);
                padding: 10px;
                border-radius: 5px;
                color: white;
                font-family: sans-serif;
            `;

            const startButton = document.createElement('button');
            startButton.textContent = 'Draw Sky Sanctuary';
            startButton.style.cssText = 'padding: 8px 12px; margin-right: 5px; cursor: pointer;';
            startButton.onclick = () => {
                initializeScene();
                requestAnimationFrame(drawScene);
            };

            const resetButton = document.createElement('button');
            resetButton.textContent = 'Reset Scene';
            resetButton.style.cssText = 'padding: 8px 12px; cursor: pointer;';
            resetButton.onclick = () => {
              ctx.clearRect(0, 0, canvas.width, canvas.height);
              initializeScene(); // Re-initialize, don't just clear arrays.
              requestAnimationFrame(drawScene); // start drawing again

            };



            controlPanel.appendChild(startButton);
            controlPanel.appendChild(resetButton);
            document.body.appendChild(controlPanel);
        }

        createControls();
    }

    waitForCanvas();
})();