经典坦克大战:Trae 轻松打造街机风格的坦克对战游戏

经典坦克大战游戏,作为街机游戏的代表之一,玩家控制一辆坦克,射击敌人并避免被敌人击中。这个游戏充满了动作和策略,每一局的战斗都紧张刺激。而制作一个经典的坦克大战游戏,看似简单,但其实需要处理坦克的移动、射击、敌人的生成与AI、碰撞检测等多个复杂的游戏逻辑。

过去,开发一个坦克大战游戏通常需要自己编写大量的代码,处理坦克的控制、敌人生成、子弹发射与碰撞检测等各个方面。而且,设计战斗和AI智能也是一项繁琐的任务。然而,自从我开始使用 Trae IDE,游戏开发变得轻松而有趣。接下来,我将分享如何通过 Trae 快速实现经典坦克大战游戏,让你轻松体验这款经典街机游戏。

💡 我的需求其实很简单

我的需求非常明确:制作一个经典的坦克大战游戏,功能要求如下:

  • 坦克控制:玩家能够通过键盘控制坦克的移动,并发射子弹。
  • 敌人生成:敌人坦克会自动生成并向玩家发起攻击。
  • 战斗逻辑:玩家需要避免被敌人击中,并击毁敌人坦克。
  • 街机风格:游戏需要拥有经典街机游戏的风格,简洁的UI,丰富的战斗体验。

虽然游戏的核心玩法并不复杂,但涉及到坦克控制、敌人AI和战斗逻辑的处理,手动编写这些功能代码可能会花费不少时间。

✨ Trae 如何理解需求并生成代码?

我只需要在 Trae 中输入一句话:

"生成一个经典坦克大战游戏,玩家控制坦克射击敌人,避免被敌人击中。"

Trae 立即解析并生成了一个完整的游戏代码,包括:

  • 坦克控制:玩家可以通过键盘的上下左右键来控制坦克的移动,空格键发射子弹。
  • 敌人生成与AI:敌人坦克会自动生成,并不断向玩家发起攻击。敌人会智能地向玩家移动并进行射击。
  • 碰撞检测与战斗逻辑:玩家的子弹会击中敌人坦克并销毁它,而敌人的子弹会击中玩家坦克并导致失败。
  • 简洁的UI:游戏界面采用经典的街机风格,界面简洁,操作直观。

只需要输入简单的指令,Trae 就能够自动生成完整的坦克大战游戏,并且为我提供了简洁的UI和完善的战斗逻辑。

🧩 游戏操作直观,战斗充满挑战

Trae 生成的坦克大战游戏操作非常简单,玩家可以使用键盘的方向键来控制坦克移动,通过空格键发射子弹。每当玩家射中敌人时,敌人坦克会被销毁,游戏画面也会即时更新。而敌人坦克则会持续向玩家发起攻击,玩家需要时刻保持警惕,避免被敌人击中。

游戏的AI智能也非常强大,敌人坦克能够根据玩家的移动做出反应,并适时发射子弹,让每一局游戏都充满了挑战。随着敌人数量的增加,游戏的难度也在逐渐上升,让玩家感受到真正的战斗压力。

🛠 游戏拓展,功能轻松加

虽然 Trae 生成的坦克大战游戏已经非常完善,但它也支持轻松添加更多功能。例如:

  • 多种敌人类型:可以增加不同类型的敌人,例如具有不同攻击模式和更高AI的坦克。
  • 关卡设计:可以设计不同的关卡,每个关卡有不同的敌人和难度。
  • 得分系统:记录玩家击毁敌人的数量,并显示总分。
  • 重生机制:增加一个机制,让玩家在被击中后重新出现在游戏中,继续进行战斗。

这些拓展功能都可以通过简单的指令描述,Trae 就能自动生成并集成到现有的游戏中。

这就是游戏开发的未来

通过这次坦克大战游戏的开发,我深刻感受到了 Trae 带来的便利。从坦克控制到敌人生成与AI,再到碰撞检测和战斗逻辑,Trae 都能快速生成完整的代码,并提供经典的街机风格UI。以前需要手动编写的复杂游戏逻辑,现在只需要输入简单的指令,就能轻松实现。

对于独立开发者或小团队来说,Trae 无疑是一个非常高效的工具,它帮助我节省了大量的开发时间,让我可以更加专注于游戏的创意和功能拓展。

结语

如果你也想制作一个经典的坦克大战游戏,试试 Trae IDE,输入类似的需求:

"生成一个经典坦克大战游戏,玩家控制坦克射击敌人,避免被敌人击中。"

几秒钟内,Trae 就会生成完整的游戏代码,带有智能敌人AI、坦克控制、战斗逻辑和街机风格的UI设计。你可以直接将它嵌入到你的项目中,甚至根据需求继续扩展和优化。

快来体验一下 Trae,让你的游戏开发变得更加轻松、有趣、充满挑战!

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>
        body {
            margin: 0;
            padding: 0;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            height: 100vh;
            background-color: #222;
            font-family: Arial, sans-serif;
            color: #fff;
        }
        
        .game-container {
            position: relative;
            width: 800px;
            height: 600px;
            background-color: #000;
            overflow: hidden;
            border: 2px solid #444;
            box-shadow: 0 0 20px rgba(0, 0, 0, 0.5);
        }
        
        #game-canvas {
            display: block;
            background-color: #000;
        }
        
        .controls {
            margin-top: 20px;
            display: flex;
            gap: 20px;
        }
        
        button {
            padding: 10px 20px;
            background-color: #4CAF50;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 16px;
            transition: background-color 0.3s;
        }
        
        button:hover {
            background-color: #45a049;
        }
        
        .game-info {
            margin-top: 10px;
            display: flex;
            justify-content: space-between;
            width: 800px;
        }
        
        .score, .lives, .level {
            font-size: 18px;
            font-weight: bold;
        }
        
        .game-over {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background-color: rgba(0, 0, 0, 0.8);
            padding: 20px 40px;
            border-radius: 10px;
            text-align: center;
            display: none;
        }
        
        .game-over h2 {
            color: #ff0000;
            font-size: 36px;
            margin-bottom: 20px;
        }
        
        .instructions {
            margin-top: 20px;
            background-color: #333;
            padding: 15px;
            border-radius: 5px;
            width: 800px;
        }
        
        .instructions h3 {
            margin-top: 0;
            color: #4CAF50;
        }
        
        .instructions ul {
            padding-left: 20px;
        }
    </style>
</head>
<body>
    <h1>坦克大战</h1>
    
    <div class="game-info">
        <div class="score">分数: <span id="score">0</span></div>
        <div class="level">关卡: <span id="level">1</span></div>
        <div class="lives">生命: <span id="lives">3</span></div>
    </div>
    
    <div class="game-container">
        <canvas id="game-canvas" width="800" height="600"></canvas>
        <div class="game-over" id="game-over">
            <h2>游戏结束</h2>
            <p>你的最终分数: <span id="final-score">0</span></p>
            <button id="restart-btn">重新开始</button>
        </div>
    </div>
    
    <div class="controls">
        <button id="start-btn">开始游戏</button>
        <button id="pause-btn">暂停</button>
    </div>
    
    <div class="instructions">
        <h3>游戏说明:</h3>
        <ul>
            <li>使用方向键(↑ ↓ ← →)控制坦克移动</li>
            <li>按空格键发射子弹</li>
            <li>摧毁敌方坦克获得分数</li>
            <li>避免被敌方坦克击中</li>
            <li>保护你的基地不被摧毁</li>
        </ul>
    </div>
    
    <script>
        // 游戏常量
        const TANK_SIZE = 40;
        const BULLET_SIZE = 8;
        const BULLET_SPEED = 5;
        const PLAYER_SPEED = 3;
        const ENEMY_SPEED = 1.5;
        const BRICK_SIZE = 40;
        const EXPLOSION_DURATION = 500; // 爆炸动画持续时间(毫秒)
        
        // 游戏状态
        let gameRunning = false;
        let gamePaused = false;
        let score = 0;
        let lives = 3;
        let level = 1;
        let enemySpawnRate = 3000; // 敌人生成间隔(毫秒)
        let lastEnemySpawn = 0;
        let maxEnemies = 5; // 同时存在的最大敌人数量
        
        // 游戏对象
        let player;
        let bullets = [];
        let enemies = [];
        let enemyBullets = [];
        let walls = [];
        let explosions = [];
        let base;
        
        // 图像资源
        const images = {};
        const imageUrls = {
            playerTank: 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0MCA0MCI+PHJlY3QgeD0iNSIgeT0iNSIgd2lkdGg9IjMwIiBoZWlnaHQ9IjMwIiBmaWxsPSIjNWNiODUwIiByeD0iMyIgcnk9IjMiLz48cmVjdCB4PSIxNSIgeT0iMCIgd2lkdGg9IjEwIiBoZWlnaHQ9IjIwIiBmaWxsPSIjNWNiODUwIi8+PGNpcmNsZSBjeD0iMjAiIGN5PSIyMCIgcj0iOCIgZmlsbD0iIzM4NzAzMCIvPjxyZWN0IHg9IjAiIHk9IjEyIiB3aWR0aD0iNDAiIGhlaWdodD0iMTYiIGZpbGw9IiM1Y2I4NTAiIHJ4PSIzIiByeT0iMyIvPjwvc3ZnPg==',
            enemyTank: 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0MCA0MCI+PHJlY3QgeD0iNSIgeT0iNSIgd2lkdGg9IjMwIiBoZWlnaHQ9IjMwIiBmaWxsPSIjZDk1MzRmIiByeD0iMyIgcnk9IjMiLz48cmVjdCB4PSIxNSIgeT0iMCIgd2lkdGg9IjEwIiBoZWlnaHQ9IjIwIiBmaWxsPSIjZDk1MzRmIi8+PGNpcmNsZSBjeD0iMjAiIGN5PSIyMCIgcj0iOCIgZmlsbD0iIzk5MzMzMCIvPjxyZWN0IHg9IjAiIHk9IjEyIiB3aWR0aD0iNDAiIGhlaWdodD0iMTYiIGZpbGw9IiNkOTUzNGYiIHJ4PSIzIiByeT0iMyIvPjwvc3ZnPg==',
            brick: 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0MCA0MCI+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjIwIiBoZWlnaHQ9IjIwIiBmaWxsPSIjYTU2NzNmIi8+PHJlY3QgeD0iMjAiIHk9IjAiIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0iIzhkNTUzNSIvPjxyZWN0IHg9IjAiIHk9IjIwIiB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIGZpbGw9IiM4ZDU1MzUiLz48cmVjdCB4PSIyMCIgeT0iMjAiIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0iI2E1NjczZiIvPjwvc3ZnPg==',
            steel: 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0MCA0MCI+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjQwIiBoZWlnaHQ9IjQwIiBmaWxsPSIjNzA3MDcwIi8+PHJlY3QgeD0iMiIgeT0iMiIgd2lkdGg9IjM2IiBoZWlnaHQ9IjM2IiBmaWxsPSIjYTBhMGEwIi8+PHJlY3QgeD0iNSIgeT0iNSIgd2lkdGg9IjMwIiBoZWlnaHQ9IjMwIiBmaWxsPSIjODA4MDgwIi8+PC9zdmc+',
            base: 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0MCA0MCI+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjQwIiBoZWlnaHQ9IjQwIiBmaWxsPSIjMzMzIi8+PHBvbHlnb24gcG9pbnRzPSIyMCwwIDQwLDIwIDIwLDQwIDAsMjAiIGZpbGw9IiNmZmNjMDAiLz48Y2lyY2xlIGN4PSIyMCIgY3k9IjIwIiByPSIxMCIgZmlsbD0iI2ZmMDAwMCIvPjxjaXJjbGUgY3g9IjIwIiBjeT0iMjAiIHI9IjUiIGZpbGw9IiNmZmZmMDAiLz48L3N2Zz4=',
            explosion: 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0MCA0MCI+PGNpcmNsZSBjeD0iMjAiIGN5PSIyMCIgcj0iMTgiIGZpbGw9IiNmZjk5MDAiLz48Y2lyY2xlIGN4PSIyMCIgY3k9IjIwIiByPSIxMiIgZmlsbD0iI2ZmY2MwMCIvPjxjaXJjbGUgY3g9IjIwIiBjeT0iMjAiIHI9IjYiIGZpbGw9IiNmZmZmMDAiLz48cGF0aCBkPSJNMTAsMCBMMzAsMCBMMjAsMTAgWiIgZmlsbD0iI2ZmOTkwMCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjAsIDApIHJvdGF0ZSgwKSIvPjxwYXRoIGQ9Ik0xMCwwIEwzMCwwIEwyMCwxMCBaIiBmaWxsPSIjZmY5OTAwIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0MCwgMjApIHJvdGF0ZSg5MCkiLz48cGF0aCBkPSJNMTAsMCBMMzAsMCBMMjAsMTAgWiIgZmlsbD0iI2ZmOTkwMCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjAsIDQwKSByb3RhdGUoMTgwKSIvPjxwYXRoIGQ9Ik0xMCwwIEwzMCwwIEwyMCwxMCBaIiBmaWxsPSIjZmY5OTAwIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLCAyMCkgcm90YXRlKDI3MCkiLz48L3N2Zz4='
        };
        
        // DOM 元素
        const canvas = document.getElementById('game-canvas');
        const ctx = canvas.getContext('2d');
        const startBtn = document.getElementById('start-btn');
        const pauseBtn = document.getElementById('pause-btn');
        const restartBtn = document.getElementById('restart-btn');
        const gameOverEl = document.getElementById('game-over');
        const scoreEl = document.getElementById('score');
        const livesEl = document.getElementById('lives');
        const levelEl = document.getElementById('level');
        const finalScoreEl = document.getElementById('final-score');
        
        // 加载图像资源
        function loadImages() {
            const promises = [];
            
            for (const key in imageUrls) {
                const img = new Image();
                img.src = imageUrls[key];
                images[key] = img;
                
                const promise = new Promise(resolve => {
                    img.onload = resolve;
                });
                
                promises.push(promise);
            }
            
            return Promise.all(promises);
        }
        
        // 初始化游戏
        function initGame() {
            // 创建玩家坦克
            player = {
                x: canvas.width / 2 - TANK_SIZE / 2,
                y: canvas.height - TANK_SIZE - 20,
                width: TANK_SIZE,
                height: TANK_SIZE,
                direction: 'up',
                lastShot: 0,
                shootDelay: 300 // 射击延迟(毫秒)
            };
            
            // 创建基地
            base = {
                x: canvas.width / 2 - TANK_SIZE / 2,
                y: canvas.height - TANK_SIZE,
                width: TANK_SIZE,
                height: TANK_SIZE
            };
            
            // 创建墙壁
            createWalls();
            
            // 重置游戏状态
            bullets = [];
            enemies = [];
            enemyBullets = [];
            explosions = [];
            score = 0;
            lives = 3;
            level = 1;
            enemySpawnRate = 3000;
            maxEnemies = 5;
            
            // 更新UI
            updateUI();
        }
        
        // 创建墙壁
        function createWalls() {
            walls = [];
            
            // 基地周围的墙
            const baseX = base.x;
            const baseY = base.y;
            
            // 左侧墙
            walls.push({ x: baseX - BRICK_SIZE, y: baseY, width: BRICK_SIZE, height: BRICK_SIZE, type: 'brick' });
            walls.push({ x: baseX - BRICK_SIZE, y: baseY - BRICK_SIZE, width: BRICK_SIZE, height: BRICK_SIZE, type: 'brick' });
            
            // 右侧墙
            walls.push({ x: baseX + TANK_SIZE, y: baseY, width: BRICK_SIZE, height: BRICK_SIZE, type: 'brick' });
            walls.push({ x: baseX + TANK_SIZE, y: baseY - BRICK_SIZE, width: BRICK_SIZE, height: BRICK_SIZE, type: 'brick' });
            
            // 上方墙
            walls.push({ x: baseX, y: baseY - BRICK_SIZE, width: BRICK_SIZE, height: BRICK_SIZE, type: 'brick' });
            
            // 添加随机墙壁
            const gridSize = BRICK_SIZE;
            const gridWidth = canvas.width / gridSize;
            const gridHeight = canvas.height / gridSize;
            
            // 创建一些随机的砖墙
            for (let i = 0; i < 30; i++) {
                const x = Math.floor(Math.random() * (gridWidth - 2) + 1) * gridSize;
                const y = Math.floor(Math.random() * (gridHeight - 6) + 1) * gridSize;
                
                // 确保不会在玩家初始位置创建墙
                if (Math.abs(x - player.x) > TANK_SIZE * 2 || Math.abs(y - player.y) > TANK_SIZE * 2) {
                    walls.push({ x, y, width: BRICK_SIZE, height: BRICK_SIZE, type: 'brick' });
                }
            }
            
            // 创建一些钢墙(不可摧毁)
            for (let i = 0; i < 10; i++) {
                const x = Math.floor(Math.random() * (gridWidth - 2) + 1) * gridSize;
                const y = Math.floor(Math.random() * (gridHeight - 6) + 1) * gridSize;
                
                // 确保不会在玩家初始位置创建墙
                if (Math.abs(x - player.x) > TANK_SIZE * 2 || Math.abs(y - player.y) > TANK_SIZE * 2) {
                    walls.push({ x, y, width: BRICK_SIZE, height: BRICK_SIZE, type: 'steel' });
                }
            }
        }
        
        // 生成敌人
        function spawnEnemy() {
            if (enemies.length >= maxEnemies) return;
            
            const spawnPoints = [
                { x: 0, y: 0 },
                { x: canvas.width / 2 - TANK_SIZE / 2, y: 0 },
                { x: canvas.width - TANK_SIZE, y: 0 }
            ];
            
            const spawnPoint = spawnPoints[Math.floor(Math.random() * spawnPoints.length)];
            
            // 检查是否与现有敌人重叠
            for (const enemy of enemies) {
                if (Math.abs(enemy.x - spawnPoint.x) < TANK_SIZE && Math.abs(enemy.y - spawnPoint.y) < TANK_SIZE) {
                    return; // 如果重叠,不生成新敌人
                }
            }
            
            const directions = ['down', 'left', 'right'];
            const enemy = {
                x: spawnPoint.x,
                y: spawnPoint.y,
                width: TANK_SIZE,
                height: TANK_SIZE,
                direction: directions[Math.floor(Math.random() * directions.length)],
                lastShot: 0,
                shootDelay: 1500 + Math.random() * 1500, // 随机射击延迟
                moveTimer: 0,
                moveDelay: 1000 + Math.random() * 1000, // 随机移动延迟
                speed: ENEMY_SPEED * (1 + level * 0.1) // 随着关卡增加速度
            };
            
            enemies.push(enemy);
        }
        
        // 更新游戏状态
        function update(timestamp) {
            if (!gameRunning || gamePaused) return;
            
            // 生成敌人
            if (timestamp - lastEnemySpawn > enemySpawnRate) {
                spawnEnemy();
                lastEnemySpawn = timestamp;
            }
            
            // 更新玩家子弹
            updateBullets(bullets);
            
            // 更新敌人子弹
            updateBullets(enemyBullets);
            
            // 更新敌人
            updateEnemies(timestamp);
            
            // 更新爆炸效果
            updateExplosions(timestamp);
            
            // 检查关卡进度
            checkLevelProgress();
        }
        
        // 更新子弹位置和碰撞
        function updateBullets(bulletArray) {
            for (let i = bulletArray.length - 1; i >= 0; i--) {
                const bullet = bulletArray[i];
                
                // 根据方向移动子弹
                switch (bullet.direction) {
                    case 'up':
                        bullet.y -= BULLET_SPEED;
                        break;
                    case 'down':
                        bullet.y += BULLET_SPEED;
                        break;
                    case 'left':
                        bullet.x -= BULLET_SPEED;
                        break;
                    case 'right':
                        bullet.x += BULLET_SPEED;
                        break;
                }
                
                // 检查子弹是否超出边界
                if (bullet.x < 0 || bullet.x > canvas.width || bullet.y < 0 || bullet.y > canvas.height) {
                    bulletArray.splice(i, 1);
                    continue;
                }
                
                // 检查子弹与墙壁碰撞
                let hitWall = false;
                for (let j = walls.length - 1; j >= 0; j--) {
                    const wall = walls[j];
                    if (checkCollision(bullet, wall)) {
                        bulletArray.splice(i, 1);
                        
                        // 只有砖墙可以被摧毁
                        if (wall.type === 'brick') {
                            walls.splice(j, 1);
                            createExplosion(bullet.x, bullet.y, 0.5);
                        }
                        
                        hitWall = true;
                        break;
                    }
                }
                
                if (hitWall) continue;
                
                // 检查玩家子弹与敌人碰撞
                if (bulletArray === bullets) {
                    for (let j = enemies.length - 1; j >= 0; j--) {
                        const enemy = enemies[j];
                        if (checkCollision(bullet, enemy)) {
                            bulletArray.splice(i, 1);
                            enemies.splice(j, 1);
                            createExplosion(enemy.x + enemy.width / 2, enemy.y + enemy.height / 2, 1);
                            score += 100;
                            updateUI();
                            break;
                        }
                    }
                }
                
                // 检查敌人子弹与玩家碰撞
                if (bulletArray === enemyBullets && player.alive !== false) {
                    if (checkCollision(bullet, player)) {
                        bulletArray.splice(i, 1);
                        playerHit();
                        break;
                    }
                }
                
                // 检查子弹与基地碰撞
                if (checkCollision(bullet, base)) {
                    bulletArray.splice(i, 1);
                    createExplosion(base.x + base.width / 2, base.y + base.height / 2, 1.5);
                    gameOver();
                    break;
                }
            }
        }
        
        // 更新敌人行为
        function updateEnemies(timestamp) {
            for (let i = 0; i < enemies.length; i++) {
                const enemy = enemies[i];
                
                // 敌人射击
                if (timestamp - enemy.lastShot > enemy.shootDelay) {
                    enemyShoot(enemy);
                    enemy.lastShot = timestamp;
                }
                
                // 敌人移动
                if (timestamp - enemy.moveTimer > enemy.moveDelay) {
                    // 随机改变方向
                    const directions = ['up', 'down', 'left', 'right'];
                    enemy.direction = directions[Math.floor(Math.random() * directions.length)];
                    enemy.moveTimer = timestamp;
                    enemy.moveDelay = 1000 + Math.random() * 1000;
                }
                
                // 根据方向移动敌人
                let newX = enemy.x;
                let newY = enemy.y;
                
                switch (enemy.direction) {
                    case 'up':
                        newY -= enemy.speed;
                        break;
                    case 'down':
                        newY += enemy.speed;
                        break;
                    case 'left':
                        newX -= enemy.speed;
                        break;
                    case 'right':
                        newX += enemy.speed;
                        break;
                }
                
                // 检查边界碰撞
                if (newX < 0) {
                    newX = 0;
                    enemy.direction = 'right';
                } else if (newX + enemy.width > canvas.width) {
                    newX = canvas.width - enemy.width;
                    enemy.direction = 'left';
                }
                
                if (newY < 0) {
                    newY = 0;
                    enemy.direction = 'down';
                } else if (newY + enemy.height > canvas.height) {
                    newY = canvas.height - enemy.height;
                    enemy.direction = 'up';
                }
                
                // 检查与墙壁碰撞
                const tempEnemy = { ...enemy, x: newX, y: newY };
                let wallCollision = false;
                
                for (const wall of walls) {
                    if (checkCollision(tempEnemy, wall)) {
                        wallCollision = true;
                        break;
                    }
                }
                
                // 检查与其他敌人碰撞
                let enemyCollision = false;
                for (const otherEnemy of enemies) {
                    if (otherEnemy === enemy) continue;
                    
                    if (checkCollision(tempEnemy, otherEnemy)) {
                        enemyCollision = true;
                        break;
                    }
                }
                
                // 检查与玩家碰撞
                let playerCollision = false;
                if (player.alive !== false && checkCollision(tempEnemy, player)) {
                    playerCollision = true;
                }
                
                // 检查与基地碰撞
                let baseCollision = false;
                if (checkCollision(tempEnemy, base)) {
                    baseCollision = true;
                }
                
                // 如果没有碰撞,更新位置
                if (!wallCollision && !enemyCollision && !playerCollision && !baseCollision) {
                    enemy.x = newX;
                    enemy.y = newY;
                } else {
                    // 如果有碰撞,改变方向
                    const directions = ['up', 'down', 'left', 'right'];
                    enemy.direction = directions[Math.floor(Math.random() * directions.length)];
                }
            }
        }
        
        // 更新爆炸效果
        function updateExplosions(timestamp) {
            for (let i = explosions.length - 1; i >= 0; i--) {
                const explosion = explosions[i];
                if (timestamp - explosion.startTime > EXPLOSION_DURATION) {
                    explosions.splice(i, 1);
                }
            }
        }
        
        // 检查关卡进度
        function checkLevelProgress() {
            // 如果消灭了足够多的敌人,进入下一关
            if (score >= level * 1000) {
                level++;
                enemySpawnRate = Math.max(1000, 3000 - level * 200); // 随着关卡增加,敌人生成速度加快
                maxEnemies = Math.min(10, 5 + Math.floor(level / 2)); // 随着关卡增加,最大敌人数量增加
                updateUI();
                
                // 创建新的墙壁布局
                createWalls();
            }
        }
        
        // 玩家被击中
        function playerHit() {
            lives--;
            updateUI();
            
            createExplosion(player.x + player.width / 2, player.y + player.height / 2, 1);
            
            // 暂时使玩家无敌
            player.alive = false;
            
            // 如果还有生命,重生玩家
            if (lives > 0) {
                setTimeout(() => {
                    player.x = canvas.width / 2 - TANK_SIZE / 2;
                    player.y = canvas.height - TANK_SIZE - 20;
                    player.direction = 'up';
                    player.alive = true;
                }, 1000);
            } else {
                gameOver();
            }
        }
        
        // 游戏结束
        function gameOver() {
            gameRunning = false;
            finalScoreEl.textContent = score;
            gameOverEl.style.display = 'block';
        }
        
        // 敌人射击
        function enemyShoot(enemy) {
            const bulletX = enemy.x + enemy.width / 2 - BULLET_SIZE / 2;
            const bulletY = enemy.y + enemy.height / 2 - BULLET_SIZE / 2;
            
            // 根据敌人方向调整子弹位置
            switch (enemy.direction) {
                case 'up':
                    enemyBullets.push({ x: bulletX, y: enemy.y - BULLET_SIZE, width: BULLET_SIZE, height: BULLET_SIZE, direction: 'up' });
                    break;
                case 'down':
                    enemyBullets.push({ x: bulletX, y: enemy.y + enemy.height, width: BULLET_SIZE, height: BULLET_SIZE, direction: 'down' });
                    break;
                case 'left':
                    enemyBullets.push({ x: enemy.x - BULLET_SIZE, y: bulletY, width: BULLET_SIZE, height: BULLET_SIZE, direction: 'left' });
                    break;
                case 'right':
                    enemyBullets.push({ x: enemy.x + enemy.width, y: bulletY, width: BULLET_SIZE, height: BULLET_SIZE, direction: 'right' });
                    break;
            }
        }
        
        // 玩家射击
        function playerShoot() {
            if (!gameRunning || gamePaused || player.alive === false) return;
            
            const now = Date.now();
            if (now - player.lastShot < player.shootDelay) return;
            
            player.lastShot = now;
            
            const bulletX = player.x + player.width / 2 - BULLET_SIZE / 2;
            const bulletY = player.y + player.height / 2 - BULLET_SIZE / 2;
            
            // 根据玩家方向调整子弹位置
            switch (player.direction) {
                case 'up':
                    bullets.push({ x: bulletX, y: player.y - BULLET_SIZE, width: BULLET_SIZE, height: BULLET_SIZE, direction: 'up' });
                    break;
                case 'down':
                    bullets.push({ x: bulletX, y: player.y + player.height, width: BULLET_SIZE, height: BULLET_SIZE, direction: 'down' });
                    break;
                case 'left':
                    bullets.push({ x: player.x - BULLET_SIZE, y: bulletY, width: BULLET_SIZE, height: BULLET_SIZE, direction: 'left' });
                    break;
                case 'right':
                    bullets.push({ x: player.x + player.width, y: bulletY, width: BULLET_SIZE, height: BULLET_SIZE, direction: 'right' });
                    break;
            }
        }
        
        // 创建爆炸效果
        function createExplosion(x, y, scale = 1) {
            explosions.push({
                x: x - (TANK_SIZE * scale) / 2,
                y: y - (TANK_SIZE * scale) / 2,
                width: TANK_SIZE * scale,
                height: TANK_SIZE * scale,
                startTime: Date.now()
            });
        }
        
        // 检查碰撞
        function checkCollision(obj1, obj2) {
            return obj1.x < obj2.x + obj2.width &&
                   obj1.x + obj1.width > obj2.x &&
                   obj1.y < obj2.y + obj2.height &&
                   obj1.y + obj1.height > obj2.y;
        }
        
        // 渲染游戏
        function render() {
            // 清空画布
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            
            // 绘制墙壁
            for (const wall of walls) {
                const img = wall.type === 'brick' ? images.brick : images.steel;
                ctx.drawImage(img, wall.x, wall.y, wall.width, wall.height);
            }
            
            // 绘制基地
            ctx.drawImage(images.base, base.x, base.y, base.width, base.height);
            
            // 绘制玩家
            if (player.alive !== false) {
                // 保存当前状态
                ctx.save();
                
                // 移动到坦克中心
                ctx.translate(player.x + player.width / 2, player.y + player.height / 2);
                
                // 根据方向旋转
                switch (player.direction) {
                    case 'up':
                        ctx.rotate(0);
                        break;
                    case 'right':
                        ctx.rotate(Math.PI / 2);
                        break;
                    case 'down':
                        ctx.rotate(Math.PI);
                        break;
                    case 'left':
                        ctx.rotate(-Math.PI / 2);
                        break;
                }
                
                // 绘制坦克(中心点在原点)
                ctx.drawImage(images.playerTank, -player.width / 2, -player.height / 2, player.width, player.height);
                
                // 恢复状态
                ctx.restore();
            }
            
            // 绘制敌人
            for (const enemy of enemies) {
                // 保存当前状态
                ctx.save();
                
                // 移动到坦克中心
                ctx.translate(enemy.x + enemy.width / 2, enemy.y + enemy.height / 2);
                
                // 根据方向旋转
                switch (enemy.direction) {
                    case 'up':
                        ctx.rotate(0);
                        break;
                    case 'right':
                        ctx.rotate(Math.PI / 2);
                        break;
                    case 'down':
                        ctx.rotate(Math.PI);
                        break;
                    case 'left':
                        ctx.rotate(-Math.PI / 2);
                        break;
                }
                
                // 绘制坦克(中心点在原点)
                ctx.drawImage(images.enemyTank, -enemy.width / 2, -enemy.height / 2, enemy.width, enemy.height);
                
                // 恢复状态
                ctx.restore();
            }
            
            // 绘制玩家子弹
            ctx.fillStyle = '#5cb850';
            for (const bullet of bullets) {
                ctx.fillRect(bullet.x, bullet.y, bullet.width, bullet.height);
            }
            
            // 绘制敌人子弹
            ctx.fillStyle = '#d9534f';
            for (const bullet of enemyBullets) {
                ctx.fillRect(bullet.x, bullet.y, bullet.width, bullet.height);
            }
            
            // 绘制爆炸效果
            for (const explosion of explosions) {
                ctx.drawImage(images.explosion, explosion.x, explosion.y, explosion.width, explosion.height);
            }
        }
        
        // 更新UI
        function updateUI() {
            scoreEl.textContent = score;
            livesEl.textContent = lives;
            levelEl.textContent = level;
        }
        
        // 游戏循环
        let lastTime = 0;
        function gameLoop(timestamp) {
            if (!lastTime) lastTime = timestamp;
            const deltaTime = timestamp - lastTime;
            lastTime = timestamp;
            
            update(timestamp);
            render();
            
            requestAnimationFrame(gameLoop);
        }
        
        // 键盘控制
        const keys = {};
        
        window.addEventListener('keydown', (e) => {
            keys[e.key] = true;
            
            // 空格键射击
            if (e.key === ' ') {
                playerShoot();
            }
            
            // 防止方向键滚动页面
            if (['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', ' '].includes(e.key)) {
                e.preventDefault();
            }
        });
        
        window.addEventListener('keyup', (e) => {
            keys[e.key] = false;
        });
        
        // 处理玩家移动
        function handlePlayerMovement() {
            if (!gameRunning || gamePaused || player.alive === false) return;
            
            let newX = player.x;
            let newY = player.y;
            let directionChanged = false;
            
            if (keys['ArrowUp']) {
                newY -= PLAYER_SPEED;
                if (player.direction !== 'up') {
                    player.direction = 'up';
                    directionChanged = true;
                }
            } else if (keys['ArrowDown']) {
                newY += PLAYER_SPEED;
                if (player.direction !== 'down') {
                    player.direction = 'down';
                    directionChanged = true;
                }
            } else if (keys['ArrowLeft']) {
                newX -= PLAYER_SPEED;
                if (player.direction !== 'left') {
                    player.direction = 'left';
                    directionChanged = true;
                }
            } else if (keys['ArrowRight']) {
                newX += PLAYER_SPEED;
                if (player.direction !== 'right') {
                    player.direction = 'right';
                    directionChanged = true;
                }
            }
            
            // 如果只是改变方向,不需要检查碰撞
            if (directionChanged && newX === player.x && newY === player.y) {
                return;
            }
            
            // 检查边界碰撞
            if (newX < 0) {
                newX = 0;
            } else if (newX + player.width > canvas.width) {
                newX = canvas.width - player.width;
            }
            
            if (newY < 0) {
                newY = 0;
            } else if (newY + player.height > canvas.height) {
                newY = canvas.height - player.height;
            }
            
            // 检查与墙壁碰撞
            const tempPlayer = { ...player, x: newX, y: newY };
            let wallCollision = false;
            
            for (const wall of walls) {
                if (checkCollision(tempPlayer, wall)) {
                    wallCollision = true;
                    break;
                }
            }
            
            // 检查与敌人碰撞
            let enemyCollision = false;
            for (const enemy of enemies) {
                if (checkCollision(tempPlayer, enemy)) {
                    enemyCollision = true;
                    break;
                }
            }
            
            // 检查与基地碰撞
            let baseCollision = false;
            if (checkCollision(tempPlayer, base)) {
                baseCollision = true;
            }
            
            // 如果没有碰撞,更新位置
            if (!wallCollision && !enemyCollision && !baseCollision) {
                player.x = newX;
                player.y = newY;
            }
        }
        
        // 设置移动处理间隔
        setInterval(handlePlayerMovement, 16); // 约60fps
        
        // 事件监听器
        startBtn.addEventListener('click', () => {
            if (!gameRunning) {
                initGame();
                gameRunning = true;
                gamePaused = false;
                gameOverEl.style.display = 'none';
                requestAnimationFrame(gameLoop);
            }
        });
        
        pauseBtn.addEventListener('click', () => {
            if (gameRunning) {
                gamePaused = !gamePaused;
                pauseBtn.textContent = gamePaused ? '继续' : '暂停';
            }
        });
        
        restartBtn.addEventListener('click', () => {
            gameOverEl.style.display = 'none';
            initGame();
            gameRunning = true;
            gamePaused = false;
            requestAnimationFrame(gameLoop);
        });
        
        // 加载图像并初始化游戏
        loadImages().then(() => {
            initGame();
        });
    </script>
</body>
</html>
相关推荐
量子位40 分钟前
10年前押中英伟达:这位复旦学霸如何用AI Agent重新定义投资
ai编程
量子位1 小时前
Nano banana手办玩法火爆出圈!无需抽卡,效果惊了(°o°)
人工智能·ai编程
鼓掌MVP2 小时前
基于MCP与Trae框架的“人情账本”系统开发实践:用自然语言管理人际往来
trae
TimelessHaze4 小时前
【webpack】让面试官眼前一亮的webpack :从基础配置到高级优化
前端·webpack·trae
孟健6 小时前
AI 出海应用存储怎么选?我踩过的坑,你别再踩了
ai编程
盏灯7 小时前
Trae:从设计到接口,全栈自动化IDE
人工智能·trae
bug菌7 小时前
🤔还在为代码调试熬夜?字节TRAE如何让我的开发效率翻三倍的神操作!
aigc·ai编程·trae
豆包MarsCode7 小时前
TRAE Rules 实践:两套规则,实现从设计图到代码的全自动化流程
trae
兵临天下api7 小时前
淘宝 item_get_app 接口深度分析及 Python 实现
trae