feat: add realistic mountains with peaks and ground terrain

Enhanced tunnel entrances with proper mountain scenery:

Mountains:
- Added triangular mountain peaks rising above tunnel entrances
- Gradient shading for depth and dimension
- Rocky texture with vertical crack details
- Green vegetation/bushes at mountain base

Tunnels:
- Stone brick archways with brown/tan coloring
- Brick texture pattern on arch rim
- Dark interior for depth

Ground:
- Brown earth terrain extending full viewport width
- Gradient shading for ground surface depth
- Positioned below tunnel entrances

Train now emerges from/enters proper mountain tunnels set into
realistic terrain.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Thomas Hallock
2025-09-30 16:41:41 -05:00
parent 7488bb3803
commit 99cdfa8a0b

View File

@@ -203,6 +203,42 @@ export function SteamTrainJourney({ momentum, trainPosition, pressure, elapsedTi
overflow: 'visible'
}}
>
{/* Gradient definitions for mountain shading and ground */}
<defs>
<linearGradient id="mountainGradientLeft" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style={{ stopColor: '#a0a0a0', stopOpacity: 0.8 }} />
<stop offset="50%" style={{ stopColor: '#7a7a7a', stopOpacity: 0.6 }} />
<stop offset="100%" style={{ stopColor: '#5a5a5a', stopOpacity: 0.4 }} />
</linearGradient>
<linearGradient id="mountainGradientRight" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style={{ stopColor: '#5a5a5a', stopOpacity: 0.4 }} />
<stop offset="50%" style={{ stopColor: '#7a7a7a', stopOpacity: 0.6 }} />
<stop offset="100%" style={{ stopColor: '#a0a0a0', stopOpacity: 0.8 }} />
</linearGradient>
<linearGradient id="groundGradient" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style={{ stopColor: '#6a8759', stopOpacity: 0.3 }} />
<stop offset="100%" style={{ stopColor: '#8B7355', stopOpacity: 0 }} />
</linearGradient>
</defs>
{/* Ground layer - extends full width */}
<rect
x="-50"
y="450"
width="900"
height="200"
fill="#8B7355"
/>
{/* Ground gradient for depth */}
<rect
x="-50"
y="450"
width="900"
height="40"
fill="url(#groundGradient)"
/>
{/* Railroad ballast (gravel bed) */}
<path
d={trackData.ballastPath}
@@ -212,18 +248,55 @@ export function SteamTrainJourney({ momentum, trainPosition, pressure, elapsedTi
strokeLinecap="round"
/>
{/* Left tunnel - at absolute left edge of viewBox (x = -50) */}
{/* Left mountain and tunnel */}
<g data-element="left-tunnel">
{/* Mountain face - extends from left edge */}
{/* Mountain base - extends from left edge */}
<rect
x="-50"
y="-50"
width="70"
height="700"
fill="#5a5a5a"
stroke="#4a4a4a"
strokeWidth="2"
y="200"
width="120"
height="450"
fill="#6b7280"
/>
{/* Mountain peak - triangular slope */}
<path
d="M -50 200 L 70 200 L 20 -50 L -50 100 Z"
fill="#8b8b8b"
/>
{/* Mountain ridge shading */}
<path
d="M -50 200 L 70 200 L 20 -50 Z"
fill="url(#mountainGradientLeft)"
/>
{/* Rocky texture - vertical cracks */}
{[0, 1, 2, 3].map((i) => (
<line
key={`rock-left-${i}`}
x1={-30 + i * 20}
y1={250 + i * 30}
x2={-35 + i * 20}
y2={350 + i * 40}
stroke="#4a5568"
strokeWidth="2"
opacity="0.6"
/>
))}
{/* Vegetation/bushes at base */}
{[0, 1, 2].map((i) => (
<circle
key={`bush-left-${i}`}
cx={-20 + i * 30}
cy={380 + i * 15}
r={15}
fill="#4a7c59"
opacity="0.7"
/>
))}
{/* Tunnel depth/interior (dark entrance) */}
<ellipse
cx="20"
@@ -232,6 +305,7 @@ export function SteamTrainJourney({ momentum, trainPosition, pressure, elapsedTi
ry="55"
fill="#0a0a0a"
/>
{/* Tunnel arch opening */}
<path
d="M 20 355 L -50 355 L -50 245 Q -50 235, 20 235 Q 70 235, 70 245 L 70 355 Z"
@@ -239,28 +313,75 @@ export function SteamTrainJourney({ momentum, trainPosition, pressure, elapsedTi
stroke="#4a4a4a"
strokeWidth="3"
/>
{/* Tunnel arch rim (stone) */}
{/* Tunnel arch rim (stone bricks) */}
<path
d="M -50 245 Q -50 235, 20 235 Q 70 235, 70 245"
fill="none"
stroke="#6a6a6a"
strokeWidth="6"
stroke="#8b7355"
strokeWidth="8"
strokeLinecap="round"
/>
{/* Stone brick texture around arch */}
<path
d="M -50 245 Q -50 235, 20 235 Q 70 235, 70 245"
fill="none"
stroke="#654321"
strokeWidth="2"
strokeDasharray="15,10"
/>
</g>
{/* Right tunnel - at absolute right edge of viewBox (x = 850) */}
{/* Right mountain and tunnel */}
<g data-element="right-tunnel">
{/* Mountain face - extends to right edge */}
{/* Mountain base - extends to right edge */}
<rect
x="780"
y="-50"
width="70"
height="700"
fill="#5a5a5a"
stroke="#4a4a4a"
strokeWidth="2"
x="680"
y="200"
width="170"
height="450"
fill="#6b7280"
/>
{/* Mountain peak - triangular slope */}
<path
d="M 730 200 L 850 200 L 850 100 L 780 -50 Z"
fill="#8b8b8b"
/>
{/* Mountain ridge shading */}
<path
d="M 730 200 L 850 150 L 780 -50 Z"
fill="url(#mountainGradientRight)"
/>
{/* Rocky texture - vertical cracks */}
{[0, 1, 2, 3].map((i) => (
<line
key={`rock-right-${i}`}
x1={750 + i * 20}
y1={250 + i * 30}
x2={745 + i * 20}
y2={350 + i * 40}
stroke="#4a5568"
strokeWidth="2"
opacity="0.6"
/>
))}
{/* Vegetation/bushes at base */}
{[0, 1, 2].map((i) => (
<circle
key={`bush-right-${i}`}
cx={720 + i * 30}
cy={380 + i * 15}
r={15}
fill="#4a7c59"
opacity="0.7"
/>
))}
{/* Tunnel depth/interior (dark entrance) */}
<ellipse
cx="780"
@@ -269,6 +390,7 @@ export function SteamTrainJourney({ momentum, trainPosition, pressure, elapsedTi
ry="55"
fill="#0a0a0a"
/>
{/* Tunnel arch opening */}
<path
d="M 780 355 L 730 355 L 730 245 Q 730 235, 780 235 Q 850 235, 850 245 L 850 355 Z"
@@ -276,14 +398,24 @@ export function SteamTrainJourney({ momentum, trainPosition, pressure, elapsedTi
stroke="#4a4a4a"
strokeWidth="3"
/>
{/* Tunnel arch rim (stone) */}
{/* Tunnel arch rim (stone bricks) */}
<path
d="M 730 245 Q 730 235, 780 235 Q 850 235, 850 245"
fill="none"
stroke="#6a6a6a"
strokeWidth="6"
stroke="#8b7355"
strokeWidth="8"
strokeLinecap="round"
/>
{/* Stone brick texture around arch */}
<path
d="M 730 245 Q 730 235, 780 235 Q 850 235, 850 245"
fill="none"
stroke="#654321"
strokeWidth="2"
strokeDasharray="15,10"
/>
</g>
{/* Railroad ties */}