about summary refs log tree commit diff stats
path: root/html/rogue/js/rogue.js
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 /html/rogue/js/rogue.js
parentc3951059c3730204735dcb6717fbebcb3a10bff1 (diff)
downloadtour-bb977cc4e502e3d35f3c82e1fca1a3535fda5e19.tar.gz
*
Diffstat (limited to 'html/rogue/js/rogue.js')
-rw-r--r--html/rogue/js/rogue.js87
1 files changed, 55 insertions, 32 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