🎮ArcadeLab

飞机大战手机版

by ApexNinja89
200 lines5.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, maximum-scale=1.0, user-scalable=no">
    <title>飞机大战手机版</title>
    <style>
        body { 
            margin: 0; 
            overflow: hidden; 
            background: #000; 
            display: flex; 
            justify-content: center; 
            align-items: center; 
            height: 100vh; 
            touch-action: none; /* 防止手机端滑动时页面滚动 */
        }
        canvas { 
            background: #111; 
            box-shadow: 0 0 20px rgba(0, 255, 255, 0.2); 
            display: block;
        }
    </style>
</head>
<body>
<canvas id="gameCanvas"></canvas>
<script>
    const canvas = document.getElementById('gameCanvas');
    const ctx = canvas.getContext('2d');
    
    // 自动适配手机屏幕大小
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;

    // 玩家对象
    const player = {
        x: canvas.width / 2 - 15,
        y: canvas.height - 80,
        width: 30,
        height: 30,
        speed: 5,
        color: '#0ff'
    };

    let bullets = [];
    let enemies = [];
    let score = 0;
    let isGameOver = false;
    let lastShotTime = 0; // 自动射击计时器

    // 触摸控制逻辑
    let touchStartX = 0, touchStartY = 0;
    let playerStartX = 0, playerStartY = 0;

    canvas.addEventListener('touchstart', e => {
        e.preventDefault();
        if (isGameOver) return;
        const touch = e.touches[0];
        touchStartX = touch.clientX;
        touchStartY = touch.clientY;
        playerStartX = player.x;
        playerStartY = player.y;
    }, { passive: false });

    canvas.addEventListener('touchmove', e => {
        e.preventDefault();
        if (isGameOver) return;
        const touch = e.touches[0];
        const dx = touch.clientX - touchStartX;
        const dy = touch.clientY - touchStartY;
        
        // 限制玩家在屏幕内移动
        player.x = Math.max(0, Math.min(canvas.width - player.width, playerStartX + dx));
        player.y = Math.max(0, Math.min(canvas.height - player.height, playerStartY + dy));
    }, { passive: false });

    // 自动生成子弹(手机屏幕小,自动射击体验更好)
    function autoShoot() {
        if (Date.now() - lastShotTime > 200) { // 每200毫秒发射一发
            bullets.push({
                x: player.x + player.width / 2 - 2,
                y: player.y,
                width: 4,
                height: 10,
                speed: 7
            });
            lastShotTime = Date.now();
        }
    }

    // 生成敌机
    function spawnEnemy() {
        const size = Math.random() * 20 + 20;
        enemies.push({
            x: Math.random() * (canvas.width - size),
            y: -size,
            width: size,
            height: size,
            speed: Math.random() * 2 + 1,
            color: '#f55'
        });
    }

    // 碰撞检测
    function isCollide(rect1, rect2) {
        return rect1.x < rect2.x + rect2.width &&
               rect1.x + rect1.width > rect2.x &&
               rect1.y < rect2.y + rect2.height &&
               rect1.y + rect1.height > rect2.y;
    }

    // 更新游戏状态
    function update() {
        if (isGameOver) return;
        autoShoot();

        // 子弹移动
        bullets.forEach((b, i) => {
            b.y -= b.speed;
            if (b.y < 0) bullets.splice(i, 1);
        });

        // 敌机移动 & 碰撞
        enemies.forEach((e, i) => {
            e.y += e.speed;
            if (e.y > canvas.height) {
                enemies.splice(i, 1);
                return;
            }
            // 子弹打敌机
            bullets.forEach((b, bi) => {
                if (isCollide(b, e)) {
                    enemies.splice(i, 1);
                    bullets.splice(bi, 1);
                    score += 10;
                }
            });
            // 敌机撞玩家
            if (isCollide(player, e)) {
                isGameOver = true;
            }
        });
    }

    // 绘制画面
    function draw() {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        
        // 画玩家
        ctx.fillStyle = player.color;
        ctx.beginPath();
        ctx.moveTo(player.x + player.width / 2, player.y);
        ctx.lineTo(player.x, player.y + player.height);
        ctx.lineTo(player.x + player.width, player.y + player.height);
        ctx.fill();

        // 画子弹
        ctx.fillStyle = '#ff0';
        bullets.forEach(b => ctx.fillRect(b.x, b.y, b.width, b.height));

        // 画敌机
        ctx.fillStyle = '#f55';
        enemies.forEach(e => ctx.fillRect(e.x, e.y, e.width, e.height));

        // 分数
        ctx.fillStyle = '#fff';
        ctx.font = '20px Arial';
        ctx.fillText('Score: ' + score, 10, 30);

        // 游戏结束提示
        if (isGameOver) {
            ctx.fillStyle = 'rgba(0,0,0,0.7)';
            ctx.fillRect(0, 0, canvas.width, canvas.height);
            ctx.fillStyle = '#fff';
            ctx.font = '40px Arial';
            ctx.textAlign = 'center';
            ctx.fillText('GAME OVER', canvas.width / 2, canvas.height / 2);
            ctx.font = '20px Arial';
            ctx.fillText('点击屏幕重新开始', canvas.width / 2, canvas.height / 2 + 40);
        }
    }

    // 主循环
    function loop() {
        update();
        draw();
        if (!isGameOver) {
            if (Math.random() < 0.03) spawnEnemy();
            requestAnimationFrame(loop);
        } else {
            // 游戏结束后点击屏幕重新开始
            canvas.addEventListener('click', () => location.reload(), { once: true });
        }
    }

    loop();
</script>
</body>
</html>

Game Source: 飞机大战手机版

Creator: ApexNinja89

Libraries: none

Complexity: complex (200 lines, 5.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: game-apexninja89" to link back to the original. Then publish at arcadelab.ai/publish.