🎮ArcadeLab

太阳系战术星图 - 2036

by TurboKoala83
264 lines10.2 KB
▶ Play
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>太阳系战术星图 - 2036</title>
    <style>
        body {
            margin: 0;
            overflow: hidden;
            background-color: #02040a;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            height: 100vh;
            font-family: 'Courier New', monospace;
            color: #e2e8f0;
        }
        #controls {
            position: absolute;
            bottom: 20px;
            z-index: 100;
            background: rgba(15, 23, 42, 0.8);
            padding: 10px 20px;
            border-radius: 8px;
            border: 1px solid #1e3a5f;
            display: flex;
            gap: 20px;
            align-items: center;
            font-size: 12px;
        }
        button {
            background: #1e293b;
            color: #22d3ee;
            border: 1px solid #22d3ee;
            padding: 5px 15px;
            border-radius: 4px;
            cursor: pointer;
            font-family: inherit;
            transition: all 0.2s;
        }
        button:hover {
            background: #22d3ee;
            color: #0f172a;
        }
        .legend {
            display: flex;
            gap: 15px;
        }
        .legend-item {
            display: flex;
            align-items: center;
            gap: 5px;
        }
        .dot {
            width: 8px;
            height: 8px;
            border-radius: 50%;
        }
    </style>
</head>
<body>
    <canvas id="mapCanvas"></canvas>
    
    <div id="controls">
        <button id="btnPause">暂停 / 继续</button>
        <div class="legend">
            <div class="legend-item"><div class="dot" style="background: #3b82f6;"></div>地球/月球</div>
            <div class="legend-item"><div class="dot" style="background: #ef4444;"></div>火星轨道边界</div>
            <div class="legend-item"><div class="dot" style="background: #fbbf24;"></div>太阳</div>
        </div>
    </div>

    <script>
        const canvas = document.getElementById('mapCanvas');
        const ctx = canvas.getContext('2d');
        
        let width, height;
        let centerX, centerY;
        let isPaused = false;
        let time = 0;

        // ---- 配置行星数据 (轨道半径比例,角速度,颜色,大小) ----
        // 为了游戏地图的视觉效果,距离和大小做了夸张处理,并非真实比例
        const planets = [
            { name: '水星', orbitRadius: 80,  speed: 0.030, color: '#9CA3AF', size: 4,  angle: Math.random()*Math.PI*2 },
            { name: '金星', orbitRadius: 120, speed: 0.022, color: '#FDE047', size: 5,  angle: Math.random()*Math.PI*2 },
            { name: '地球', orbitRadius: 170, speed: 0.015, color: '#3B82F6', size: 6,  angle: Math.random()*Math.PI*2, hasMoon: true },
            { name: '火星', orbitRadius: 240, speed: 0.010, color: '#EF4444', size: 5,  angle: Math.random()*Math.PI*2, isBorder: true },
            { name: '木星', orbitRadius: 380, speed: 0.005, color: '#D97706', size: 14, angle: Math.random()*Math.PI*2 },
            { name: '土星', orbitRadius: 520, speed: 0.003, color: '#FCD34D', size: 11, angle: Math.random()*Math.PI*2, hasRing: true }
        ];

        // ---- 星空背景 ----
        const stars = [];
        function initStars() {
            stars.length = 0;
            for (let i = 0; i < 400; i++) {
                stars.push({
                    x: Math.random() * width,
                    y: Math.random() * height,
                    radius: Math.random() * 1.2,
                    alpha: Math.random() * 0.8 + 0.2,
                    twinkleSpeed: Math.random() * 0.02 + 0.01
                });
            }
        }

        // ---- 初始化画布 ----
        function resize() {
            width = canvas.width = window.innerWidth;
            height = canvas.height = window.innerHeight;
            centerX = width / 2;
            centerY = height / 2;
            initStars();
        }
        window.addEventListener('resize', resize);
        resize();

        // ---- 绘图工具函数 ----
        function drawCircle(x, y, r, fillColor, strokeColor, lineWidth) {
            ctx.beginPath();
            ctx.arc(x, y, r, 0, Math.PI * 2);
            if (fillColor) { ctx.fillStyle = fillColor; ctx.fill(); }
            if (strokeColor) { ctx.strokeStyle = strokeColor; ctx.lineWidth = lineWidth || 1; ctx.stroke(); }
        }

        // ---- 主渲染循环 ----
        function render() {
            // 清空画布 (拖尾效果可以去掉,保持清晰)
            ctx.fillStyle = '#02040a';
            ctx.fillRect(0, 0, width, height);

            // 1. 绘制星空
            stars.forEach(star => {
                star.alpha += star.twinkleSpeed;
                if (star.alpha > 1 || star.alpha < 0.1) star.twinkleSpeed *= -1;
                
                ctx.beginPath();
                ctx.arc(star.x, star.y, star.radius, 0, Math.PI * 2);
                ctx.fillStyle = `rgba(255, 255, 255, ${star.alpha})`;
                ctx.fill();
            });

            // 2. 绘制太阳
            const sunGrad = ctx.createRadialGradient(centerX, centerY, 10, centerX, centerY, 50);
            sunGrad.addColorStop(0, '#FEF08A');
            sunGrad.addColorStop(0.5, '#F59E0B');
            sunGrad.addColorStop(1, 'rgba(245, 158, 11, 0)');
            ctx.beginPath();
            ctx.arc(centerX, centerY, 50, 0, Math.PI * 2);
            ctx.fillStyle = sunGrad;
            ctx.fill();
            drawCircle(centerX, centerY, 15, '#FBBF24');

            // 3. 绘制轨道和行星
            planets.forEach(planet => {
                // 轨道线
                ctx.beginPath();
                ctx.arc(centerX, centerY, planet.orbitRadius, 0, Math.PI * 2);
                
                // 如果是火星轨道(人类活动极限边界),用红色虚线强调
                if (planet.isBorder) {
                    ctx.strokeStyle = 'rgba(239, 68, 68, 0.4)';
                    ctx.lineWidth = 2;
                    ctx.setLineDash([8, 8]); // 虚线
                } else {
                    ctx.strokeStyle = 'rgba(71, 85, 105, 0.3)';
                    ctx.lineWidth = 1;
                    ctx.setLineDash([]); // 实线
                }
                ctx.stroke();
                ctx.setLineDash([]); // 重置为实线

                // 计算行星当前位置
                let px = centerX + Math.cos(planet.angle) * planet.orbitRadius;
                let py = centerY + Math.sin(planet.angle) * planet.orbitRadius;

                // 绘制行星拖尾光晕(视觉效果)
                const trailLength = 15;
                for (let i = 0; i < trailLength; i++) {
                    let trailAngle = planet.angle - (i * 0.02 * planet.speed * 10);
                    let tx = centerX + Math.cos(trailAngle) * planet.orbitRadius;
                    let ty = centerY + Math.sin(trailAngle) * planet.orbitRadius;
                    ctx.beginPath();
                    ctx.arc(tx, ty, planet.size * (1 - i/trailLength) * 0.8, 0, Math.PI * 2);
                    ctx.fillStyle = planet.color;
                    ctx.globalAlpha = (1 - i/trailLength) * 0.2;
                    ctx.fill();
                }
                ctx.globalAlpha = 1;

                // 绘制行星本体
                drawCircle(px, py, planet.size, planet.color, 'rgba(255,255,255,0.3)', 1);

                // 如果有光环(土星)
                if (planet.hasRing) {
                    ctx.beginPath();
                    ctx.ellipse(px, py, planet.size * 2.2, planet.size * 0.8, Math.PI / 6, 0, Math.PI * 2);
                    ctx.strokeStyle = 'rgba(252, 211, 77, 0.5)';
                    ctx.lineWidth = 3;
                    ctx.stroke();
                }

                // 地球的月球
                if (planet.hasMoon) {
                    let moonDist = 15;
                    let moonAngle = planet.angle * 8; // 月球公转速度快
                    let mx = px + Math.cos(moonAngle) * moonDist;
                    let my = py + Math.sin(moonAngle) * moonDist;
                    
                    // 绘制月球轨道
                    ctx.beginPath();
                    ctx.arc(px, py, moonDist, 0, Math.PI * 2);
                    ctx.strokeStyle = 'rgba(255,255,255,0.1)';
                    ctx.lineWidth = 1;
                    ctx.stroke();
                    
                    drawCircle(mx, my, 2.5, '#E2E8F0');
                }

                // 军事战略标注(体现2036年的太空战设定)
                if (planet.name === '地球' || planet.name === '火星') {
                    ctx.fillStyle = 'rgba(34, 211, 238, 0.8)';
                    ctx.font = '10px Courier New';
                    ctx.textAlign = 'center';
                    // 在行星下方画一个小小的战术节点光点
                    ctx.beginPath();
                    ctx.arc(px, py + 15, 2, 0, Math.PI * 2);
                    ctx.fillStyle = '#22D3EE';
                    ctx.fill();
                    
                    // 伪代码标注(因为用户要求不用特意标明哪个舱,这里用闪烁光点代替文字,更具游戏UI感)
                    ctx.fillText('◈', px, py + 28); // 用特殊符号表示战略据点
                }

                // 更新行星角度(运动状态)
                if (!isPaused) {
                    planet.angle += planet.speed * 0.02; // 控制整体速度
                }
            });

            // 4. 绘制人类活动边界提示(在火星轨道外画一层淡淡的红色边界线)
            ctx.beginPath();
            ctx.arc(centerX, centerY, 260, 0, Math.PI * 2);
            ctx.strokeStyle = 'rgba(239, 68, 68, 0.1)';
            ctx.lineWidth = 1;
            ctx.stroke();

            requestAnimationFrame(render);
        }

        // ---- 事件监听 ----
        document.getElementById('btnPause').addEventListener('click', () => {
            isPaused = !isPaused;
        });

        // 鼠标滚轮缩放(可选功能,这里暂不实现,保持简单)
        
        // 启动渲染
        render();
    </script>
</body>
</html>

Game Source: 太阳系战术星图 - 2036

Creator: TurboKoala83

Libraries: none

Complexity: complex (264 lines, 10.2 KB)

The full source code is displayed above on this page.

Remix Instructions

To remix this game, copy the source code above and modify it. Add a ARCADELAB header at the top with "remix_of: 2036-turbokoala83" to link back to the original. Then publish at arcadelab.ai/publish.