about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorelioat <elioat@tilde.institute>2024-12-24 15:48:54 -0500
committerelioat <elioat@tilde.institute>2024-12-24 15:48:54 -0500
commitbb977cc4e502e3d35f3c82e1fca1a3535fda5e19 (patch)
tree306a2f837e495329551532ab743be3c449014842
parentc3951059c3730204735dcb6717fbebcb3a10bff1 (diff)
downloadtour-bb977cc4e502e3d35f3c82e1fca1a3535fda5e19.tar.gz
*
-rw-r--r--html/rogue/js/rogue.js87
-rw-r--r--html/rogue/js/world.js567
2 files changed, 345 insertions, 309 deletions
diff --git a/html/rogue/js/rogue.js b/html/rogue/js/rogue.js
index 3e8b12e..b4379ea 100644
--- a/html/rogue/js/rogue.js
+++ b/html/rogue/js/rogue.js
@@ -29,10 +29,16 @@ const initGame = () => {
     // Make gameState globally accessible
     window.gameState = gameState;
 
-    // Add mouse move listener
+    // Throttle mouse move updates
+    let mouseMoveThrottle;
     canvas.addEventListener('mousemove', (e) => {
-        gameState.debug.mouseX = e.clientX + gameState.camera.x;
-        gameState.debug.mouseY = e.clientY + gameState.camera.y;
+        if (!mouseMoveThrottle) {
+            mouseMoveThrottle = setTimeout(() => {
+                gameState.debug.mouseX = e.clientX + gameState.camera.x;
+                gameState.debug.mouseY = e.clientY + gameState.camera.y;
+                mouseMoveThrottle = null;
+            }, 16); // ~60fps
+        }
     });
 
     // Add debug toggle listener
@@ -74,44 +80,61 @@ const updateGame = (state, deltaTime) => {
 };
 
 const render = (ctx, state) => {
-    // Create gradient for sky
+    // Calculate groundY once at the start
     const groundY = ctx.canvas.height - state.world.groundHeight;
-    const skyGradient = ctx.createLinearGradient(0, 0, 0, groundY);
-    
-    // Twilight colors from top to bottom
-    skyGradient.addColorStop(0, '#1a1a2e');    // Deep blue at top
-    skyGradient.addColorStop(0.4, '#2d1b3d');  // Dark purple
-    skyGradient.addColorStop(0.7, '#462639');  // Purple-red
-    skyGradient.addColorStop(1, '#1f1f2f');    // Dark blue-grey near ground
-
-    // Fill sky
-    ctx.fillStyle = skyGradient;
+
+    // Create gradient for sky - cache this instead of recreating every frame
+    if (!state.cachedGradient) {
+        const gradient = ctx.createLinearGradient(0, 0, 0, groundY);
+        gradient.addColorStop(0, '#1a1a2e');
+        gradient.addColorStop(0.4, '#2d1b3d');
+        gradient.addColorStop(0.7, '#462639');
+        gradient.addColorStop(1, '#1f1f2f');
+        state.cachedGradient = gradient;
+    }
+
+    // Fill sky using cached gradient
+    ctx.fillStyle = state.cachedGradient;
     ctx.fillRect(0, 0, ctx.canvas.width, groundY);
+    
+    // Implement view frustum culling - only render visible objects
+    const viewBounds = {
+        left: state.camera.x - 100, // Add small buffer
+        right: state.camera.x + state.camera.width + 100,
+        top: state.camera.y - 100,
+        bottom: state.camera.y + state.camera.height + 100
+    };
 
     // Apply camera transform
     ctx.save();
     ctx.translate(-state.camera.x, -state.camera.y);
 
-    // Fill everything below ground with black (after camera transform)
+    // Fill black background
     ctx.fillStyle = '#000000';
     ctx.fillRect(
-        state.camera.x - 1000, // Extend well beyond viewport
+        viewBounds.left,
         groundY,
-        ctx.canvas.width + 2000, // Make sure it covers everything
+        viewBounds.right - viewBounds.left,
         ctx.canvas.height
     );
 
-    // 1. Render background objects
+    // 1. Render only visible background objects
     state.world.backgroundTrees.forEach(tree => {
-        renderTree(ctx, tree, groundY);
+        if (tree.x > viewBounds.left && tree.x < viewBounds.right) {
+            renderTree(ctx, tree, groundY);
+        }
     });
     
     state.world.backgroundRocks.forEach(rock => {
-        renderRock(ctx, rock, groundY);
+        if (rock.x > viewBounds.left && rock.x < viewBounds.right) {
+            renderRock(ctx, rock, groundY);
+        }
     });
 
     state.world.backgroundGrass.forEach(grass => {
-        renderGrass(ctx, grass, groundY, state.time);
+        if (grass.x > viewBounds.left && grass.x < viewBounds.right) {
+            renderGrass(ctx, grass, groundY, state.time);
+        }
     });
     
     // 2. Render platforms
@@ -125,15 +148,21 @@ const render = (ctx, state) => {
 
     // 4. Render foreground objects
     state.world.foregroundTrees.forEach(tree => {
-        renderTree(ctx, tree, groundY);
+        if (tree.x > viewBounds.left && tree.x < viewBounds.right) {
+            renderTree(ctx, tree, groundY);
+        }
     });
     
     state.world.foregroundRocks.forEach(rock => {
-        renderRock(ctx, rock, groundY);
+        if (rock.x > viewBounds.left && rock.x < viewBounds.right) {
+            renderRock(ctx, rock, groundY);
+        }
     });
 
     state.world.foregroundGrass.forEach(grass => {
-        renderGrass(ctx, grass, groundY, state.time);
+        if (grass.x > viewBounds.left && grass.x < viewBounds.right) {
+            renderGrass(ctx, grass, groundY, state.time);
+        }
     });
 
     // 5. Render ground (just the grass top)
@@ -147,20 +176,14 @@ const render = (ctx, state) => {
 
     // Render debug information if enabled
     if (state.debug.enabled) {
-        ctx.restore(); // Restore the original transform for screen-space rendering
-        
-        // Set up debug text style
+        ctx.restore();
         ctx.fillStyle = '#ffffff';
         ctx.font = '14px monospace';
-        
-        // Display coordinates
         const text = `x: ${Math.round(state.debug.mouseX)}, y: ${Math.round(state.debug.mouseY)}`;
         ctx.fillText(text, 10, ctx.canvas.height - 20);
     } else {
-        ctx.restore(); // Make sure we still restore even when debug is disabled
+        ctx.restore();
     }
-
-    ctx.restore();
 };
 
 // Initialize the game when the window loads
diff --git a/html/rogue/js/world.js b/html/rogue/js/world.js
index c416c91..ec6b5e8 100644
--- a/html/rogue/js/world.js
+++ b/html/rogue/js/world.js
@@ -131,284 +131,297 @@ const GRASS_TYPES = {
 };
 
 // Create a world with platforms, trees, and rocks
-const createWorld = () => ({
-    groundHeight: 12,
-    // Separate arrays for different layers
-    backgroundTrees: [
-        // Far left trees
-        {
-            type: WORLD_OBJECTS.FIR_BACKGROUND,
-            x: -1500,
-            config: FIR_TYPES.LARGE
-        },
-        {
-            type: WORLD_OBJECTS.MAPLE_BACKGROUND,
-            x: -1200,
-            config: MAPLE_TYPES.SMALL
-        },
-        {
-            type: WORLD_OBJECTS.FIR_BACKGROUND,
-            x: -900,
-            config: FIR_TYPES.SMALL
-        },
-        // Existing trees
-        {
-            type: WORLD_OBJECTS.FIR_BACKGROUND,
-            x: -400,
-            config: FIR_TYPES.LARGE
-        },
-        {
-            type: WORLD_OBJECTS.MAPLE_BACKGROUND,
-            x: -250,
-            config: MAPLE_TYPES.SMALL
-        },
-        {
-            type: WORLD_OBJECTS.FIR_BACKGROUND,
-            x: 50,
-            config: FIR_TYPES.LARGE
-        },
-        {
-            type: WORLD_OBJECTS.MAPLE_BACKGROUND,
-            x: 250,
-            config: MAPLE_TYPES.LARGE
-        },
-        {
-            type: WORLD_OBJECTS.FIR_BACKGROUND,
-            x: 500,
-            config: FIR_TYPES.SMALL
-        },
-        {
-            type: WORLD_OBJECTS.MAPLE_BACKGROUND,
-            x: 650,
-            config: MAPLE_TYPES.SMALL
-        },
-        {
-            type: WORLD_OBJECTS.FIR_BACKGROUND,
-            x: 900,
-            config: FIR_TYPES.LARGE
-        },
-        {
-            type: WORLD_OBJECTS.MAPLE_BACKGROUND,
-            x: 1100,
-            config: MAPLE_TYPES.LARGE
-        },
-        // Far right trees
-        {
-            type: WORLD_OBJECTS.MAPLE_BACKGROUND,
-            x: 1400,
-            config: MAPLE_TYPES.LARGE
-        },
-        {
-            type: WORLD_OBJECTS.FIR_BACKGROUND,
-            x: 1700,
-            config: FIR_TYPES.SMALL
-        },
-        {
-            type: WORLD_OBJECTS.MAPLE_BACKGROUND,
-            x: 2000,
-            config: MAPLE_TYPES.LARGE
-        }
-    ],
-    backgroundRocks: [
-        // Far left rocks
-        {
-            type: WORLD_OBJECTS.ROCK_BACKGROUND,
-            x: -1300,
-            config: ROCK_TYPES.LARGE
-        },
-        {
-            type: WORLD_OBJECTS.ROCK_BACKGROUND,
-            x: -1000,
-            config: ROCK_TYPES.SMALL
-        },
-        {
-            type: WORLD_OBJECTS.ROCK_BACKGROUND,
-            x: -300,
-            config: ROCK_TYPES.MEDIUM
-        },
-        {
-            type: WORLD_OBJECTS.ROCK_BACKGROUND,
-            x: -100,
-            config: ROCK_TYPES.SMALL
-        },
-        {
-            type: WORLD_OBJECTS.ROCK_BACKGROUND,
-            x: 150,
-            config: ROCK_TYPES.LARGE
-        },
-        {
-            type: WORLD_OBJECTS.ROCK_BACKGROUND,
-            x: 400,
-            config: ROCK_TYPES.SMALL
-        },
-        {
-            type: WORLD_OBJECTS.ROCK_BACKGROUND,
-            x: 750,
-            config: ROCK_TYPES.MEDIUM
-        },
-        {
-            type: WORLD_OBJECTS.ROCK_BACKGROUND,
-            x: 1000,
-            config: ROCK_TYPES.SMALL
-        },
-        // Far right rocks
-        {
-            type: WORLD_OBJECTS.ROCK_BACKGROUND,
-            x: 1600,
-            config: ROCK_TYPES.MEDIUM
-        },
-        {
-            type: WORLD_OBJECTS.ROCK_BACKGROUND,
-            x: 1900,
-            config: ROCK_TYPES.SMALL
-        }
-    ],
-    platforms: [
-        {
-            type: WORLD_OBJECTS.PLATFORM,
-            x: 300,
-            y: 300,
-            width: 200,
-            height: 20,
-            color: '#484'
-        },
-        {
-            type: WORLD_OBJECTS.PLATFORM,
-            x: 600,
-            y: 200,
-            width: 200,
-            height: 20,
-            color: '#484'
-        },
-        {
-            type: WORLD_OBJECTS.PLATFORM,
-            x: -200,
-            y: 250,
-            width: 200,
-            height: 20,
-            color: '#484'
-        }
-    ],
-    foregroundTrees: [
-        // Far left trees
-        {
-            type: WORLD_OBJECTS.FIR_FOREGROUND,
-            x: -1400,
-            config: FIR_TYPES.LARGE
-        },
-        {
-            type: WORLD_OBJECTS.MAPLE_FOREGROUND,
-            x: -1100,
-            config: MAPLE_TYPES.SMALL
-        },
-        // Existing trees
-        {
-            type: WORLD_OBJECTS.MAPLE_FOREGROUND,
-            x: -150,
-            config: MAPLE_TYPES.SMALL
-        },
-        {
-            type: WORLD_OBJECTS.FIR_FOREGROUND,
-            x: 200,
-            config: FIR_TYPES.SMALL
-        },
-        {
-            type: WORLD_OBJECTS.MAPLE_FOREGROUND,
-            x: 450,
-            config: MAPLE_TYPES.LARGE
-        },
-        {
-            type: WORLD_OBJECTS.FIR_FOREGROUND,
-            x: 800,
-            config: FIR_TYPES.LARGE
-        },
-        {
-            type: WORLD_OBJECTS.MAPLE_FOREGROUND,
-            x: 1200,
-            config: MAPLE_TYPES.SMALL
-        },
-        // Far right trees
-        {
-            type: WORLD_OBJECTS.FIR_FOREGROUND,
-            x: 1500,
-            config: FIR_TYPES.LARGE
-        },
-        {
-            type: WORLD_OBJECTS.MAPLE_FOREGROUND,
-            x: 1800,
-            config: MAPLE_TYPES.SMALL
-        }
-    ],
-    foregroundRocks: [
-        // Far left rocks
-        {
-            type: WORLD_OBJECTS.ROCK_FOREGROUND,
-            x: -1000,
-            config: ROCK_TYPES.MEDIUM
-        },
-        {
-            type: WORLD_OBJECTS.ROCK_FOREGROUND,
-            x: 0,
-            config: ROCK_TYPES.SMALL
-        },
-        {
-            type: WORLD_OBJECTS.ROCK_FOREGROUND,
-            x: 300,
-            config: ROCK_TYPES.MEDIUM
-        },
-        {
-            type: WORLD_OBJECTS.ROCK_FOREGROUND,
-            x: 700,
-            config: ROCK_TYPES.SMALL
-        },
-        {
-            type: WORLD_OBJECTS.ROCK_FOREGROUND,
-            x: 950,
-            config: ROCK_TYPES.LARGE
-        },
-        // Far right rocks
-        {
-            type: WORLD_OBJECTS.ROCK_FOREGROUND,
-            x: 1500,
-            config: ROCK_TYPES.LARGE
+const createWorld = () => {
+    const world = {
+        groundHeight: 12,
+        // Separate arrays for different layers
+        backgroundTrees: [
+            // Far left trees
+            {
+                type: WORLD_OBJECTS.FIR_BACKGROUND,
+                x: -1500,
+                config: FIR_TYPES.LARGE
+            },
+            {
+                type: WORLD_OBJECTS.MAPLE_BACKGROUND,
+                x: -1200,
+                config: MAPLE_TYPES.SMALL
+            },
+            {
+                type: WORLD_OBJECTS.FIR_BACKGROUND,
+                x: -900,
+                config: FIR_TYPES.SMALL
+            },
+            // Existing trees
+            {
+                type: WORLD_OBJECTS.FIR_BACKGROUND,
+                x: -400,
+                config: FIR_TYPES.LARGE
+            },
+            {
+                type: WORLD_OBJECTS.MAPLE_BACKGROUND,
+                x: -250,
+                config: MAPLE_TYPES.SMALL
+            },
+            {
+                type: WORLD_OBJECTS.FIR_BACKGROUND,
+                x: 50,
+                config: FIR_TYPES.LARGE
+            },
+            {
+                type: WORLD_OBJECTS.MAPLE_BACKGROUND,
+                x: 250,
+                config: MAPLE_TYPES.LARGE
+            },
+            {
+                type: WORLD_OBJECTS.FIR_BACKGROUND,
+                x: 500,
+                config: FIR_TYPES.SMALL
+            },
+            {
+                type: WORLD_OBJECTS.MAPLE_BACKGROUND,
+                x: 650,
+                config: MAPLE_TYPES.SMALL
+            },
+            {
+                type: WORLD_OBJECTS.FIR_BACKGROUND,
+                x: 900,
+                config: FIR_TYPES.LARGE
+            },
+            {
+                type: WORLD_OBJECTS.MAPLE_BACKGROUND,
+                x: 1100,
+                config: MAPLE_TYPES.LARGE
+            },
+            // Far right trees
+            {
+                type: WORLD_OBJECTS.MAPLE_BACKGROUND,
+                x: 1400,
+                config: MAPLE_TYPES.LARGE
+            },
+            {
+                type: WORLD_OBJECTS.FIR_BACKGROUND,
+                x: 1700,
+                config: FIR_TYPES.SMALL
+            },
+            {
+                type: WORLD_OBJECTS.MAPLE_BACKGROUND,
+                x: 2000,
+                config: MAPLE_TYPES.LARGE
+            }
+        ],
+        backgroundRocks: [
+            // Far left rocks
+            {
+                type: WORLD_OBJECTS.ROCK_BACKGROUND,
+                x: -1300,
+                config: ROCK_TYPES.LARGE
+            },
+            {
+                type: WORLD_OBJECTS.ROCK_BACKGROUND,
+                x: -1000,
+                config: ROCK_TYPES.SMALL
+            },
+            {
+                type: WORLD_OBJECTS.ROCK_BACKGROUND,
+                x: -300,
+                config: ROCK_TYPES.MEDIUM
+            },
+            {
+                type: WORLD_OBJECTS.ROCK_BACKGROUND,
+                x: -100,
+                config: ROCK_TYPES.SMALL
+            },
+            {
+                type: WORLD_OBJECTS.ROCK_BACKGROUND,
+                x: 150,
+                config: ROCK_TYPES.LARGE
+            },
+            {
+                type: WORLD_OBJECTS.ROCK_BACKGROUND,
+                x: 400,
+                config: ROCK_TYPES.SMALL
+            },
+            {
+                type: WORLD_OBJECTS.ROCK_BACKGROUND,
+                x: 750,
+                config: ROCK_TYPES.MEDIUM
+            },
+            {
+                type: WORLD_OBJECTS.ROCK_BACKGROUND,
+                x: 1000,
+                config: ROCK_TYPES.SMALL
+            },
+            // Far right rocks
+            {
+                type: WORLD_OBJECTS.ROCK_BACKGROUND,
+                x: 1600,
+                config: ROCK_TYPES.MEDIUM
+            },
+            {
+                type: WORLD_OBJECTS.ROCK_BACKGROUND,
+                x: 1900,
+                config: ROCK_TYPES.SMALL
+            }
+        ],
+        platforms: [
+            {
+                type: WORLD_OBJECTS.PLATFORM,
+                x: 300,
+                y: 300,
+                width: 200,
+                height: 20,
+                color: '#484'
+            },
+            {
+                type: WORLD_OBJECTS.PLATFORM,
+                x: 600,
+                y: 200,
+                width: 200,
+                height: 20,
+                color: '#484'
+            },
+            {
+                type: WORLD_OBJECTS.PLATFORM,
+                x: -200,
+                y: 250,
+                width: 200,
+                height: 20,
+                color: '#484'
+            }
+        ],
+        foregroundTrees: [
+            // Far left trees
+            {
+                type: WORLD_OBJECTS.FIR_FOREGROUND,
+                x: -1400,
+                config: FIR_TYPES.LARGE
+            },
+            {
+                type: WORLD_OBJECTS.MAPLE_FOREGROUND,
+                x: -1100,
+                config: MAPLE_TYPES.SMALL
+            },
+            // Existing trees
+            {
+                type: WORLD_OBJECTS.MAPLE_FOREGROUND,
+                x: -150,
+                config: MAPLE_TYPES.SMALL
+            },
+            {
+                type: WORLD_OBJECTS.FIR_FOREGROUND,
+                x: 200,
+                config: FIR_TYPES.SMALL
+            },
+            {
+                type: WORLD_OBJECTS.MAPLE_FOREGROUND,
+                x: 450,
+                config: MAPLE_TYPES.LARGE
+            },
+            {
+                type: WORLD_OBJECTS.FIR_FOREGROUND,
+                x: 800,
+                config: FIR_TYPES.LARGE
+            },
+            {
+                type: WORLD_OBJECTS.MAPLE_FOREGROUND,
+                x: 1200,
+                config: MAPLE_TYPES.SMALL
+            },
+            // Far right trees
+            {
+                type: WORLD_OBJECTS.FIR_FOREGROUND,
+                x: 1500,
+                config: FIR_TYPES.LARGE
+            },
+            {
+                type: WORLD_OBJECTS.MAPLE_FOREGROUND,
+                x: 1800,
+                config: MAPLE_TYPES.SMALL
+            }
+        ],
+        foregroundRocks: [
+            // Far left rocks
+            {
+                type: WORLD_OBJECTS.ROCK_FOREGROUND,
+                x: -1000,
+                config: ROCK_TYPES.MEDIUM
+            },
+            {
+                type: WORLD_OBJECTS.ROCK_FOREGROUND,
+                x: 0,
+                config: ROCK_TYPES.SMALL
+            },
+            {
+                type: WORLD_OBJECTS.ROCK_FOREGROUND,
+                x: 300,
+                config: ROCK_TYPES.MEDIUM
+            },
+            {
+                type: WORLD_OBJECTS.ROCK_FOREGROUND,
+                x: 700,
+                config: ROCK_TYPES.SMALL
+            },
+            {
+                type: WORLD_OBJECTS.ROCK_FOREGROUND,
+                x: 950,
+                config: ROCK_TYPES.LARGE
+            },
+            // Far right rocks
+            {
+                type: WORLD_OBJECTS.ROCK_FOREGROUND,
+                x: 1500,
+                config: ROCK_TYPES.LARGE
+            }
+        ],
+        backgroundGrass: [
+            // Far left grass
+            { type: WORLD_OBJECTS.GRASS_BACKGROUND, x: -1400, config: GRASS_TYPES.BLUE_TALL },
+            { type: WORLD_OBJECTS.GRASS_BACKGROUND, x: -1100, config: GRASS_TYPES.GOLDEN_SHORT },
+            { type: WORLD_OBJECTS.GRASS_BACKGROUND, x: -950, config: GRASS_TYPES.TALL },
+            { type: WORLD_OBJECTS.GRASS_BACKGROUND, x: -350, config: GRASS_TYPES.SHORT },
+            { type: WORLD_OBJECTS.GRASS_BACKGROUND, x: -180, config: GRASS_TYPES.GOLDEN_TALL },
+            { type: WORLD_OBJECTS.GRASS_BACKGROUND, x: 100, config: GRASS_TYPES.TALL },
+            { type: WORLD_OBJECTS.GRASS_BACKGROUND, x: 320, config: GRASS_TYPES.BLUE_SHORT },
+            { type: WORLD_OBJECTS.GRASS_BACKGROUND, x: 580, config: GRASS_TYPES.GOLDEN_SHORT },
+            { type: WORLD_OBJECTS.GRASS_BACKGROUND, x: 750, config: GRASS_TYPES.BLUE_TALL },
+            { type: WORLD_OBJECTS.GRASS_BACKGROUND, x: 950, config: GRASS_TYPES.TALL },
+            { type: WORLD_OBJECTS.GRASS_BACKGROUND, x: 1050, config: GRASS_TYPES.GOLDEN_TALL },
+            // Far right grass
+            { type: WORLD_OBJECTS.GRASS_BACKGROUND, x: 1500, config: GRASS_TYPES.BLUE_SHORT },
+            { type: WORLD_OBJECTS.GRASS_BACKGROUND, x: 1750, config: GRASS_TYPES.GOLDEN_TALL },
+            { type: WORLD_OBJECTS.GRASS_BACKGROUND, x: 1850, config: GRASS_TYPES.SHORT }
+        ],
+        foregroundGrass: [
+            // Far left grass
+            { type: WORLD_OBJECTS.GRASS_FOREGROUND, x: -1250, config: GRASS_TYPES.TALL },
+            { type: WORLD_OBJECTS.GRASS_FOREGROUND, x: -1050, config: GRASS_TYPES.BLUE_SHORT },
+            { type: WORLD_OBJECTS.GRASS_FOREGROUND, x: -280, config: GRASS_TYPES.BLUE_TALL },
+            { type: WORLD_OBJECTS.GRASS_FOREGROUND, x: -50, config: GRASS_TYPES.GOLDEN_SHORT },
+            { type: WORLD_OBJECTS.GRASS_FOREGROUND, x: 150, config: GRASS_TYPES.TALL },
+            { type: WORLD_OBJECTS.GRASS_FOREGROUND, x: 420, config: GRASS_TYPES.BLUE_SHORT },
+            { type: WORLD_OBJECTS.GRASS_FOREGROUND, x: 680, config: GRASS_TYPES.GOLDEN_TALL },
+            { type: WORLD_OBJECTS.GRASS_FOREGROUND, x: 880, config: GRASS_TYPES.SHORT },
+            { type: WORLD_OBJECTS.GRASS_FOREGROUND, x: 1150, config: GRASS_TYPES.BLUE_TALL },
+            // Far right grass
+            { type: WORLD_OBJECTS.GRASS_FOREGROUND, x: 1650, config: GRASS_TYPES.GOLDEN_TALL },
+            { type: WORLD_OBJECTS.GRASS_FOREGROUND, x: 1850, config: GRASS_TYPES.BLUE_SHORT }
+        ],
+        // Track grass animation states
+        grassStates: {},
+        // Add methods for quick spatial lookups
+        getObjectsInView: function(bounds) {
+            return {
+                backgroundTrees: this.backgroundTrees.filter(tree => 
+                    tree.x > bounds.left && tree.x < bounds.right
+                ),
+                // ... similar for other object types
+            };
         }
-    ],
-    backgroundGrass: [
-        // Far left grass
-        { type: WORLD_OBJECTS.GRASS_BACKGROUND, x: -1400, config: GRASS_TYPES.BLUE_TALL },
-        { type: WORLD_OBJECTS.GRASS_BACKGROUND, x: -1100, config: GRASS_TYPES.GOLDEN_SHORT },
-        { type: WORLD_OBJECTS.GRASS_BACKGROUND, x: -950, config: GRASS_TYPES.TALL },
-        { type: WORLD_OBJECTS.GRASS_BACKGROUND, x: -350, config: GRASS_TYPES.SHORT },
-        { type: WORLD_OBJECTS.GRASS_BACKGROUND, x: -180, config: GRASS_TYPES.GOLDEN_TALL },
-        { type: WORLD_OBJECTS.GRASS_BACKGROUND, x: 100, config: GRASS_TYPES.TALL },
-        { type: WORLD_OBJECTS.GRASS_BACKGROUND, x: 320, config: GRASS_TYPES.BLUE_SHORT },
-        { type: WORLD_OBJECTS.GRASS_BACKGROUND, x: 580, config: GRASS_TYPES.GOLDEN_SHORT },
-        { type: WORLD_OBJECTS.GRASS_BACKGROUND, x: 750, config: GRASS_TYPES.BLUE_TALL },
-        { type: WORLD_OBJECTS.GRASS_BACKGROUND, x: 950, config: GRASS_TYPES.TALL },
-        { type: WORLD_OBJECTS.GRASS_BACKGROUND, x: 1050, config: GRASS_TYPES.GOLDEN_TALL },
-        // Far right grass
-        { type: WORLD_OBJECTS.GRASS_BACKGROUND, x: 1500, config: GRASS_TYPES.BLUE_SHORT },
-        { type: WORLD_OBJECTS.GRASS_BACKGROUND, x: 1750, config: GRASS_TYPES.GOLDEN_TALL },
-        { type: WORLD_OBJECTS.GRASS_BACKGROUND, x: 1850, config: GRASS_TYPES.SHORT }
-    ],
-    foregroundGrass: [
-        // Far left grass
-        { type: WORLD_OBJECTS.GRASS_FOREGROUND, x: -1250, config: GRASS_TYPES.TALL },
-        { type: WORLD_OBJECTS.GRASS_FOREGROUND, x: -1050, config: GRASS_TYPES.BLUE_SHORT },
-        { type: WORLD_OBJECTS.GRASS_FOREGROUND, x: -280, config: GRASS_TYPES.BLUE_TALL },
-        { type: WORLD_OBJECTS.GRASS_FOREGROUND, x: -50, config: GRASS_TYPES.GOLDEN_SHORT },
-        { type: WORLD_OBJECTS.GRASS_FOREGROUND, x: 150, config: GRASS_TYPES.TALL },
-        { type: WORLD_OBJECTS.GRASS_FOREGROUND, x: 420, config: GRASS_TYPES.BLUE_SHORT },
-        { type: WORLD_OBJECTS.GRASS_FOREGROUND, x: 680, config: GRASS_TYPES.GOLDEN_TALL },
-        { type: WORLD_OBJECTS.GRASS_FOREGROUND, x: 880, config: GRASS_TYPES.SHORT },
-        { type: WORLD_OBJECTS.GRASS_FOREGROUND, x: 1150, config: GRASS_TYPES.BLUE_TALL },
-        // Far right grass
-        { type: WORLD_OBJECTS.GRASS_FOREGROUND, x: 1650, config: GRASS_TYPES.GOLDEN_TALL },
-        { type: WORLD_OBJECTS.GRASS_FOREGROUND, x: 1850, config: GRASS_TYPES.BLUE_SHORT }
-    ],
-    // Track grass animation states
-    grassStates: {}
-});
+    };
+    
+    return world;
+};
 
 // Add seededRandom function
 const seededRandom = (x, y) => {