未命名 EEAtPQedit icon

创建者:
用户zdlDCoL7
Fork(复制)
下载
嵌入
BUG反馈
index.html
index.html
            
            <!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>深圳—天空之城无人机导航系统</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: 'Segoe UI', 'Microsoft YaHei', sans-serif;
        }
        
        body {
            background: linear-gradient(135deg, #0a0a2a, #1a1a3a);
            color: #e0f7fa;
            min-height: 100vh;
            padding: 15px;
            position: relative;
            overflow-x: hidden;
        }
        
        .tech-grid {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background-image: 
                linear-gradient(rgba(0, 150, 255, 0.1) 1px, transparent 1px),
                linear-gradient(90deg, rgba(0, 150, 255, 0.1) 1px, transparent 1px);
            background-size: 30px 30px;
            z-index: -2;
            pointer-events: none;
        }
        
        .scan-line {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 2px;
            background: linear-gradient(90deg, transparent, rgba(0, 255, 255, 0.7), transparent);
            box-shadow: 0 0 10px rgba(0, 255, 255, 0.8);
            z-index: -1;
            animation: scan 3s linear infinite;
            pointer-events: none;
        }
        
        @keyframes scan {
            0% { top: 0; }
            100% { top: 100%; }
        }
        
        .grass-bg {
            position: absolute;
            bottom: 0;
            left: 0;
            width: 100%;
            height: 80px;
            background: linear-gradient(to top, rgba(0, 100, 0, 0.3), transparent);
            z-index: -1;
        }
        
        .grass-bg::before {
            content: "";
            position: absolute;
            top: -15px;
            left: 0;
            width: 100%;
            height: 30px;
            background: 
                radial-gradient(circle at 10% 20%, rgba(0, 150, 0, 0.4) 8px, transparent 8px),
                radial-gradient(circle at 30% 30%, rgba(0, 150, 0, 0.4) 12px, transparent 12px),
                radial-gradient(circle at 50% 10%, rgba(0, 150, 0, 0.4) 10px, transparent 10px),
                radial-gradient(circle at 70% 25%, rgba(0, 150, 0, 0.4) 11px, transparent 11px),
                radial-gradient(circle at 90% 15%, rgba(0, 150, 0, 0.4) 9px, transparent 9px);
        }
        
        .container {
            display: flex;
            max-width: 1300px;
            margin: 0 auto;
            gap: 30px;
            height: calc(100vh - 120px);
        }
        
        header {
            text-align: center;
            margin-bottom: 20px;
            padding: 15px;
            background: rgba(0, 20, 40, 0.7);
            border-radius: 12px;
            box-shadow: 0 0 15px rgba(0, 200, 255, 0.3);
            position: relative;
            z-index: 1;
            border: 1px solid rgba(0, 200, 255, 0.3);
            height: 80px;
            display: flex;
            flex-direction: column;
            justify-content: center;
        }
        
        h1 {
            font-size: 2.2rem;
            background: linear-gradient(90deg, #00e5ff, #00ffaa, #00e5ff);
            -webkit-background-clip: text;
            background-clip: text;
            color: transparent;
            text-shadow: 0 0 10px rgba(0, 200, 255, 0.5);
            letter-spacing: 2px;
            animation: glow 2s ease-in-out infinite alternate;
        }
        
        @keyframes glow {
            0% {
                text-shadow: 0 0 10px rgba(0, 200, 255, 0.5),
                             0 0 20px rgba(0, 200, 255, 0.3),
                             0 0 30px rgba(0, 200, 255, 0.2);
            }
            100% {
                text-shadow: 0 0 15px rgba(0, 200, 255, 0.8),
                             0 0 25px rgba(0, 200, 255, 0.5),
                             0 0 35px rgba(0, 200, 255, 0.3);
            }
        }
        
        .map-container {
            flex: 1.2;
            background: rgba(10, 25, 47, 0.8);
            border-radius: 15px;
            padding: 25px;
            box-shadow: 0 0 25px rgba(0, 150, 255, 0.2);
            position: relative;
            overflow: hidden;
            border: 1px solid rgba(0, 200, 255, 0.2);
            display: flex;
            flex-direction: column;
        }
        
        .map-container::before {
            content: "";
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            border: 1px solid rgba(0, 200, 255, 0.1);
            border-radius: 15px;
            pointer-events: none;
        }
        
        .compass {
            position: relative;
            width: 380px;
            height: 380px;
            margin: 0 auto 20px;
            background: rgba(5, 15, 30, 0.9);
            border-radius: 50%;
            box-shadow: 0 0 20px rgba(0, 200, 255, 0.3);
            border: 1px solid rgba(0, 200, 255, 0.2);
            flex-shrink: 0;
        }
        
        .compass-center {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            width: 30px;
            height: 30px;
            background: rgba(0, 50, 100, 0.9);
            border-radius: 50%;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            z-index: 10;
            box-shadow: 0 0 8px rgba(0, 200, 255, 0.5);
        }
        
        .drone-icon {
            width: 20px;
            height: 20px;
            filter: invert(70%) sepia(50%) saturate(500%) hue-rotate(160deg);
        }
        
        .compass-center span {
            font-size: 0.7rem;
            color: #80deea;
            margin-top: 2px;
        }
        
        .compass-direction {
            position: absolute;
            font-weight: bold;
            color: #4fc3f7;
            text-shadow: 0 0 5px rgba(79, 195, 247, 0.7);
            font-size: 1.1rem;
        }
        
        .north {
            top: 15px;
            left: 50%;
            transform: translateX(-50%);
        }
        
        .south {
            bottom: 15px;
            left: 50%;
            transform: translateX(-50%);
        }
        
        .east {
            right: 15px;
            top: 50%;
            transform: translateY(-50%);
        }
        
        .west {
            left: 15px;
            top: 50%;
            transform: translateY(-50%);
        }
        
        .compass-line {
            position: absolute;
            background: rgba(79, 195, 247, 0.3);
        }
        
        .vertical {
            width: 1px;
            height: 100%;
            left: 50%;
            top: 0;
        }
        
        .horizontal {
            width: 100%;
            height: 1px;
            top: 50%;
            left: 0;
        }
        
        .park {
            position: absolute;
            width: 14px;
            height: 14px;
            border-radius: 50%;
            background: radial-gradient(circle, #00c853, #006400);
            cursor: pointer;
            box-shadow: 0 0 8px rgba(0, 200, 83, 0.7);
            transition: transform 0.3s, box-shadow 0.3s;
            z-index: 5;
        }
        
        .park:hover {
            transform: scale(1.3);
            box-shadow: 0 0 12px rgba(0, 255, 100, 0.9);
        }
        
        .park-label {
            position: absolute;
            font-size: 0.8rem;
            white-space: nowrap;
            background: rgba(0, 20, 40, 0.8);
            padding: 3px 8px;
            border-radius: 4px;
            pointer-events: none;
            opacity: 0.9;
            border: 1px solid rgba(255, 255, 255, 0.2);
        }
        
        #xiangmi .park-label {
            color: #ff6b6b;
            font-family: 'Microsoft YaHei', sans-serif;
            font-weight: bold;
        }
        
        #lianhua .park-label {
            color: #ffe66d;
            font-family: 'KaiTi', cursive;
        }
        
        #huanggang .park-label {
            color: #ff9ff3;
            font-family: 'SimHei', sans-serif;
            font-weight: bold;
        }
        
        .connection-line {
            position: absolute;
            border-top: 2px dashed rgba(0, 230, 255, 0.7);
            transform-origin: 0 0;
            z-index: 1;
            pointer-events: none;
        }
        
        .distance-label {
            position: absolute;
            color: #00e5ff;
            font-size: 0.8rem;
            background: rgba(0, 20, 40, 0.7);
            padding: 3px 8px;
            border-radius: 4px;
            pointer-events: none;
            border: 1px solid rgba(0, 200, 255, 0.3);
        }
        
        .angle-label {
            position: absolute;
            color: #ff4081;
            font-size: 0.8rem;
            background: rgba(0, 20, 40, 0.7);
            padding: 3px 8px;
            border-radius: 4px;
            pointer-events: none;
            border: 1px solid rgba(255, 64, 129, 0.3);
        }
        
        .angle-arc {
            position: absolute;
            border: 2px solid rgba(255, 64, 129, 0.7);
            border-radius: 50%;
            pointer-events: none;
            z-index: 2;
        }
        
        .drone {
            position: absolute;
            width: 40px;
            height: 40px;
            z-index: 20;
            pointer-events: none;
            filter: invert(70%) sepia(50%) saturate(500%) hue-rotate(160deg);
            transition: all 0.1s linear;
            transform-origin: center;
        }
        
        .scale-container {
            display: flex;
            align-items: center;
            justify-content: center;
            margin-top: 15px;
            padding: 8px;
            background: rgba(0, 20, 40, 0.7);
            border-radius: 6px;
            border: 1px solid rgba(0, 200, 255, 0.3);
        }
        
        .scale-line {
            width: 50px;
            height: 6px;
            background: linear-gradient(90deg, #00e5ff, #00ffaa);
            position: relative;
            margin: 0 10px;
            box-shadow: 0 0 8px rgba(0, 200, 255, 0.5);
        }
        
        .scale-line::before, .scale-line::after {
            content: "";
            position: absolute;
            width: 2px;
            height: 12px;
            background: #00e5ff;
            top: -3px;
        }
        
        .scale-line::before {
            left: 0;
        }
        
        .scale-line::after {
            right: 0;
        }
        
        .scale-label {
            color: #80deea;
            font-size: 0.9rem;
            white-space: nowrap;
        }
        
        .map-info {
            margin-top: 10px;
            text-align: center;
            font-size: 0.9rem;
            color: #80deea;
        }
        
        .park-buttons {
            display: flex;
            justify-content: space-between;
            margin-top: 15px;
            gap: 10px;
        }
        
        .park-btn {
            flex: 1;
            padding: 8px 5px;
            background: rgba(0, 50, 100, 0.7);
            border: 1px solid rgba(0, 200, 255, 0.3);
            border-radius: 5px;
            color: #e0f7fa;
            cursor: pointer;
            transition: all 0.3s;
            font-size: 0.8rem;
            text-align: center;
            box-shadow: 0 0 5px rgba(0, 200, 255, 0.3);
        }
        
        .park-btn:hover {
            background: rgba(0, 100, 200, 0.7);
            box-shadow: 0 0 10px rgba(0, 200, 255, 0.5);
        }
        
        .park-btn.active {
            background: rgba(0, 150, 255, 0.7);
            box-shadow: 0 0 15px rgba(0, 200, 255, 0.7);
        }
        
        .question-container {
            flex: 1;
            background: rgba(10, 25, 47, 0.8);
            border-radius: 15px;
            padding: 20px;
            box-shadow: 0 0 25px rgba(0, 150, 255, 0.2);
            display: flex;
            flex-direction: column;
            border: 1px solid rgba(0, 200, 255, 0.2);
        }
        
        .question-box {
            background: rgba(5, 15, 30, 0.9);
            border-radius: 10px;
            padding: 20px;
            margin-bottom: 20px;
            min-height: 150px;
            box-shadow: 0 0 15px rgba(0, 200, 255, 0.2);
            border: 1px solid rgba(0, 200, 255, 0.1);
        }
        
        .question-title {
            font-size: 1.2rem;
            color: #4fc3f7;
            margin-bottom: 15px;
            text-shadow: 0 0 5px rgba(79, 195, 247, 0.5);
        }
        
        .question-text {
            font-size: 1.1rem;
            line-height: 1.6;
            color: #e0f7fa;
        }
        
        .blank {
            display: inline-block;
            min-width: 80px;
            height: 35px;
            background: rgba(0, 50, 100, 0.7);
            border: 2px solid #00e5ff;
            border-radius: 5px;
            margin: 0 5px;
            text-align: center;
            line-height: 35px;
            color: #00e5ff;
            cursor: pointer;
            transition: all 0.2s;
            box-shadow: 0 0 5px rgba(0, 200, 255, 0.3);
        }
        
        .blank.active {
            background: rgba(0, 100, 200, 0.7);
            box-shadow: 0 0 10px rgba(0, 200, 255, 0.5);
            border-color: #00ffaa;
        }
        
        .keyboard {
            display: grid;
            grid-template-columns: repeat(10, 1fr);
            gap: 8px;
            margin-bottom: 20px;
        }
        
        .key {
            background: rgba(0, 50, 100, 0.7);
            border: none;
            border-radius: 5px;
            color: #e0f7fa;
            padding: 10px 5px;
            font-size: 0.9rem;
            cursor: pointer;
            transition: all 0.2s;
            box-shadow: 0 0 5px rgba(0, 200, 255, 0.3);
            border: 1px solid rgba(0, 200, 255, 0.2);
        }
        
        .key:hover {
            background: rgba(0, 100, 200, 0.7);
            box-shadow: 0 0 10px rgba(0, 200, 255, 0.5);
        }
        
        .key:active {
            transform: scale(0.95);
            background: rgba(0, 150, 255, 0.7);
        }
        
        .action-buttons {
            display: flex;
            gap: 15px;
        }
        
        .action-btn {
            flex: 1;
            padding: 12px;
            border: none;
            border-radius: 8px;
            font-size: 1rem;
            font-weight: bold;
            cursor: pointer;
            transition: all 0.3s;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
        }
        
        .confirm {
            background: linear-gradient(135deg, #00c853, #009624);
            color: white;
        }
        
        .delete {
            background: linear-gradient(135deg, #ff9100, #ff6d00);
            color: white;
        }
        
        .clear {
            background: linear-gradient(135deg, #ff1744, #d50000);
            color: white;
        }
        
        .action-btn:hover {
            transform: translateY(-2px);
            box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
        }
        
        .action-btn:active {
            transform: translateY(0);
        }
        
        .answer-display {
            margin-top: 20px;
            padding: 15px;
            background: rgba(5, 15, 30, 0.9);
            border-radius: 10px;
            min-height: 60px;
            font-size: 1.2rem;
            color: #00e5ff;
            box-shadow: 0 0 10px rgba(0, 200, 255, 0.2);
            display: flex;
            flex-wrap: wrap;
            align-items: center;
            border: 1px solid rgba(0, 200, 255, 0.2);
        }
        
        .feedback {
            margin-top: 15px;
            padding: 10px;
            border-radius: 8px;
            text-align: center;
            font-weight: bold;
            opacity: 0;
            transition: opacity 0.5s;
            border: 1px solid rgba(255, 255, 255, 0.1);
        }
        
        .correct {
            background: rgba(0, 200, 83, 0.2);
            color: #00e5ff;
            opacity: 1;
            border-color: rgba(0, 200, 83, 0.3);
        }
        
        .incorrect {
            background: rgba(255, 23, 68, 0.2);
            color: #ff4081;
            opacity: 1;
            border-color: rgba(255, 23, 68, 0.3);
        }
        
        @media (max-width: 900px) {
            .container {
                flex-direction: column;
            }
            
            .keyboard {
                grid-template-columns: repeat(6, 1fr);
            }
        }
    </style>
</head>
<body>
    <div class="tech-grid"></div>
    <div class="scan-line"></div>
    <div class="grass-bg"></div>
    
    <header>
        <h1>深圳—天空之城</h1>
    </header>
    
    <div class="container">
        <div class="map-container">
            <div class="compass">
                <div class="compass-line vertical"></div>
                <div class="compass-line horizontal"></div>
                
                <div class="compass-direction north">北</div>
                <div class="compass-direction south">南</div>
                <div class="compass-direction east">东</div>
                <div class="compass-direction west">西</div>
                
                <div class="compass-center">
                    <svg class="drone-icon" viewBox="0 0 100 100">
                        <path d="M50,10 L60,30 L70,30 L60,50 L50,70 L40,50 L30,30 L40,30 Z" fill="#00e5ff"/>
                        <circle cx="50" cy="50" r="5" fill="#00e5ff"/>
                        <circle cx="35" cy="35" r="3" fill="#00e5ff"/>
                        <circle cx="65" cy="35" r="3" fill="#00e5ff"/>
                        <circle cx="35" cy="65" r="3" fill="#00e5ff"/>
                        <circle cx="65" cy="65" r="3" fill="#00e5ff"/>
                    </svg>
                    <span>基地</span>
                </div>
                
                <svg class="drone" id="drone" viewBox="0 0 100 100" style="display: none;">
                    <path d="M50,10 L60,30 L70,30 L60,50 L50,70 L40,50 L30,30 L40,30 Z" fill="#00e5ff"/>
                    <circle cx="50" cy="50" r="5" fill="#00e5ff"/>
                    <circle cx="35" cy="35" r="3" fill="#00e5ff"/>
                    <circle cx="65" cy="35" r="3" fill="#00e5ff"/>
                    <circle cx="35" cy="65" r="3" fill="#00e5ff"/>
                    <circle cx="65" cy="65" r="3" fill="#00e5ff"/>
                </svg>
                
                <div class="park" id="xiangmi" style="top: 20%; left: 55%; display: none;">
                    <div class="park-label" style="top: -25px; left: -10px;">香蜜湖公园</div>
                </div>
                
                <div class="park" id="lianhua" style="top: 35%; left: 65%; display: none;">
                    <div class="park-label" style="top: -25px; left: -10px;">莲花山公园</div>
                </div>
                
                <div class="park" id="huanggang" style="top: 70%; left: 30%; display: none;">
                    <div class="park-label" style="top: 20px; left: -10px;">皇岗公园</div>
                </div>
            </div>
            
            <div class="scale-container">
                <div class="scale-line"></div>
                <div class="scale-label">图上1厘米表示实际距离1千米</div>
            </div>
            
            <div class="park-buttons">
                <button class="park-btn" data-park="xiangmi">香蜜湖公园</button>
                <button class="park-btn" data-park="lianhua">莲花山公园</button>
                <button class="park-btn" data-park="huanggang">皇岗公园</button>
            </div>
            
            <div class="map-info">
                <p>请点击下方按钮选择公园并回答问题</p>
            </div>
        </div>
        
        <div class="question-container">
            <div class="question-box">
                <div class="question-title">当前问题</div>
                <div class="question-text" id="question-text">
                    请点击下方按钮选择公园开始答题
                </div>
            </div>
            
            <div class="answer-display" id="answer-display">
                您的答案将显示在这里
            </div>
            
            <div class="keyboard">
                <button class="key" data-key="东">东</button>
                <button class="key" data-key="南">南</button>
                <button class="key" data-key="西">西</button>
                <button class="key" data-key="北">北</button>
                <button class="key" data-key="偏">偏</button>
                <button class="key" data-key="度">度</button>
                <button class="key" data-key="米">米</button>
                <button class="key" data-key="千米">千米</button>
                <button class="key" data-key="1">1</button>
                <button class="key" data-key="2">2</button>
                <button class="key" data-key="3">3</button>
                <button class="key" data-key="4">4</button>
                <button class="key" data-key="5">5</button>
                <button class="key" data-key="6">6</button>
                <button class="key" data-key="7">7</button>
                <button class="key" data-key="8">8</button>
                <button class="key" data-key="9">9</button>
                <button class="key" data-key="0">0</button>
            </div>
            
            <div class="action-buttons">
                <button class="action-btn confirm" id="confirm-btn">确认</button>
                <button class="action-btn delete" id="delete-btn">删除</button>
                <button class="action-btn clear" id="clear-btn">清空</button>
            </div>
            
            <div class="feedback" id="feedback"></div>
        </div>
    </div>

    <script>
        document.addEventListener('DOMContentLoaded', function() {
            const parks = {
                xiangmi: {
                    name: '香蜜湖公园',
                    angle: '北偏东10度',
                    distance: 6,
                    mapDistance: '6厘米',
                    question: '香蜜湖公园在基地的<span class="blank" data-index="0">□</span>,距离<span class="blank" data-index="1">□</span>。',
                    answers: [
                        '北偏东10度,距离6千米',
                        '北偏东10度,距离6000米'
                    ],
                    baseAngle: 0,
                    offsetAngle: 10,
                    position: { top: '20%', left: '55%' },
                    namePosition: { top: '-25px', left: '-10px' },
                    distancePosition: { xOffset: 0.6, yOffset: 0.6 },
                    anglePosition: { radius: 65, offset: 5 }
                },
                lianhua: {
                    name: '莲花山公园',
                    angle: '北偏东60度',
                    distance: 4,
                    mapDistance: '4厘米',
                    question: '莲花山公园在基地的<span class="blank" data-index="0">□</span>,距离<span class="blank" data-index="1">□</span>。',
                    answers: [
                        '北偏东60度,距离4千米',
                        '北偏东60度,距离4000米'
                    ],
                    baseAngle: 0,
                    offsetAngle: 60,
                    position: { top: '35%', left: '65%' },
                    namePosition: { top: '-25px', left: '-10px' },
                    distancePosition: { xOffset: 0.4, yOffset: 0.4 },
                    anglePosition: { radius: 65, offset: 30 }
                },
                huanggang: {
                    name: '皇岗公园',
                    angle: '南偏西45度',
                    distance: 7,
                    mapDistance: '7厘米',
                    question: '皇岗公园在基地的<span class="blank" data-index="0">□</span>,距离<span class="blank" data-index="1">□</span>。',
                    answers: [
                        '南偏西45度,距离7千米',
                        '南偏西45度,距离7000米'
                    ],
                    baseAngle: 180,
                    offsetAngle: 45,
                    position: { top: '70%', left: '30%' },
                    namePosition: { top: '20px', left: '-10px' },
                    distancePosition: { xOffset: 0.5, yOffset: 0.5 },
                    anglePosition: { radius: 65, offset: -22.5 }
                }
            };
            
            let currentPark = null;
            let userAnswer = ['', ''];
            let activeBlankIndex = 0;
            
            const questionText = document.getElementById('question-text');
            const answerDisplay = document.getElementById('answer-display');
            const feedback = document.getElementById('feedback');
            const confirmBtn = document.getElementById('confirm-btn');
            const deleteBtn = document.getElementById('delete-btn');
            const clearBtn = document.getElementById('clear-btn');
            const keys = document.querySelectorAll('.key');
            const parkBtns = document.querySelectorAll('.park-btn');
            const drone = document.getElementById('drone');
            const parksElements = document.querySelectorAll('.park');
            
            parkBtns.forEach(btn => {
                btn.addEventListener('click', function() {
                    const parkId = this.getAttribute('data-park');
                    selectPark(parkId);
                    
                    parkBtns.forEach(b => b.classList.remove('active'));
                    this.classList.add('active');
                });
            });
            
            function selectPark(parkId) {
                parksElements.forEach(park => {
                    park.style.display = 'none';
                });
                
                document.querySelectorAll('.connection-line, .distance-label, .angle-label, .angle-arc, svg').forEach(el => {
                    if (el.id !== 'drone') el.remove();
                });
                
                currentPark = parks[parkId];
                
                const selectedPark = document.getElementById(parkId);
                selectedPark.style.display = 'block';
                
                questionText.innerHTML = currentPark.question;
                
                feedback.className = 'feedback';
                feedback.textContent = '';
                
                userAnswer = ['', ''];
                updateAnswerDisplay();
                
                document.querySelectorAll('.blank').forEach(blank => {
                    blank.addEventListener('click', function() {
                        document.querySelectorAll('.blank').forEach(b => {
                            b.classList.remove('active');
                        });
                        
                        this.classList.add('active');
                        activeBlankIndex = parseInt(this.getAttribute('data-index'));
                    });
                });
                
                if (document.querySelector('.blank')) {
                    document.querySelector('.blank').classList.add('active');
                    activeBlankIndex = 0;
                }
                
                drawConnection(parkId);
                
                playSound('click');
            }
            
            function drawConnection(parkId) {
                const park = document.getElementById(parkId);
                const compass = document.querySelector('.compass');
                const center = document.querySelector('.compass-center');
                
                const centerRect = center.getBoundingClientRect();
                const parkRect = park.getBoundingClientRect();
                const compassRect = compass.getBoundingClientRect();
                
                const centerX = centerRect.left + centerRect.width/2 - compassRect.left;
                const centerY = centerRect.top + centerRect.height/2 - compassRect.top;
                const parkX = parkRect.left + parkRect.width/2 - compassRect.left;
                const parkY = parkRect.top + parkRect.height/2 - compassRect.top;
                
                const dx = parkX - centerX;
                const dy = parkY - centerY;
                const distance = Math.sqrt(dx*dx + dy*dy);
                let angle = Math.atan2(dy, dx) * 180 / Math.PI;
                if (angle < 0) angle += 360;
                
                const line = document.createElement('div');
                line.className = 'connection-line';
                line.style.width = `${distance}px`;
                line.style.left = `${centerX}px`;
                line.style.top = `${centerY}px`;
                line.style.transform = `rotate(${angle}deg)`;
                
                const distanceLabel = document.createElement('div');
                distanceLabel.className = 'distance-label';
                distanceLabel.textContent = `${parks[parkId].mapDistance}`;
                
                let distanceX, distanceY;
                if (parkId === 'xiangmi') {
                    distanceX = centerX + dx * 0.6;
                    distanceY = centerY + dy * 0.6 - 15;
                } else if (parkId === 'lianhua') {
                    distanceX = centerX + dx * 0.4;
                    distanceY = centerY + dy * 0.4 - 15;
                } else if (parkId === 'huanggang') {
                    // 皇岗公园:7厘米标签向西移动1厘米
                    const distanceAngle = 180 + 60;
                    const distanceRadius = distance * 0.5;
                    
                    distanceX = centerX + Math.cos((distanceAngle - 90) * Math.PI / 180) * distanceRadius - 19; // 向西移动1厘米(19px)
                    distanceY = centerY + Math.sin((distanceAngle - 90) * Math.PI / 180) * distanceRadius;
                }
                
                distanceLabel.style.left = `${distanceX}px`;
                distanceLabel.style.top = `${distanceY}px`;
                
                const angleLabel = document.createElement('div');
                angleLabel.className = 'angle-label';
                
                if (parkId === 'xiangmi') {
                    angleLabel.textContent = '10°';
                } else if (parkId === 'lianhua') {
                    angleLabel.textContent = '60°';
                } else if (parkId === 'huanggang') {
                    angleLabel.textContent = '45°';
                }
                
                const arc = document.createElement('div');
                arc.className = 'angle-arc';
                
                const baseAngle = parks[parkId].baseAngle;
                const offsetAngle = parks[parkId].offsetAngle;
                const arcRadius = 50;
                
                arc.style.width = `${arcRadius * 2}px`;
                arc.style.height = `${arcRadius * 2}px`;
                arc.style.left = `${centerX - arcRadius}px`;
                arc.style.top = `${centerY - arcRadius}px`;
                
                arc.style.borderTop = 'none';
                arc.style.borderRight = 'none';
                arc.style.borderBottom = 'none';
                arc.style.borderLeft = 'none';
                
                createSVGArc(compass, centerX, centerY, arcRadius, baseAngle, offsetAngle, parkId, angleLabel);
                
                compass.appendChild(line);
                compass.appendChild(distanceLabel);
                compass.appendChild(angleLabel);
                compass.appendChild(arc);
            }
            
            function createSVGArc(container, centerX, centerY, radius, startAngle, endAngle, parkId, angleLabel) {
                const svgNS = "http://www.w3.org/2000/svg";
                const svg = document.createElementNS(svgNS, "svg");
                svg.setAttribute("width", "380");
                svg.setAttribute("height", "380");
                svg.setAttribute("style", "position: absolute; top: 0; left: 0; pointer-events: none;");
                
                let startRad, endRad;
                
                if (parkId === 'huanggang') {
                    startRad = (180 - 90) * Math.PI / 180;
                    endRad = ((180 + 45) - 90) * Math.PI / 180;
                } else if (parkId === 'lianhua') {
                    startRad = (startAngle - 90) * Math.PI / 180;
                    endRad = ((startAngle + 60) - 90) * Math.PI / 180;
                } else {
                    startRad = (startAngle - 90) * Math.PI / 180;
                    endRad = ((startAngle + endAngle) - 90) * Math.PI / 180;
                }
                
                const startX = centerX + radius * Math.cos(startRad);
                const startY = centerY + radius * Math.sin(startRad);
                const endX = centerX + radius * Math.cos(endRad);
                const endY = centerY + radius * Math.sin(endRad);
                
                const path = document.createElementNS(svgNS, "path");
                const largeArcFlag = endAngle > 180 ? 1 : 0;
                
                let d = `M ${startX} ${startY} A ${radius} ${radius} 0 ${largeArcFlag} 1 ${endX} ${endY}`;
                
                path.setAttribute("d", d);
                path.setAttribute("fill", "none");
                path.setAttribute("stroke", "rgba(255, 64, 129, 0.7)");
                path.setAttribute("stroke-width", "2");
                
                svg.appendChild(path);
                container.appendChild(svg);
                
                // 优化角度标签位置
                let labelAngle;
                let labelRadius;
                
                if (parkId === 'huanggang') {
                    // 皇岗公园:45°标签向西北方向移动1厘米
                    labelAngle = 180 + 20; // 南偏西20度
                    labelRadius = 80; // 4厘米对应80px
                    
                    // 向西北方向移动1厘米(19px)
                    const moveAngle = 180 + 45 + 135; // 西北方向角度
                    const moveDistance = 19; // 1厘米
                    
                    const baseX = centerX + Math.cos((labelAngle - 90) * Math.PI / 180) * labelRadius;
                    const baseY = centerY + Math.sin((labelAngle - 90) * Math.PI / 180) * labelRadius;
                    
                    const finalX = baseX + Math.cos((moveAngle - 90) * Math.PI / 180) * moveDistance;
                    const finalY = baseY + Math.sin((moveAngle - 90) * Math.PI / 180) * moveDistance;
                    
                    angleLabel.style.left = `${finalX}px`;
                    angleLabel.style.top = `${finalY}px`;
                    return; // 提前返回,不使用通用计算
                } else if (parkId === 'lianhua') {
                    // 莲花山公园:60°标签向西移动1厘米
                    labelAngle = 0 + 30; // 北偏东30度
                    labelRadius = 57; // 3厘米对应57px
                    
                    // 向西移动1厘米(19px)
                    const baseX = centerX + Math.cos((labelAngle - 90) * Math.PI / 180) * labelRadius;
                    const baseY = centerY + Math.sin((labelAngle - 90) * Math.PI / 180) * labelRadius;
                    
                    const finalX = baseX - 19; // 向西移动
                    const finalY = baseY;
                    
                    angleLabel.style.left = `${finalX}px`;
                    angleLabel.style.top = `${finalY}px`;
                    return; // 提前返回,不使用通用计算
                } else {
                    labelAngle = startAngle + endAngle/2;
                    labelRadius = 65;
                }
                
                if (parkId === 'xiangmi') {
                    labelRadius = 60;
                }
                
                const labelX = centerX + Math.cos((labelAngle - 90) * Math.PI / 180) * labelRadius;
                const labelY = centerY + Math.sin((labelAngle - 90) * Math.PI / 180) * labelRadius;
                
                angleLabel.style.left = `${labelX}px`;
                angleLabel.style.top = `${labelY}px`;
            }
            
            function flyDroneToPark(parkId) {
                const park = document.getElementById(parkId);
                const compass = document.querySelector('.compass');
                const compassRect = compass.getBoundingClientRect();
                const parkRect = park.getBoundingClientRect();
                const center = document.querySelector('.compass-center');
                const centerRect = center.getBoundingClientRect();
                
                const startX = centerRect.left + centerRect.width/2 - compassRect.left - 20;
                const startY = centerRect.top + centerRect.height/2 - compassRect.top - 20;
                const endX = parkRect.left + parkRect.width/2 - compassRect.left - 20;
                const endY = parkRect.top + parkRect.height/2 - compassRect.top - 20;
                
                drone.style.display = 'block';
                drone.style.left = `${startX}px`;
                drone.style.top = `${startY}px`;
                
                const dx = endX - startX;
                const dy = endY - startY;
                const angle = Math.atan2(dy, dx) * 180 / Math.PI;
                drone.style.transform = `rotate(${angle}deg)`;
                
                playSound('drone');
                
                let progress = 0;
                const duration = 2000;
                const startTime = Date.now();
                
                function animateDrone() {
                    const currentTime = Date.now();
                    progress = (currentTime - startTime) / duration;
                    
                    if (progress < 1) {
                        const currentX = startX + dx * progress;
                        const currentY = startY + dy * progress;
                        
                        drone.style.left = `${currentX}px`;
                        drone.style.top = `${currentY}px`;
                        
                        requestAnimationFrame(animateDrone);
                    } else {
                        setTimeout(() => {
                            returnDroneToBase(startX, startY, dx, dy);
                        }, 1000);
                    }
                }
                
                animateDrone();
            }
            
            function returnDroneToBase(startX, startY, dx, dy) {
                let progress = 1;
                const duration = 2000;
                const startTime = Date.now();
                
                function animateReturn() {
                    const currentTime = Date.now();
                    progress = 1 - (currentTime - startTime) / duration;
                    
                    if (progress > 0) {
                        const currentX = startX + dx * progress;
                        const currentY = startY + dy * progress;
                        
                        drone.style.left = `${currentX}px`;
                        drone.style.top = `${currentY}px`;
                        
                        requestAnimationFrame(animateReturn);
                    } else {
                        drone.style.display = 'none';
                    }
                }
                
                animateReturn();
            }
            
            keys.forEach(key => {
                key.addEventListener('click', function() {
                    if (!currentPark) {
                        alert('请先选择一个公园!');
                        return;
                    }
                    
                    const keyValue = this.getAttribute('data-key');
                    userAnswer[activeBlankIndex] += keyValue;
                    updateAnswerDisplay();
                    
                    playSound('keypress');
                    
                    this.style.transform = 'scale(0.9)';
                    setTimeout(() => {
                        this.style.transform = '';
                    }, 100);
                });
            });
            
            function updateAnswerDisplay() {
                document.querySelectorAll('.blank').forEach((blank, index) => {
                    blank.textContent = userAnswer[index] || '□';
                });
                
                answerDisplay.textContent = userAnswer.join(' ') || '您的答案将显示在这里';
            }
            
            deleteBtn.addEventListener('click', function() {
                if (userAnswer[activeBlankIndex].length > 0) {
                    userAnswer[activeBlankIndex] = userAnswer[activeBlankIndex].slice(0, -1);
                    updateAnswerDisplay();
                    
                    playSound('delete');
                }
            });
            
            clearBtn.addEventListener('click', function() {
                userAnswer[activeBlankIndex] = '';
                updateAnswerDisplay();
                
                playSound('clear');
            });
            
            confirmBtn.addEventListener('click', function() {
                if (!currentPark) {
                    alert('请先选择一个公园!');
                    return;
                }
                
                if (!userAnswer[0] || !userAnswer[1]) {
                    alert('请完成所有填空!');
                    return;
                }
                
                const userAnswerStr = userAnswer.join(',距离') + '';
                let isCorrect = false;
                
                for (const correctAnswer of currentPark.answers) {
                    const normalizedUserAnswer = userAnswerStr.replace(/\s/g, '');
                    const normalizedCorrectAnswer = correctAnswer.replace(/\s/g, '');
                    
                    if (normalizedUserAnswer === normalizedCorrectAnswer) {
                        isCorrect = true;
                        break;
                    }
                }
                
                if (isCorrect) {
                    feedback.className = 'feedback correct';
                    feedback.textContent = '回答正确!无人机已起飞前往目标公园!';
                    playSound('correct');
                    
                    const activeParkBtn = document.querySelector('.park-btn.active');
                    if (activeParkBtn) {
                        const parkId = activeParkBtn.getAttribute('data-park');
                        flyDroneToPark(parkId);
                    }
                } else {
                    feedback.className = 'feedback incorrect';
                    feedback.textContent = `回答错误!正确答案是:${currentPark.answers[0]} 或 ${currentPark.answers[1]}`;
                    playSound('incorrect');
                }
            });
            
            function playSound(type) {
                const audioContext = new (window.AudioContext || window.webkitAudioContext)();
                
                let oscillator = audioContext.createOscillator();
                let gainNode = audioContext.createGain();
                
                oscillator.connect(gainNode);
                gainNode.connect(audioContext.destination);
                
                switch(type) {
                    case 'click':
                        oscillator.frequency.setValueAtTime(800, audioContext.currentTime);
                        gainNode.gain.setValueAtTime(0.3, audioContext.currentTime);
                        oscillator.type = 'sine';
                        break;
                    case 'keypress':
                        oscillator.frequency.setValueAtTime(600, audioContext.currentTime);
                        gainNode.gain.setValueAtTime(0.2, audioContext.currentTime);
                        oscillator.type = 'square';
                        break;
                    case 'delete':
                        oscillator.frequency.setValueAtTime(400, audioContext.currentTime);
                        gainNode.gain.setValueAtTime(0.2, audioContext.currentTime);
                        oscillator.type = 'sawtooth';
                        break;
                    case 'clear':
                        oscillator.frequency.setValueAtTime(300, audioContext.currentTime);
                        gainNode.gain.setValueAtTime(0.3, audioContext.currentTime);
                        oscillator.type = 'triangle';
                        break;
                    case 'correct':
                        oscillator.frequency.setValueAtTime(523.25, audioContext.currentTime);
                        oscillator.frequency.setValueAtTime(659.25, audioContext.currentTime + 0.1);
                        oscillator.frequency.setValueAtTime(783.99, audioContext.currentTime + 0.2);
                        gainNode.gain.setValueAtTime(0.3, audioContext.currentTime);
                        oscillator.type = 'sine';
                        break;
                    case 'incorrect':
                        oscillator.frequency.setValueAtTime(400, audioContext.currentTime);
                        oscillator.frequency.setValueAtTime(300, audioContext.currentTime + 0.1);
                        gainNode.gain.setValueAtTime(0.3, audioContext.currentTime);
                        oscillator.type = 'sawtooth';
                        break;
                    case 'drone':
                        oscillator.frequency.setValueAtTime(150, audioContext.currentTime);
                        oscillator.frequency.setValueAtTime(200, audioContext.currentTime + 0.5);
                        oscillator.frequency.setValueAtTime(250, audioContext.currentTime + 1);
                        gainNode.gain.setValueAtTime(0.4, audioContext.currentTime);
                        oscillator.type = 'sawtooth';
                        break;
                }
                
                oscillator.start();
                
                let duration = 0.2;
                if (type === 'correct') duration = 0.5;
                if (type === 'drone') duration = 2;
                
                gainNode.gain.exponentialRampToValueAtTime(0.001, audioContext.currentTime + duration);
                oscillator.stop(audioContext.currentTime + duration);
            }
        });
    </script>
</body>
</html>
        
编辑器加载中
预览
控制台