diff options
-rw-r--r-- | html/rogue/js/rogue.js | 87 | ||||
-rw-r--r-- | html/rogue/js/world.js | 567 |
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) => { |