about summary refs log tree commit diff stats
path: root/html/rogue
diff options
context:
space:
mode:
authorelioat <elioat@tilde.institute>2024-12-24 14:43:49 -0500
committerelioat <elioat@tilde.institute>2024-12-24 14:43:49 -0500
commitb08a7074b84223fc92d3a24b7758cf222f3f97ef (patch)
tree0ff8f237828241443665f302c4a3b03e9bfccb09 /html/rogue
parent57929fc1a92493cee0de00a079fb22d003a348e3 (diff)
downloadtour-b08a7074b84223fc92d3a24b7758cf222f3f97ef.tar.gz
*
Diffstat (limited to 'html/rogue')
-rw-r--r--html/rogue/js/rogue.js8
-rw-r--r--html/rogue/js/world.js167
2 files changed, 172 insertions, 3 deletions
diff --git a/html/rogue/js/rogue.js b/html/rogue/js/rogue.js
index 8276d8d..f441bbd 100644
--- a/html/rogue/js/rogue.js
+++ b/html/rogue/js/rogue.js
@@ -72,6 +72,10 @@ const render = (ctx, state) => {
     state.world.backgroundRocks.forEach(rock => {
         renderRock(ctx, rock, ctx.canvas.height - state.world.groundHeight);
     });
+
+    state.world.backgroundGrass.forEach(grass => {
+        renderGrass(ctx, grass, ctx.canvas.height - state.world.groundHeight, state.time);
+    });
     
     // 2. Render platforms
     state.world.platforms.forEach(platform => {
@@ -91,6 +95,10 @@ const render = (ctx, state) => {
         renderRock(ctx, rock, ctx.canvas.height - state.world.groundHeight);
     });
 
+    state.world.foregroundGrass.forEach(grass => {
+        renderGrass(ctx, grass, ctx.canvas.height - state.world.groundHeight, state.time);
+    });
+
     // 5. Render ground
     const groundY = ctx.canvas.height - state.world.groundHeight;
     ctx.fillStyle = '#4a4';
diff --git a/html/rogue/js/world.js b/html/rogue/js/world.js
index 1a54853..ad25e9d 100644
--- a/html/rogue/js/world.js
+++ b/html/rogue/js/world.js
@@ -6,7 +6,9 @@ const WORLD_OBJECTS = {
     MAPLE_BACKGROUND: 'maple_background',
     MAPLE_FOREGROUND: 'maple_foreground',
     ROCK_BACKGROUND: 'rock_background',
-    ROCK_FOREGROUND: 'rock_foreground'
+    ROCK_FOREGROUND: 'rock_foreground',
+    GRASS_BACKGROUND: 'grass_background',
+    GRASS_FOREGROUND: 'grass_foreground'
 };
 
 // Separate configurations for different tree types
@@ -74,6 +76,26 @@ const ROCK_TYPES = {
     }
 };
 
+// Add grass configurations
+const GRASS_TYPES = {
+    TALL: {
+        type: 'grass',
+        width: 30,
+        height: 40,
+        blades: 5,
+        color: '#3a5',
+        shadowColor: '#294'
+    },
+    SHORT: {
+        type: 'grass',
+        width: 20,
+        height: 25,
+        blades: 4,
+        color: '#3b6',
+        shadowColor: '#2a5'
+    }
+};
+
 // Create a world with platforms, trees, and rocks
 const createWorld = () => ({
     groundHeight: 12,
@@ -81,6 +103,16 @@ const createWorld = () => ({
     backgroundTrees: [
         {
             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
         },
@@ -98,11 +130,31 @@ const createWorld = () => ({
             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
         }
     ],
     backgroundRocks: [
         {
             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
         },
@@ -110,6 +162,16 @@ const createWorld = () => ({
             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
         }
     ],
     platforms: [
@@ -141,18 +203,38 @@ const createWorld = () => ({
     foregroundTrees: [
         {
             type: WORLD_OBJECTS.MAPLE_FOREGROUND,
-            x: 200,
+            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
         }
     ],
     foregroundRocks: [
         {
             type: WORLD_OBJECTS.ROCK_FOREGROUND,
+            x: 0,
+            config: ROCK_TYPES.SMALL
+        },
+        {
+            type: WORLD_OBJECTS.ROCK_FOREGROUND,
             x: 300,
             config: ROCK_TYPES.MEDIUM
         },
@@ -160,8 +242,34 @@ const createWorld = () => ({
             type: WORLD_OBJECTS.ROCK_FOREGROUND,
             x: 700,
             config: ROCK_TYPES.SMALL
+        },
+        {
+            type: WORLD_OBJECTS.ROCK_FOREGROUND,
+            x: 950,
+            config: ROCK_TYPES.LARGE
         }
-    ]
+    ],
+    backgroundGrass: [
+        { type: WORLD_OBJECTS.GRASS_BACKGROUND, x: -350, config: GRASS_TYPES.SHORT },
+        { type: WORLD_OBJECTS.GRASS_BACKGROUND, x: -180, config: GRASS_TYPES.TALL },
+        { type: WORLD_OBJECTS.GRASS_BACKGROUND, x: 100, config: GRASS_TYPES.TALL },
+        { type: WORLD_OBJECTS.GRASS_BACKGROUND, x: 320, config: GRASS_TYPES.SHORT },
+        { type: WORLD_OBJECTS.GRASS_BACKGROUND, x: 580, config: GRASS_TYPES.TALL },
+        { type: WORLD_OBJECTS.GRASS_BACKGROUND, x: 750, config: GRASS_TYPES.SHORT },
+        { type: WORLD_OBJECTS.GRASS_BACKGROUND, x: 950, config: GRASS_TYPES.TALL },
+        { type: WORLD_OBJECTS.GRASS_BACKGROUND, x: 1050, config: GRASS_TYPES.SHORT }
+    ],
+    foregroundGrass: [
+        { type: WORLD_OBJECTS.GRASS_FOREGROUND, x: -280, config: GRASS_TYPES.TALL },
+        { type: WORLD_OBJECTS.GRASS_FOREGROUND, x: -50, config: GRASS_TYPES.SHORT },
+        { type: WORLD_OBJECTS.GRASS_FOREGROUND, x: 150, config: GRASS_TYPES.TALL },
+        { type: WORLD_OBJECTS.GRASS_FOREGROUND, x: 420, config: GRASS_TYPES.SHORT },
+        { type: WORLD_OBJECTS.GRASS_FOREGROUND, x: 680, config: GRASS_TYPES.TALL },
+        { type: WORLD_OBJECTS.GRASS_FOREGROUND, x: 880, config: GRASS_TYPES.SHORT },
+        { type: WORLD_OBJECTS.GRASS_FOREGROUND, x: 1150, config: GRASS_TYPES.TALL }
+    ],
+    // Track grass animation states
+    grassStates: {}
 });
 
 // Rename current tree render function
@@ -265,6 +373,59 @@ const renderRock = (ctx, rock, groundY) => {
     ctx.fill();
 };
 
+// Add grass rendering function
+const renderGrass = (ctx, grass, groundY, time) => {
+    const { x, config } = grass;
+    const { width, height, blades, color, shadowColor } = config;
+    
+    // Get or initialize grass state
+    const stateKey = `grass_${x}`;
+    if (!window.gameState.world.grassStates[stateKey]) {
+        window.gameState.world.grassStates[stateKey] = {
+            rustleAmount: 0,
+            rustleDecay: 0.95
+        };
+    }
+    const state = window.gameState.world.grassStates[stateKey];
+    
+    // Check for player interaction
+    const player = window.gameState.player;
+    const interactionDistance = width;
+    const distanceToPlayer = Math.abs(player.x + player.width/2 - x);
+    
+    if (distanceToPlayer < interactionDistance) {
+        state.rustleAmount = Math.min(1, state.rustleAmount + 0.3);
+    } else {
+        state.rustleAmount *= state.rustleDecay;
+    }
+
+    // Draw each blade of grass
+    for (let i = 0; i < blades; i++) {
+        const bladeX = x + (i - blades/2) * (width/blades);
+        const bladeWidth = width / blades * 0.7;
+        
+        // Calculate blade curve based on rustle and time
+        const rustleOffset = Math.sin(time/300 + i) * 5 * state.rustleAmount;
+        const baseWave = Math.sin(time/1000 + i) * 2; // Gentle wave motion
+        
+        // Draw blade
+        ctx.fillStyle = i % 2 === 0 ? color : shadowColor;
+        ctx.beginPath();
+        ctx.moveTo(bladeX, groundY);
+        
+        // Control points for quadratic curve
+        const cp1x = bladeX + rustleOffset + baseWave;
+        const cp1y = groundY - height/2;
+        const cp2x = bladeX + rustleOffset * 1.5 + baseWave;
+        const cp2y = groundY - height;
+        
+        // Draw curved blade
+        ctx.quadraticCurveTo(cp1x, cp1y, cp2x, cp2y);
+        ctx.quadraticCurveTo(cp1x + bladeWidth, cp1y, bladeX + bladeWidth, groundY);
+        ctx.fill();
+    }
+};
+
 // Collision detection helper
 const checkCollision = (player, platform) => {
     return player.x < platform.x + platform.width &&