diff options
author | elioat <elioat@tilde.institute> | 2024-12-24 16:36:31 -0500 |
---|---|---|
committer | elioat <elioat@tilde.institute> | 2024-12-24 16:36:31 -0500 |
commit | f7a5877aa7f1a606d7116319fd71edb438b21011 (patch) | |
tree | 976f94c7a2142406aeda6a45b3d8321b40d30376 /html/rogue/js/world.js | |
parent | 9c2002f6010d2b117b75195888f3ccb4044cccf5 (diff) | |
download | tour-f7a5877aa7f1a606d7116319fd71edb438b21011.tar.gz |
*
Diffstat (limited to 'html/rogue/js/world.js')
-rw-r--r-- | html/rogue/js/world.js | 211 |
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 |