分享图
动画工坊
引擎就绪
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>TRIZ 理想最终解:零重量着陆机构原理</title>
    <style>
        @import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@100;400;700&family=Noto+Sans+SC:wght@300;500;700&display=swap');

        :root {
            --bg-color: #060913;
            --grid-color: rgba(30, 58, 138, 0.2);
            --rocket-body: #e2e8f0;
            --rocket-dark: #64748b;
            --accent-cyan: #00f0ff;
            --accent-blue: #3b82f6;
            --accent-orange: #ff5500;
            --accent-red: #ff003c;
            --text-main: #f8fafc;
            --text-dim: #94a3b8;
            --font-mono: 'JetBrains Mono', monospace;
            --font-sans: 'Noto Sans SC', sans-serif;
        }

        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
        }

        body {
            background-color: var(--bg-color);
            color: var(--text-main);
            font-family: var(--font-sans);
            overflow: hidden;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            width: 100vw;
            background-image: 
                linear-gradient(var(--grid-color) 1px, transparent 1px),
                linear-gradient(90deg, var(--grid-color) 1px, transparent 1px);
            background-size: 40px 40px;
            background-position: center center;
        }

        /* 绝对定位的数据面板,遵守极简、小字号、边缘放置的规则 */
        .hud-panel {
            position: absolute;
            z-index: 10;
            background: rgba(6, 9, 19, 0.7);
            border: 1px solid rgba(0, 240, 255, 0.2);
            backdrop-filter: blur(4px);
            padding: 16px;
            border-radius: 4px;
            font-family: var(--font-mono);
            font-size: 12px;
            pointer-events: none;
        }

        .hud-left {
            top: 40px;
            left: 40px;
            width: 280px;
        }

        .hud-right {
            top: 40px;
            right: 40px;
            width: 240px;
        }

        .hud-title {
            color: var(--accent-cyan);
            font-weight: 700;
            font-size: 14px;
            margin-bottom: 12px;
            border-bottom: 1px solid rgba(0, 240, 255, 0.3);
            padding-bottom: 6px;
            text-transform: uppercase;
            letter-spacing: 1px;
            font-family: var(--font-sans);
        }

        .hud-row {
            display: flex;
            justify-content: space-between;
            margin-bottom: 8px;
            color: var(--text-dim);
        }

        .hud-value {
            color: var(--text-main);
            font-weight: 700;
            text-shadow: 0 0 5px rgba(255, 255, 255, 0.3);
        }

        .hud-value.highlight {
            color: var(--accent-orange);
            text-shadow: 0 0 8px rgba(255, 85, 0, 0.5);
        }
        
        .hud-value.success {
            color: var(--accent-cyan);
            text-shadow: 0 0 8px rgba(0, 240, 255, 0.5);
        }

        .triz-concept {
            margin-top: 16px;
            padding-top: 12px;
            border-top: 1px dashed rgba(148, 163, 184, 0.3);
            font-family: var(--font-sans);
        }
        
        .triz-concept p {
            line-height: 1.6;
            margin-bottom: 8px;
            color: var(--text-dim);
        }
        
        .triz-concept span.highlight-cyan {
            color: var(--accent-cyan);
            font-weight: 500;
        }

        /* 主动画容器 */
        #svg-container {
            width: 100%;
            height: 100%;
            max-width: 1200px;
            max-height: 900px;
            display: flex;
            justify-content: center;
            align-items: center;
        }

        svg {
            width: 100%;
            height: 100%;
            overflow: visible;
        }

        /* SVG 样式 */
        .glow-cyan { filter: drop-shadow(0 0 8px rgba(0, 240, 255, 0.6)); }
        .glow-orange { filter: drop-shadow(0 0 12px rgba(255, 85, 0, 0.8)); }
        
        .rocket-body { fill: url(#rocket-gradient); }
        .grid-fin { fill: #1e293b; stroke: var(--accent-cyan); stroke-width: 1.5; }
        .engine-bell { fill: #334155; }
        
        .tower-struct { fill: none; stroke: #1e293b; stroke-width: 4; }
        .tower-highlight { fill: none; stroke: var(--accent-blue); stroke-width: 1; opacity: 0.5; }
        
        .catch-arm { fill: #0f172a; stroke: var(--accent-cyan); stroke-width: 2; }
        .damper-cylinder { fill: #1e293b; stroke: #475569; stroke-width: 2; }
        .damper-rod { fill: #cbd5e1; }
        .damper-indicator { fill: var(--accent-blue); transition: fill 0.3s; }
        
        .ghost-leg { fill: none; stroke: var(--accent-red); stroke-width: 2; stroke-dasharray: 4 4; opacity: 0; }
        
        /* 激光雷达扫描线 */
        .radar-scan {
            fill: none;
            stroke: var(--accent-cyan);
            stroke-width: 1;
            opacity: 0;
        }
    </style>
</head>
<body>

    <!-- 左侧 HUD:理论基础与状态 -->
    <div class="hud-panel hud-left">
        <div class="hud-title">TRIZ 理想最终解 (IFR)</div>
        <div class="triz-concept">
            <p>传统矛盾:火箭需极高精度着陆,但自备着陆腿增加死重,降低运载效率。</p>
            <p>IFR 策略:<span class="highlight-cyan">消除功能载体,保留功能。</span></p>
            <p>空间分离:将“缓冲”功能从飞行器本体转移至超系统(地面设施)。火箭仅保留<span class="highlight-cyan">承力栅格舵</span>。</p>
            <p style="margin-top: 10px; font-family: var(--font-mono); font-size: 11px; border-left: 2px solid var(--accent-cyan); padding-left: 8px;">
                > 箭载着陆机构重量 = 0<br>
                > 系统复杂度 = 转移至地面
            </p>
        </div>
    </div>

    <!-- 右侧 HUD:实时遥测数据 -->
    <div class="hud-panel hud-right">
        <div class="hud-title">遥测终端 / TELEMETRY</div>
        <div class="hud-row">
            <span>相对高度 (ALT)</span>
            <span class="hud-value" id="ui-alt">--- m</span>
        </div>
        <div class="hud-row">
            <span>下降速度 (VEL)</span>
            <span class="hud-value" id="ui-vel">--- m/s</span>
        </div>
        <div class="hud-row">
            <span>推力水平 (THR)</span>
            <span class="hud-value" id="ui-thr">--- %</span>
        </div>
        <div class="hud-row" style="margin-top: 12px; border-top: 1px solid #1e293b; padding-top: 12px;">
            <span>地面阻尼行程</span>
            <span class="hud-value" id="ui-damper">0.0 / 25 m</span>
        </div>
        <div class="hud-row">
            <span>单索张力负荷</span>
            <span class="hud-value" id="ui-tension">0 kN</span>
        </div>
        <div class="hud-row" style="margin-top: 12px;">
            <span>阶段 (PHASE)</span>
            <span class="hud-value success" id="ui-phase">系统待命</span>
        </div>
    </div>

    <div id="svg-container">
        <svg viewBox="0 0 1000 1000" preserveAspectRatio="xMidYMid meet">
            <defs>
                <!-- 火箭金属质感渐变 -->
                <linearGradient id="rocket-gradient" x1="0%" y1="0%" x2="100%" y2="0%">
                    <stop offset="0%" stop-color="#94a3b8" />
                    <stop offset="20%" stop-color="#f1f5f9" />
                    <stop offset="50%" stop-color="#cbd5e1" />
                    <stop offset="80%" stop-color="#64748b" />
                    <stop offset="100%" stop-color="#475569" />
                </linearGradient>

                <!-- 发动机尾焰渐变 -->
                <radialGradient id="flame-gradient" cx="50%" cy="20%" r="80%" fx="50%" fy="10%">
                    <stop offset="0%" stop-color="#ffffff" />
                    <stop offset="20%" stop-color="#ffed4a" />
                    <stop offset="60%" stop-color="#ff5500" />
                    <stop offset="100%" stop-color="rgba(255, 0, 0, 0)" />
                </radialGradient>

                <!-- 网格模式 (背景刻度) -->
                <pattern id="scale-grid" width="100" height="100" patternUnits="userSpaceOnUse">
                    <line x1="0" y1="0" x2="100" y2="0" stroke="rgba(255,255,255,0.05)" stroke-width="1" />
                    <line x1="0" y1="0" x2="0" y2="100" stroke="rgba(255,255,255,0.05)" stroke-width="1" />
                    <text x="5" y="15" fill="rgba(255,255,255,0.1)" font-size="10" font-family="monospace">10m</text>
                </pattern>

                <!-- 阻尼器发光滤镜 -->
                <filter id="glow-filter" x="-20%" y="-20%" width="140%" height="140%">
                    <feGaussianBlur stdDeviation="4" result="blur" />
                    <feComposite in="SourceGraphic" in2="blur" operator="over" />
                </filter>
            </defs>

            <!-- 背景刻度 -->
            <rect width="1000" height="1000" fill="url(#scale-grid)" />
            
            <!-- 地面线 -->
            <line x1="0" y1="950" x2="1000" y2="950" stroke="#1e293b" stroke-width="4" />
            <line x1="0" y1="950" x2="1000" y2="950" stroke="var(--accent-cyan)" stroke-width="1" opacity="0.5" />

            <!-- === 地面捕获设施 (超系统) === -->
            <g id="ground-system">
                <!-- 左塔 -->
                <g class="tower" transform="translate(250, 0)">
                    <rect x="0" y="300" width="60" height="650" class="tower-struct" />
                    <path d="M0,350 L60,400 M0,400 L60,450 M0,450 L60,500 M0,500 L60,550 M0,550 L60,600 M0,600 L60,650 M0,650 L60,700 M0,700 L60,750 M0,750 L60,800 M0,800 L60,850 M0,850 L60,900" stroke="#1e293b" stroke-width="2" />
                    <!-- 塔身科技线 -->
                    <line x1="30" y1="300" x2="30" y2="950" class="tower-highlight" />
                </g>

                <!-- 右塔 -->
                <g class="tower" transform="translate(690, 0)">
                    <rect x="0" y="300" width="60" height="650" class="tower-struct" />
                    <path d="M0,350 L60,400 M0,400 L60,450 M0,450 L60,500 M0,500 L60,550 M0,550 L60,600 M0,600 L60,650 M0,650 L60,700 M0,700 L60,750 M0,750 L60,800 M0,800 L60,850 M0,850 L60,900" stroke="#1e293b" stroke-width="2" />
                    <line x1="30" y1="300" x2="30" y2="950" class="tower-highlight" />
                </g>

                <!-- 动态捕获臂/柔性网架 (整个机构随动下沉) -->
                <g id="catch-mechanism" transform="translate(0, 500)">
                    <!-- 左侧机械臂基础 -->
                    <rect x="230" y="-20" width="100" height="40" fill="#0f172a" stroke="#475569" stroke-width="2" rx="4" />
                    <!-- 右侧机械臂基础 -->
                    <rect x="670" y="-20" width="100" height="40" fill="#0f172a" stroke="#475569" stroke-width="2" rx="4" />

                    <!-- 左侧阻尼器与轨道 -->
                    <rect x="310" y="-10" width="40" height="20" class="damper-cylinder" />
                    <rect x="350" y="-4" width="70" height="8" class="damper-rod" id="left-arm-rod" />
                    <circle cx="420" cy="0" r="12" class="catch-arm glow-cyan" id="left-contact-node" />
                    <rect x="315" y="-6" width="10" height="12" class="damper-indicator" id="left-damper-led" />

                    <!-- 右侧阻尼器与轨道 -->
                    <rect x="650" y="-10" width="40" height="20" class="damper-cylinder" />
                    <rect x="580" y="-4" width="70" height="8" class="damper-rod" id="right-arm-rod" />
                    <circle cx="580" cy="0" r="12" class="catch-arm glow-cyan" id="right-contact-node" />
                    <rect x="675" y="-6" width="10" height="12" class="damper-indicator" id="right-damper-led" />

                    <!-- 引导激光束 (闭环引导可视化) -->
                    <path id="guidance-laser-l" d="M 420,0 L 500,-150" class="radar-scan" />
                    <path id="guidance-laser-r" d="M 580,0 L 500,-150" class="radar-scan" />
                    
                    <!-- 捕捉网张力可视化连接线 (在后台,仅在接触后显现高张力状态) -->
                    <line x1="420" y1="0" x2="580" y2="0" stroke="var(--accent-orange)" stroke-width="4" stroke-dasharray="8 4" opacity="0" id="tension-net" filter="url(#glow-filter)" />
                </g>
            </g>

            <!-- === 火箭本体 === -->
            <!-- 初始位于上方,通过 JS 控制 transform -->
            <g id="rocket" transform="translate(500, -200)">
                <!-- 被消除的传统着陆腿 (幽灵状态,展示 IFR 消除死重) -->
                <path d="M -35,180 L -70,250 L -80,250" class="ghost-leg" id="ghost-leg-l" />
                <path d="M 35,180 L 70,250 L 80,250" class="ghost-leg" id="ghost-leg-r" />

                <!-- 尾焰 -->
                <path id="engine-flame" d="M -20,195 Q 0,400 20,195 Q 0,220 -20,195 Z" fill="url(#flame-gradient)" class="glow-orange" style="transform-origin: 0 195px;" />
                
                <!-- 发动机喷口 -->
                <path d="M -25,180 L 25,180 L 30,195 L -30,195 Z" class="engine-bell" />
                
                <!-- 箭体 -->
                <rect x="-35" y="-180" width="70" height="360" rx="10" class="rocket-body" />
                
                <!-- 表面细节线 -->
                <line x1="-35" y1="-100" x2="35" y2="-100" stroke="#64748b" stroke-width="1" />
                <line x1="-35" y1="0" x2="35" y2="0" stroke="#64748b" stroke-width="1" />
                <line x1="-35" y1="100" x2="35" y2="100" stroke="#64748b" stroke-width="1" />
                <text x="0" y="50" fill="#64748b" font-family="monospace" font-size="24" font-weight="bold" transform="rotate(-90)" text-anchor="middle" opacity="0.3">IFR-X1</text>

                <!-- 承力栅格舵 (核心捕获部件) -->
                <!-- 左栅格舵 -->
                <g transform="translate(-35, -140)" id="grid-fin-l">
                    <rect x="-40" y="0" width="40" height="15" class="grid-fin" rx="2" />
                    <!-- 内部网格暗示 -->
                    <line x1="-30" y1="0" x2="-30" y2="15" stroke="var(--accent-cyan)" stroke-width="1" />
                    <line x1="-20" y1="0" x2="-20" y2="15" stroke="var(--accent-cyan)" stroke-width="1" />
                    <line x1="-10" y1="0" x2="-10" y2="15" stroke="var(--accent-cyan)" stroke-width="1" />
                </g>
                <!-- 右栅格舵 -->
                <g transform="translate(35, -140)" id="grid-fin-r">
                    <rect x="0" y="0" width="40" height="15" class="grid-fin" rx="2" />
                    <line x1="10" y1="0" x2="10" y2="15" stroke="var(--accent-cyan)" stroke-width="1" />
                    <line x1="20" y1="0" x2="20" y2="15" stroke="var(--accent-cyan)" stroke-width="1" />
                    <line x1="30" y1="0" x2="30" y2="15" stroke="var(--accent-cyan)" stroke-width="1" />
                </g>
                
                <!-- 接触点高亮圆环 (仅在入网瞬间闪烁) -->
                <circle cx="-75" cy="-132.5" r="15" fill="none" stroke="var(--accent-orange)" stroke-width="3" opacity="0" id="impact-glow-l" filter="url(#glow-filter)" />
                <circle cx="75" cy="-132.5" r="15" fill="none" stroke="var(--accent-orange)" stroke-width="3" opacity="0" id="impact-glow-r" filter="url(#glow-filter)" />
            </g>
            
            <!-- 视觉引导:动态箭头与说明文字 (绝对避免遮挡主体,放在中心外侧) -->
            <g id="visual-cues" opacity="0">
                <path d="M 330,520 L 330,620 M 320,610 L 330,620 L 340,610" fill="none" stroke="var(--accent-cyan)" stroke-width="2" />
                <text x="310" y="570" fill="var(--accent-cyan)" font-size="12" font-family="var(--font-sans)">阻尼下沉 20-25m</text>
                
                <path d="M 670,520 L 670,620 M 660,610 L 670,620 L 680,610" fill="none" stroke="var(--accent-cyan)" stroke-width="2" />
                <text x="690" y="570" fill="var(--accent-cyan)" font-size="12" font-family="var(--font-sans)">吸收残余动能</text>
            </g>

        </svg>
    </div>

    <script>
        document.addEventListener('DOMContentLoaded', () => {
            // DOM 元素引用
            const elements = {
                rocket: document.getElementById('rocket'),
                flame: document.getElementById('engine-flame'),
                catchMechanism: document.getElementById('catch-mechanism'),
                ghostLegs: [document.getElementById('ghost-leg-l'), document.getElementById('ghost-leg-r')],
                lasers: [document.getElementById('guidance-laser-l'), document.getElementById('guidance-laser-r')],
                impactGlows: [document.getElementById('impact-glow-l'), document.getElementById('impact-glow-r')],
                damperLeds: [document.getElementById('left-damper-led'), document.getElementById('right-damper-led')],
                damperRods: [document.getElementById('left-arm-rod'), document.getElementById('right-arm-rod')],
                tensionNet: document.getElementById('tension-net'),
                visualCues: document.getElementById('visual-cues'),
                
                // UI 文本
                uiAlt: document.getElementById('ui-alt'),
                uiVel: document.getElementById('ui-vel'),
                uiThr: document.getElementById('ui-thr'),
                uiDamper: document.getElementById('ui-damper'),
                uiTension: document.getElementById('ui-tension'),
                uiPhase: document.getElementById('ui-phase'),
            };

            // 物理常量与配置 (映射到 SVG 坐标)
            const config = {
                cycleTime: 14000, // 完整动画周期 14 秒
                startY: -100,     // 火箭初始 Y
                catchY: 345,      // 栅格舵接触捕捉网时,火箭中心的 Y 坐标
                groundY: 950,
                mechBaseY: 360,   // 机构初始 Y 坐标
                mechTravel: 150,  // 阻尼机构下沉距离 (视觉上夸大以便看清原理)
                maxSpeed: 80,
                targetSpeed: 6.5  // 入网残余速度 5-8 m/s
            };

            let animationFrameId;
            let startTime = null;

            // 缓动函数
            const easeOutQuad = t => t * (2 - t);
            const easeOutCubic = t => (--t) * t * t + 1;
            const easeInOutSine = t => -(Math.cos(Math.PI * t) - 1) / 2;

            function animate(timestamp) {
                if (!startTime) startTime = timestamp;
                
                // 计算当前周期内的时间 [0, cycleTime]
                let elapsed = (timestamp - startTime) % config.cycleTime;
                
                // 定义四个主要阶段
                // 1. 高空减速入场 (0 - 4000ms)
                // 2. 闭环雷达引导对准 (4000 - 7000ms)
                // 3. 接触与阻尼下沉吸收动能 (7000 - 9000ms)
                // 4. 锁定与重置 (9000 - 14000ms)

                let rocketY = config.startY;
                let rocketSpeed = 0;
                let flameScale = 0;
                let mechY = config.mechBaseY;
                let damperCompress = 0; // 0 to 1

                if (elapsed < 4000) {
                    // --- 阶段 1: 极速下降与主减速 ---
                    let p = elapsed / 4000;
                    let easeP = easeOutQuad(p);
                    
                    rocketY = config.startY + (config.catchY - 150 - config.startY) * easeP;
                    rocketSpeed = config.maxSpeed - (config.maxSpeed - 20) * easeP;
                    flameScale = 1.2 + Math.random() * 0.3; // 强尾焰抖动
                    
                    // UI 更新
                    elements.uiPhase.textContent = "反推减速下降";
                    elements.uiPhase.className = "hud-value";
                    elements.ghostLegs.forEach(el => el.style.opacity = Math.max(0, 1 - p * 3)); // 快速淡出传统腿
                    elements.lasers.forEach(el => el.style.opacity = 0);
                    
                } else if (elapsed < 7000) {
                    // --- 阶段 2: 悬停对准,闭环引导 ---
                    let p = (elapsed - 4000) / 3000;
                    
                    rocketY = (config.catchY - 150) + 150 * p; // 线性慢速下降
                    rocketSpeed = 20 - (20 - config.targetSpeed) * p; // 降速至残余速度 5-8 m/s
                    flameScale = 0.5 + Math.random() * 0.1; // 较小尾焰
                    
                    // 雷达扫描视觉效果
                    let scanOp = Math.sin(p * Math.PI * 10) * 0.5 + 0.5;
                    elements.lasers.forEach(el => el.style.opacity = scanOp);
                    
                    // 跟踪激光末端对准火箭栅格舵
                    elements.lasers[0].setAttribute('d', `M 420,0 L ${500 - 75},${rocketY - config.mechBaseY - 132}`);
                    elements.lasers[1].setAttribute('d', `M 580,0 L ${500 + 75},${rocketY - config.mechBaseY - 132}`);

                    elements.uiPhase.textContent = "视觉雷达闭环引导";
                    elements.uiPhase.className = "hud-value highlight";
                    
                } else if (elapsed < 9000) {
                    // --- 阶段 3: 接触、熄火、系统随动阻尼 ---
                    let p = (elapsed - 7000) / 2000;
                    let easeP = easeOutCubic(p); // 阻尼减速特性
                    
                    // 接触瞬间 (7000-7100ms)
                    if (elapsed < 7100) {
                        elements.impactGlows.forEach(el => el.style.opacity = 1);
                        elements.tensionNet.style.opacity = 0.8;
                    } else {
                        elements.impactGlows.forEach(el => el.style.opacity = Math.max(0, 1 - (elapsed-7100)/500));
                    }
                    
                    flameScale = 0; // 熄火
                    rocketSpeed = config.targetSpeed * (1 - easeP);
                    
                    // 火箭和机构一起下沉
                    mechY = config.mechBaseY + config.mechTravel * easeP;
                    rocketY = config.catchY + config.mechTravel * easeP;
                    
                    damperCompress = easeP; // 阻尼器压缩度

                    elements.lasers.forEach(el => el.style.opacity = 0);
                    elements.uiPhase.textContent = "柔性捕获与阻尼缓冲";
                    elements.uiPhase.className = "hud-value highlight";
                    elements.visualCues.style.opacity = p < 0.5 ? p * 2 : 2 - p * 2; // 提示文字淡入淡出
                    
                } else if (elapsed < 12000) {
                    // --- 阶段 4: 锁定 ---
                    rocketY = config.catchY + config.mechTravel;
                    mechY = config.mechBaseY + config.mechTravel;
                    rocketSpeed = 0;
                    flameScale = 0;
                    damperCompress = 1;
                    
                    elements.tensionNet.style.opacity = 0.3; // 保持静张力
                    
                    elements.uiPhase.textContent = "成功锁定,动能清零";
                    elements.uiPhase.className = "hud-value success";
                    
                } else {
                    // --- 阶段 5: 重置动画准备 ---
                    let p = (elapsed - 12000) / 2000;
                    let easeP = easeInOutSine(p);
                    
                    mechY = (config.mechBaseY + config.mechTravel) - (config.mechTravel * easeP);
                    rocketY = config.startY - 300; // 移出屏幕上方
                    damperCompress = 1 - easeP;
                    
                    elements.tensionNet.style.opacity = 0;
                    elements.uiPhase.textContent = "系统复位中...";
                    elements.uiPhase.className = "hud-value";
                }

                // ==================== 应用视觉变换 ====================
                
                // 1. 火箭本体与尾焰
                elements.rocket.setAttribute('transform', `translate(500, ${rocketY})`);
                elements.flame.style.transform = `scaleY(${flameScale})`;
                elements.flame.style.opacity = flameScale > 0 ? 0.9 : 0;
                
                // 2. 地面捕获机构下沉
                elements.catchMechanism.setAttribute('transform', `translate(0, ${mechY})`);
                
                // 3. 阻尼器视觉反馈 (变色与压缩)
                // 颜色从蓝 (待命) 到 橙/红 (受力发热)
                let r = Math.floor(59 + damperCompress * 196); // 3b -> ff
                let g = Math.floor(130 - damperCompress * 45); // 82 -> 55
                let b = Math.floor(246 - damperCompress * 246); // f6 -> 00
                let damperColor = `rgb(${r}, ${g}, ${b})`;
                
                elements.damperLeds.forEach(el => {
                    el.style.fill = damperColor;
                    el.style.filter = `drop-shadow(0 0 ${4 + damperCompress*8}px ${damperColor})`;
                });
                
                // 拉杆伸出/缩进模拟 (通过宽度变化粗略模拟)
                elements.damperRods[0].setAttribute('width', 70 + damperCompress * 30);
                elements.damperRods[1].setAttribute('x', 580 - damperCompress * 30);
                elements.damperRods[1].setAttribute('width', 70 + damperCompress * 30);

                // ==================== 更新 UI 数据 ====================
                
                // 计算模拟的真实海拔 (将 SVG 坐标映射回米,基准点在地面)
                let realAltitude = Math.max(0, (config.groundY - rocketY) * 0.3).toFixed(1);
                elements.uiAlt.textContent = `${realAltitude} m`;
                
                // 速度显示格式化
                elements.uiVel.textContent = `${rocketSpeed.toFixed(1)} m/s`;
                elements.uiVel.className = rocketSpeed <= config.targetSpeed && rocketSpeed > 0 ? "hud-value success" : "hud-value";
                
                // 推力显示
                let thrust = flameScale > 0 ? (30 + flameScale * 40).toFixed(0) : "0";
                elements.uiThr.textContent = `${thrust} %`;
                
                // 阻尼行程显示 (模拟最大 25m)
                let travelMeters = (damperCompress * 25).toFixed(1);
                elements.uiDamper.textContent = `${travelMeters} / 25.0 m`;
                if(damperCompress > 0.1) {
                    elements.uiDamper.className = "hud-value highlight";
                } else {
                    elements.uiDamper.className = "hud-value";
                }

                // 碳纤维索张力显示 (最大 800kN)
                let tension = (damperCompress * 780 + (Math.random()*20 * damperCompress)).toFixed(0);
                elements.uiTension.textContent = `${tension} kN`;

                // 循环调用
                animationFrameId = requestAnimationFrame(animate);
            }

            // 启动动画
            animationFrameId = requestAnimationFrame(animate);
            
            // 确保页面重新显示时时间戳逻辑不崩,或清理重新开始
            document.addEventListener('visibilitychange', () => {
                if (document.hidden) {
                    cancelAnimationFrame(animationFrameId);
                    startTime = null; // 重置时间以防止切回时快进
                } else {
                    animationFrameId = requestAnimationFrame(animate);
                }
            });
        });
    </script>
</body>
</html>
积分规则:第一轮对话扣减8分,后续每轮扣6分