about summary refs log tree commit diff stats
path: root/html/rogue/js/world.js
diff options
context:
space:
mode:
Diffstat (limited to 'html/rogue/js/world.js')
-rw-r--r--html/rogue/js/world.js211
1 files changed, 133 insertions, 78 deletions
diff --git a/html/rogue/js/world.js b/html/rogue/js/world.js
index f68ece6..d0ac529 100644
--- a/html/rogue/js/world.js
+++ b/html/rogue/js/world.js
@@ -15,17 +15,17 @@ const WORLD_OBJECTS = {
 const FIR_TYPES = {
     SMALL: {
         type: 'fir',
-        width: 80,
-        height: 120,
-        canopyOffset: 40,
+        width: 100,
+        height: 130,
+        canopyOffset: 45,
         canopyColor: '#22aa44',
         trunkColor: '#553311'
     },
     LARGE: {
         type: 'fir',
-        width: 120,
-        height: 200,
-        canopyOffset: 60,
+        width: 150,
+        height: 220,
+        canopyOffset: 65,
         canopyColor: '#11aa44',
         trunkColor: '#442200'
     }
@@ -559,16 +559,7 @@ const renderFirTree = (ctx, tree, groundY) => {
         trunkColor
     );
 
-    // Draw main triangular canopy
-    ctx.fillStyle = canopyColor;
-    ctx.beginPath();
-    ctx.moveTo(x - width/2, groundY - canopyOffset);
-    ctx.lineTo(x + width/2, groundY - canopyOffset);
-    ctx.lineTo(x, groundY - height);
-    ctx.closePath();
-    ctx.fill();
-
-    // Define a range of green colors for texture that are distinct from the base color
+    // Define a range of green colors for texture
     const greenColors = [
         '#11aa33', // Darker forest green
         '#22bb44', // Medium forest green
@@ -579,75 +570,139 @@ const renderFirTree = (ctx, tree, groundY) => {
         '#229955', // Ocean green
         '#33bb66', // Fresh spring green
         '#117744', // Dark emerald
-    ];
-
-    // Filter out any colors too similar to the base color
-    const distinctColors = greenColors.filter(color => {
-        // Simple check - if colors are exactly the same, filter out
-        return color !== canopyColor;
-    });
+    ].filter(color => color !== canopyColor);
 
-    // Add triangle pattern texture
-    const spacing = 8; // Smaller spacing for more triangles
-    const triangleSize = 8; // Slightly smaller triangles
-    const margin = 8;
-    
-    // Calculate bounds for the pattern
-    const bounds = {
-        minX: x - width/2 + margin,
-        maxX: x + width/2 - margin,
-        minY: groundY - height + margin,
-        maxY: groundY - canopyOffset - margin
-    };
+    // Draw main triangular canopy with feathered edges
+    const drawFeatheredTriangle = (baseWidth, baseY, tipY) => {
+        // Draw main shape
+        ctx.fillStyle = canopyColor;
+        ctx.beginPath();
+        ctx.moveTo(x - baseWidth/2, baseY);
+        ctx.lineTo(x + baseWidth/2, baseY);
+        ctx.lineTo(x, tipY);
+        ctx.closePath();
+        ctx.fill();
 
-    // Generate triangle pattern
-    for (let py = bounds.minY; py < bounds.maxY; py += spacing) {
-        // Calculate how wide the tree is at this height
-        const heightRatio = (py - (groundY - height)) / (groundY - canopyOffset - (groundY - height));
-        const levelWidth = width * heightRatio;
-        
-        // Calculate x bounds for this row
-        const rowMinX = x - levelWidth/2 + margin;
-        const rowMaxX = x + levelWidth/2 - margin;
+        // Add internal triangles
+        const spacing = 8; // Smaller spacing for more triangles
+        const triangleSize = 8; // Size of internal triangles
+        const margin = 12; // Margin from edges
         
-        // Add slight offset to alternate rows
-        const rowOffset = (Math.floor(py / spacing) % 2) * (spacing / 2);
-        
-        for (let px = rowMinX; px < rowMaxX; px += spacing) {
-            // Use position for random variation
-            const seed1 = px * 13.37;
-            const seed2 = py * 7.89;
+        // Calculate area for internal triangles
+        for (let py = tipY + margin; py < baseY - margin; py += spacing) {
+            // Calculate width at this height
+            const heightRatio = (py - tipY) / (baseY - tipY);
+            const levelWidth = baseWidth * heightRatio;
             
-            // Random variations
-            const variation = {
-                x: (seededRandom(seed1, seed2) - 0.5) * 6,
-                y: (seededRandom(seed2, seed1) - 0.5) * 6,
-                rotation: seededRandom(seed1 + seed2, seed2 - seed1) * Math.PI * 0.5,
-                size: triangleSize * (0.7 + seededRandom(seed1, seed2) * 0.6)
-            };
-
-            // Pick a random color from our green palette
-            const colorIndex = Math.floor(seededRandom(seed1 * seed2, seed2 * seed1) * distinctColors.length);
-            ctx.fillStyle = distinctColors[colorIndex];
-
-            ctx.save();
-            ctx.translate(
-                px + rowOffset + variation.x, 
-                py + variation.y
-            );
-            ctx.rotate(variation.rotation);
+            // Calculate x bounds for this row
+            const rowMinX = x - levelWidth/2 + margin;
+            const rowMaxX = x + levelWidth/2 - margin;
             
-            // Draw small triangle
-            ctx.beginPath();
-            ctx.moveTo(-variation.size/2, variation.size/2);
-            ctx.lineTo(variation.size/2, variation.size/2);
-            ctx.lineTo(0, -variation.size/2);
-            ctx.closePath();
-            ctx.fill();
+            // Add slight offset to alternate rows
+            const rowOffset = (Math.floor(py / spacing) % 2) * (spacing / 2);
             
-            ctx.restore();
+            for (let px = rowMinX; px < rowMaxX; px += spacing) {
+                const seed1 = px * 13.37;
+                const seed2 = py * 7.89;
+                
+                // Random variations
+                const variation = {
+                    x: (seededRandom(seed1, seed2) - 0.5) * 4,
+                    y: (seededRandom(seed2, seed1) - 0.5) * 4,
+                    rotation: seededRandom(seed1 + seed2, seed2 - seed1) * Math.PI * 0.25,
+                    size: triangleSize * (0.7 + seededRandom(seed1, seed2) * 0.6)
+                };
+
+                // Pick a random color
+                const colorIndex = Math.floor(seededRandom(seed1 * seed2, seed2 * seed1) * greenColors.length);
+                ctx.fillStyle = greenColors[colorIndex];
+
+                ctx.save();
+                ctx.translate(
+                    px + rowOffset + variation.x, 
+                    py + variation.y
+                );
+                ctx.rotate(variation.rotation);
+                
+                // Draw small triangle
+                ctx.beginPath();
+                ctx.moveTo(-variation.size/2, variation.size/2);
+                ctx.lineTo(variation.size/2, variation.size/2);
+                ctx.lineTo(0, -variation.size/2);
+                ctx.closePath();
+                ctx.fill();
+                
+                ctx.restore();
+            }
         }
-    }
+
+        // Enhanced feathering
+        const featherCount = 24; // Doubled from 12
+        const featherLength = baseWidth * 0.15; // Increased from 0.1
+        const featherWidth = 1.5; // Slightly thinner lines
+        
+        ctx.strokeStyle = canopyColor;
+        ctx.lineWidth = featherWidth;
+        
+        // Left edge feathering - two layers
+        for (let layer = 0; layer < 2; layer++) {
+            for (let i = 0; i < featherCount; i++) {
+                const t = i / (featherCount - 1);
+                const startX = x - baseWidth/2 + (baseWidth/2) * t;
+                const startY = baseY - (baseY - tipY) * t;
+                
+                // Vary angle more with layer
+                const baseAngle = Math.PI * 0.7;
+                const angleVariation = Math.PI * (0.15 + layer * 0.1);
+                const angle = baseAngle + (angleVariation * seededRandom(startX + layer, startY));
+                
+                // Vary length with layer
+                const lengthMultiplier = 1 - t * 0.5;
+                const layerLength = featherLength * (1 - layer * 0.3) * lengthMultiplier;
+                
+                ctx.beginPath();
+                ctx.moveTo(startX, startY);
+                ctx.lineTo(
+                    startX + Math.cos(angle) * layerLength,
+                    startY + Math.sin(angle) * layerLength
+                );
+                ctx.stroke();
+            }
+        }
+        
+        // Right edge feathering - two layers
+        for (let layer = 0; layer < 2; layer++) {
+            for (let i = 0; i < featherCount; i++) {
+                const t = i / (featherCount - 1);
+                const startX = x + baseWidth/2 - (baseWidth/2) * t;
+                const startY = baseY - (baseY - tipY) * t;
+                
+                // Vary angle more with layer
+                const baseAngle = Math.PI * 0.3;
+                const angleVariation = Math.PI * (0.15 + layer * 0.1);
+                const angle = baseAngle - (angleVariation * seededRandom(startX + layer, startY));
+                
+                // Vary length with layer
+                const lengthMultiplier = 1 - t * 0.5;
+                const layerLength = featherLength * (1 - layer * 0.3) * lengthMultiplier;
+                
+                ctx.beginPath();
+                ctx.moveTo(startX, startY);
+                ctx.lineTo(
+                    startX + Math.cos(angle) * layerLength,
+                    startY + Math.sin(angle) * layerLength
+                );
+                ctx.stroke();
+            }
+        }
+    };
+
+    // Draw main triangular canopy
+    drawFeatheredTriangle(
+        width * 1.2,
+        groundY - canopyOffset,
+        groundY - height * 1.1
+    );
 };
 
 // Helper function to darken/lighten colors