about summary refs log tree commit diff stats
path: root/html/rogue/js
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/js
parent57929fc1a92493cee0de00a079fb22d003a348e3 (diff)
downloadtour-b08a7074b84223fc92d3a24b7758cf222f3f97ef.tar.gz
*
Diffstat (limited to 'html/rogue/js')
-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 &&
>579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655