🎮ArcadeLab

宇宙大战·救援地球

by FrostScout49
516 lines17.7 KB
▶ Play
<!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; }
        body { 
            background: #000; 
            overflow: hidden; 
            font-family: Arial, sans-serif;
            color: white;
            text-align: center;
            height: 100vh;
            width: 100vw;
            user-select: none;
        }
        #game {
            position: relative;
            width: 100%;
            height: 100%;
        }
        canvas {
            display: block;
            background: linear-gradient(to bottom, #0a0a2e, #1a1a4e);
        }
        .ui {
            position: absolute;
            top: 10px;
            left: 10px;
            font-size: 18px;
            text-shadow: 0 0 5px #0ff;
            z-index: 10;
        }
        .health {
            position: absolute;
            top: 10px;
            right: 10px;
            font-size: 18px;
            text-shadow: 0 0 5px #f00;
            z-index: 10;
        }
        .level {
            position: absolute;
            top: 35px;
            left: 10px;
            font-size: 16px;
            text-shadow: 0 0 5px #ff0;
            z-index: 10;
        }
        .msg {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            font-size: 28px;
            font-weight: bold;
            text-shadow: 0 0 15px #fff;
            display: none;
            z-index: 20;
        }
        .hint {
            position: absolute;
            bottom: 10px;
            left: 50%;
            transform: translateX(-50%);
            font-size: 14px;
            color: #aaa;
            z-index: 10;
        }
    </style>
</head>
<body>
    <div id="game">
        <canvas id="c"></canvas>
        <div class="ui">能量: <span id="e">3</span></div>
        <div class="health">护盾: <span id="h">100</span>%</div>
        <div class="level">关卡: <span id="l">第1关 陨石带</span></div>
        <div class="msg" id="m"></div>
        <div class="hint">点左边=闪电号上移 | 点右边=堡垒号上移 | 点中间=发射</div>
    </div>

    <script>
        const c = document.getElementById('c');
        const ctx = c.getContext('2d');
        c.width = window.innerWidth;
        c.height = window.innerHeight;
        
        // 游戏状态
        let gameState = 'playing';
        let level = 1;
        let energy = 3;
        let shield = 100;
        let stars = [];
        let meteors = [];
        let enemies = [];
        let bullets = [];
        let cores = [];
        let blackHole = null;
        let time = 0;
        
        // 玩家飞船
        const player1 = { // 孩子:蓝色闪电号(左边屏幕控制)
            x: c.width * 0.25,
            y: c.height * 0.7,
            width: 40,
            height: 40,
            color: '#0099ff'
        };
        
        const player2 = { // 大人:紫色堡垒号(右边屏幕控制)
            x: c.width * 0.75,
            y: c.height * 0.7,
            width: 50,
            height: 50,
            color: '#9933ff'
        };
        
        // 点击控制(最简单的操作,绝对不会有问题)
        document.addEventListener('click', (e) => {
            if(gameState !== 'playing') return;
            
            const x = e.clientX;
            const midX = c.width / 2;
            
            // 点左边:闪电号上移
            if(x < midX - 50) {
                player1.y = Math.max(0, player1.y - 30);
            }
            // 点右边:堡垒号上移
            else if(x > midX + 50) {
                player2.y = Math.max(0, player2.y - 30);
            }
            // 点中间:发射子弹
            else {
                bullets.push({
                    x: player1.x + player1.width / 2,
                    y: player1.y,
                    speed: 10,
                    color: player1.color
                });
                bullets.push({
                    x: player2.x + player2.width / 2,
                    y: player2.y,
                    speed: 9,
                    color: player2.color
                });
            }
        });
        
        // 初始化星星
        function initStars() {
            stars = [];
            for(let i = 0; i < 100; i++) {
                stars.push({
                    x: Math.random() * c.width,
                    y: Math.random() * c.height,
                    size: Math.random() * 2 + 1,
                    speed: Math.random() * 0.5 + 0.1
                });
            }
        }
        
        // 初始化关卡
        function initLevel(n) {
            meteors = [];
            enemies = [];
            bullets = [];
            cores = [];
            blackHole = null;
            time = 0;
            
            player1.x = c.width * 0.25;
            player1.y = c.height * 0.7;
            player2.x = c.width * 0.75;
            player2.y = c.height * 0.7;
            
            document.getElementById('l').textContent = 
                ['第1关 陨石带', '第2关 太空战', '第3关 堡垒战', '第4关 黑洞战'][n-1];
            showMsg('关卡 ' + n + ' 开始!', 1500);
            
            if(n === 1) {
                for(let i = 0; i < 10; i++) {
                    meteors.push({
                        x: Math.random() * c.width,
                        y: Math.random() * -500,
                        size: Math.random() * 30 + 20,
                        speed: Math.random() * 1.5 + 0.8
                    });
                }
            } else if(n === 2 || n === 3) {
                for(let i = 0; i < 8; i++) {
                    enemies.push({
                        x: Math.random() * c.width,
                        y: Math.random() * -300,
                        width: 30,
                        height: 30,
                        speed: Math.random() * 1.2 + 0.5,
                        hp: n === 3 ? 3 : 2
                    });
                }
            } else if(n === 4) {
                blackHole = {
                    x: c.width / 2,
                    y: c.height * 0.2,
                    radius: 80,
                    angle: 0,
                    active: true
                };
                
                for(let i = 0; i < 8; i++) {
                    const angle = (i / 8) * Math.PI * 2;
                    cores.push({
                        x: blackHole.x + Math.cos(angle) * 140,
                        y: blackHole.y + Math.sin(angle) * 140,
                        num: i + 1,
                        ok: false,
                        radius: 15
                    });
                }
            }
        }
        
        // 显示消息
        function showMsg(text, duration) {
            const el = document.getElementById('m');
            el.textContent = text;
            el.style.display = 'block';
            setTimeout(() => { el.style.display = 'none'; }, duration);
        }
        
        // 更新游戏
        function update() {
            if(gameState !== 'playing') return;
            time++;
            
            // 更新星星
            stars.forEach(star => {
                star.y += star.speed;
                if(star.y > c.height) {
                    star.y = 0;
                    star.x = Math.random() * c.width;
                }
            });
            
            // 飞船自动下落
            player1.y = Math.min(c.height - player1.height, player1.y + 1);
            player2.y = Math.min(c.height - player2.height, player2.y + 1);
            
            // 更新子弹
            bullets = bullets.filter(bullet => {
                bullet.y -= bullet.speed;
                return bullet.y > 0;
            });
            
            // 关卡逻辑
            if(level === 1) {
                meteors.forEach((meteor, index) => {
                    meteor.y += meteor.speed;
                    if(meteor.y > c.height) {
                        meteor.y = Math.random() * -100;
                        meteor.x = Math.random() * c.width;
                    }
                    
                    // 子弹打陨石
                    bullets.forEach((bullet, bIndex) => {
                        const dx = bullet.x - meteor.x;
                        const dy = bullet.y - meteor.y;
                        if(Math.sqrt(dx*dx + dy*dy) < meteor.size / 2) {
                            meteors.splice(index, 1);
                            bullets.splice(bIndex, 1);
                        }
                    });
                    
                    // 撞飞船
                    if(collide(player1, meteor) || collide(player2, meteor)) {
                        shield -= 3;
                        updateUI();
                        meteors.splice(index, 1);
                    }
                });
                if(time > 600) nextLevel();
            } else if(level === 2 || level === 3) {
                enemies.forEach((enemy, index) => {
                    enemy.y += enemy.speed;
                    if(enemy.y > c.height) {
                        enemy.y = Math.random() * -100;
                        enemy.x = Math.random() * c.width;
                    }
                    
                    // 子弹打敌人
                    bullets.forEach((bullet, bIndex) => {
                        if(bullet.x > enemy.x && bullet.x < enemy.x + enemy.width &&
                           bullet.y > enemy.y && bullet.y < enemy.y + enemy.height) {
                            enemy.hp--;
                            bullets.splice(bIndex, 1);
                            if(enemy.hp <= 0) enemies.splice(index, 1);
                        }
                    });
                    
                    // 撞飞船
                    if(collide(player1, enemy) || collide(player2, enemy)) {
                        shield -= 5;
                        updateUI();
                        enemies.splice(index, 1);
                    }
                });
                if(enemies.length === 0 && time > 300) nextLevel();
            } else if(level === 4) {
                blackHole.angle += 0.02;
                if(blackHole.active) {
                    // 护盾减少
                    if(time % 50 === 0) {
                        shield--;
                        updateUI();
                    }
                }
                
                // 破解星核(子弹碰到就破解)
                cores.forEach((core, index) => {
                    if(!core.ok) {
                        bullets.forEach((bullet, bIndex) => {
                            const dx = bullet.x - core.x;
                            const dy = bullet.y - core.y;
                            if(Math.sqrt(dx*dx + dy*dy) < core.radius) {
                                bullets.splice(bIndex, 1);
                                const okNum = cores.filter(c => c.ok).length;
                                if(core.num === okNum + 1) {
                                    core.ok = true;
                                    showMsg('星核 ' + core.num + ' 破解成功!', 1000);
                                } else {
                                    energy--;
                                    updateUI();
                                    showMsg('顺序错了!能量-1', 1000);
                                }
                            }
                        });
                    }
                });
                
                // 全部破解
                if(cores.every(c => c.ok) && blackHole.active) {
                    blackHole.active = false;
                    showMsg('🎉 黑洞净化成功!', 2000);
                    setTimeout(() => {
                        gameState = 'win';
                        showMsg('🌍 地球得救了!恭喜通关!', 10000);
                    }, 2000);
                }
            }
            
            // 游戏结束
            if(shield <= 0 || energy <= 0) {
                gameState = 'lose';
                showMsg('游戏结束!刷新页面重新开始', 10000);
            }
        }
        
        // 碰撞检测
        function collide(obj1, obj2) {
            return obj1.x < obj2.x + (obj2.width || obj2.size) &&
                   obj1.x + obj1.width > obj2.x &&
                   obj1.y < obj2.y + (obj2.height || obj2.size) &&
                   obj1.y + obj1.height > obj2.y;
        }
        
        // 下一关
        function nextLevel() {
            level++;
            if(level > 4) {
                gameState = 'win';
                showMsg('🌍 地球得救了!恭喜通关!', 10000);
            } else {
                showMsg('关卡完成!', 1500);
                setTimeout(() => initLevel(level), 1500);
            }
        }
        
        // 更新UI
        function updateUI() {
            document.getElementById('e').textContent = energy;
            document.getElementById('h').textContent = shield;
        }
        
        // 绘制游戏
        function draw() {
            ctx.clearRect(0, 0, c.width, c.height);
            
            // 画星星
            stars.forEach(star => {
                ctx.fillStyle = '#fff';
                ctx.beginPath();
                ctx.arc(star.x, star.y, star.size, 0, Math.PI * 2);
                ctx.fill();
            });
            
            // 画地球(第4关)
            if(level === 4) {
                ctx.fillStyle = '#00aaff';
                ctx.beginPath();
                ctx.arc(c.width / 2, c.height - 50, 40, 0, Math.PI * 2);
                ctx.fill();
                ctx.fillStyle = '#00ff00';
                ctx.beginPath();
                ctx.arc(c.width / 2 - 10, c.height - 55, 15, 0, Math.PI * 2);
                ctx.fill();
            }
            
            // 画陨石
            meteors.forEach(meteor => {
                ctx.fillStyle = '#888';
                ctx.beginPath();
                ctx.arc(meteor.x, meteor.y, meteor.size / 2, 0, Math.PI * 2);
                ctx.fill();
            });
            
            // 画敌人
            enemies.forEach(enemy => {
                ctx.fillStyle = '#ff0000';
                ctx.fillRect(enemy.x, enemy.y, enemy.width, enemy.height);
                ctx.fillStyle = '#ffff00';
                ctx.fillRect(enemy.x + 6, enemy.y + 6, 7, 7);
                ctx.fillRect(enemy.x + enemy.width - 13, enemy.y + 6, 7, 7);
            });
            
            // 画子弹
            bullets.forEach(bullet => {
                ctx.fillStyle = bullet.color;
                ctx.shadowColor = bullet.color;
                ctx.shadowBlur = 10;
                ctx.fillRect(bullet.x - 2, bullet.y, 4, 10);
                ctx.shadowBlur = 0;
            });
            
            // 画黑洞
            if(blackHole) {
                ctx.save();
                ctx.translate(blackHole.x, blackHole.y);
                ctx.rotate(blackHole.angle);
                
                ctx.strokeStyle = blackHole.active ? '#ff0000' : '#00ffff';
                ctx.lineWidth = 6;
                ctx.shadowColor = blackHole.active ? '#ff0000' : '#00ffff';
                ctx.shadowBlur = 25;
                ctx.beginPath();
                ctx.arc(0, 0, blackHole.radius, 0, Math.PI * 2);
                ctx.stroke();
                
                ctx.fillStyle = '#000';
                ctx.beginPath();
                ctx.arc(0, 0, blackHole.radius - 12, 0, Math.PI * 2);
                ctx.fill();
                
                ctx.shadowBlur = 0;
                ctx.restore();
                
                // 画星核
                cores.forEach(core => {
                    ctx.fillStyle = core.ok ? '#00ff00' : '#ffff00';
                    ctx.shadowColor = core.ok ? '#00ff00' : '#ffff00';
                    ctx.shadowBlur = 15;
                    ctx.beginPath();
                    ctx.arc(core.x, core.y, core.radius, 0, Math.PI * 2);
                    ctx.fill();
                    
                    if(!core.ok) {
                        ctx.fillStyle = '#000';
                        ctx.font = 'bold 16px Arial';
                        ctx.textAlign = 'center';
                        ctx.textBaseline = 'middle';
                        ctx.fillText(core.num, core.x, core.y);
                    }
                    
                    ctx.shadowBlur = 0;
                });
            }
            
            // 画玩家1(蓝色闪电号)
            ctx.fillStyle = player1.color;
            ctx.shadowColor = player1.color;
            ctx.shadowBlur = 15;
            ctx.beginPath();
            ctx.moveTo(player1.x + player1.width / 2, player1.y);
            ctx.lineTo(player1.x, player1.y + player1.height);
            ctx.lineTo(player1.x + player1.width, player1.y + player1.height);
            ctx.closePath();
            ctx.fill();
            ctx.shadowBlur = 0;
            
            // 画玩家2(紫色堡垒号)
            ctx.fillStyle = player2.color;
            ctx.shadowColor = player2.color;
            ctx.shadowBlur = 15;
            ctx.fillRect(player2.x, player2.y, player2.width, player2.height);
            ctx.fillStyle = '#cc66ff';
            ctx.fillRect(player2.x + 10, player2.y + 10, player2.width - 20, player2.height - 20);
            ctx.shadowBlur = 0;
        }
        
        // 游戏循环
        function loop() {
            update();
            draw();
            requestAnimationFrame(loop);
        }
        
        // 启动游戏
        initStars();
        initLevel(level);
        updateUI();
        loop();
    </script>
</body>
</html>

Game Source: 宇宙大战·救援地球

Creator: FrostScout49

Libraries: none

Complexity: complex (516 lines, 17.7 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: -frostscout49-mq39a8wg" to link back to the original. Then publish at arcadelab.ai/publish.