基于HTML5 Canvas的飞行射击游戏:《星际战机 太空射击游戏》

一个基于HTML5 Canvas的飞行射击游戏,玩家可以控制战机躲避陨石并射击敌人。

设计思路

  • 使用Canvas实现流畅的游戏动画
  • 添加太空背景和粒子效果增强沉浸感
  • 实现玩家战机控制、射击系统和敌人AI
  • 包含分数系统、生命值和游戏状态管理

下面是完整的实现代码:

<!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: linear-gradient(135deg, #0f0c29, #302b63, #24243e);
            height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            overflow: hidden;
            color: #fff;
        }
        
        .game-container {
            position: relative;
            width: 800px;
            height: 600px;
            box-shadow: 0 0 30px rgba(0, 150, 255, 0.5);
            border-radius: 10px;
            overflow: hidden;
        }
        
        #gameCanvas {
            background: radial-gradient(ellipse at center, #1a2980 0%, #26d0ce 100%);
            display: block;
        }
        
        .ui-overlay {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            padding: 20px;
            display: flex;
            justify-content: space-between;
        }
        
        .stats {
            background: rgba(0, 0, 0, 0.6);
            padding: 10px 20px;
            border-radius: 10px;
            border: 1px solid #00aaff;
        }
        
        .stats div {
            margin: 5px 0;
        }
        
        .screen {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            background: rgba(0, 10, 30, 0.85);
            z-index: 10;
        }
        
        .title {
            font-size: 48px;
            font-weight: bold;
            margin-bottom: 30px;
            text-shadow: 0 0 10px #00aaff, 0 0 20px #00aaff;
            color: #fff;
            letter-spacing: 3px;
        }
        
        .btn {
            background: linear-gradient(to right, #00aaff, #0088ff);
            color: white;
            border: none;
            padding: 15px 40px;
            font-size: 18px;
            border-radius: 50px;
            cursor: pointer;
            margin: 15px 0;
            transition: all 0.3s;
            box-shadow: 0 5px 15px rgba(0, 170, 255, 0.4);
        }
        
        .btn:hover {
            transform: translateY(-3px);
            box-shadow: 0 8px 20px rgba(0, 170, 255, 0.6);
        }
        
        .instructions {
            background: rgba(0, 0, 0, 0.6);
            padding: 20px;
            border-radius: 10px;
            max-width: 80%;
            margin-top: 30px;
            border: 1px solid #00aaff;
        }
        
        .instructions h3 {
            margin-bottom: 10px;
            color: #00aaff;
        }
        
        .instructions p {
            margin: 5px 0;
        }
        
        .hidden {
            display: none;
        }
        
        .game-over {
            font-size: 72px;
            color: #ff0055;
            text-shadow: 0 0 10px #ff0055, 0 0 20px #ff0055;
            margin-bottom: 30px;
        }
    </style>
</head>
<body>
    <div class="game-container">
        <canvas id="gameCanvas" width="800" height="600"></canvas>
        
        <div class="ui-overlay">
            <div class="stats">
                <div>分数: <span id="score">0</span></div>
                <div>生命值: <span id="lives">3</span></div>
                <div>等级: <span id="level">1</span></div>
            </div>
        </div>
        
        <div id="startScreen" class="screen">
            <h1 class="title">星际战机</h1>
            <button id="startBtn" class="btn">开始游戏</button>
            
            <div class="instructions">
                <h3>游戏说明</h3>
                <p>← → 方向键控制战机左右移动</p>
                <p>空格键或鼠标左键发射子弹</p>
                <p>躲避陨石和敌机,射击敌机获得分数</p>
                <p>每1000分提升一个等级,敌机速度增加</p>
            </div>
        </div>
        
        <div id="gameOverScreen" class="screen hidden">
            <h1 class="game-over">游戏结束</h1>
            <h2>最终得分: <span id="finalScore">0</span></h2>
            <button id="restartBtn" class="btn">重新开始</button>
        </div>
    </div>

    <script>
        // 获取Canvas和上下文
        const canvas = document.getElementById('gameCanvas');
        const ctx = canvas.getContext('2d');
        
        // 游戏状态
        const gameState = {
            score: 0,
            lives: 3,
            level: 1,
            gameOver: false,
            isRunning: false,
            enemies: [],
            bullets: [],
            particles: [],
            stars: [],
            lastTime: 0,
            enemySpawnTimer: 0,
            enemySpawnInterval: 1000, // 敌机生成间隔(毫秒)
            player: {
                x: canvas.width / 2 - 25,
                y: canvas.height - 80,
                width: 50,
                height: 60,
                speed: 6,
                isMovingLeft: false,
                isMovingRight: false,
                shootCooldown: 0
            }
        };
        
        // 初始化星星背景
        function initStars() {
            gameState.stars = [];
            for (let i = 0; i < 150; i++) {
                gameState.stars.push({
                    x: Math.random() * canvas.width,
                    y: Math.random() * canvas.height,
                    size: Math.random() * 2 + 1,
                    speed: Math.random() * 2 + 0.5
                });
            }
        }
        
        // 初始化游戏
        function initGame() {
            gameState.score = 0;
            gameState.lives = 3;
            gameState.level = 1;
            gameState.gameOver = false;
            gameState.enemies = [];
            gameState.bullets = [];
            gameState.particles = [];
            gameState.enemySpawnTimer = 0;
            gameState.enemySpawnInterval = 1000;
            
            gameState.player = {
                x: canvas.width / 2 - 25,
                y: canvas.height - 80,
                width: 50,
                height: 60,
                speed: 6,
                isMovingLeft: false,
                isMovingRight: false,
                shootCooldown: 0
            };
            
            initStars();
            updateUI();
        }
        
        // 更新UI显示
        function updateUI() {
            document.getElementById('score').textContent = gameState.score;
            document.getElementById('lives').textContent = gameState.lives;
            document.getElementById('level').textContent = gameState.level;
        }
        
        // 绘制玩家战机
        function drawPlayer() {
            ctx.save();
            
            // 绘制战机主体
            ctx.fillStyle = '#00aaff';
            ctx.beginPath();
            ctx.moveTo(gameState.player.x + gameState.player.width / 2, gameState.player.y);
            ctx.lineTo(gameState.player.x + gameState.player.width, gameState.player.y + gameState.player.height / 2);
            ctx.lineTo(gameState.player.x + gameState.player.width * 0.7, gameState.player.y + gameState.player.height);
            ctx.lineTo(gameState.player.x + gameState.player.width * 0.3, gameState.player.y + gameState.player.height);
            ctx.lineTo(gameState.player.x, gameState.player.y + gameState.player.height / 2);
            ctx.closePath();
            ctx.fill();
            
            // 绘制驾驶舱
            ctx.fillStyle = '#aaffff';
            ctx.beginPath();
            ctx.arc(
                gameState.player.x + gameState.player.width / 2,
                gameState.player.y + gameState.player.height / 3,
                8, 0, Math.PI * 2
            );
            ctx.fill();
            
            // 绘制引擎火焰
            const flameHeight = 15 + Math.sin(Date.now() / 100) * 5;
            ctx.fillStyle = '#ff5500';
            ctx.beginPath();
            ctx.moveTo(gameState.player.x + gameState.player.width * 0.3, gameState.player.y + gameState.player.height);
            ctx.lineTo(gameState.player.x + gameState.player.width * 0.5, gameState.player.y + gameState.player.height + flameHeight);
            ctx.lineTo(gameState.player.x + gameState.player.width * 0.7, gameState.player.y + gameState.player.height);
            ctx.closePath();
            ctx.fill();
            
            ctx.restore();
        }
        
        // 绘制敌机
        function drawEnemy(enemy) {
            ctx.save();
            
            // 敌机颜色根据类型变化
            if (enemy.type === 1) {
                ctx.fillStyle = '#ff5555';
            } else {
                ctx.fillStyle = '#ffaa00';
            }
            
            ctx.beginPath();
            ctx.moveTo(enemy.x, enemy.y);
            ctx.lineTo(enemy.x + enemy.width, enemy.y);
            ctx.lineTo(enemy.x + enemy.width * 0.8, enemy.y + enemy.height * 0.7);
            ctx.lineTo(enemy.x + enemy.width, enemy.y + enemy.height);
            ctx.lineTo(enemy.x, enemy.y + enemy.height);
            ctx.lineTo(enemy.x + enemy.width * 0.2, enemy.y + enemy.height * 0.7);
            ctx.closePath();
            ctx.fill();
            
            // 敌机引擎
            ctx.fillStyle = '#ff0000';
            ctx.fillRect(enemy.x + enemy.width * 0.3, enemy.y + enemy.height, enemy.width * 0.4, 5);
            
            ctx.restore();
        }
        
        // 绘制子弹
        function drawBullet(bullet) {
            ctx.save();
            ctx.fillStyle = '#ffff00';
            ctx.beginPath();
            ctx.arc(bullet.x, bullet.y, bullet.radius, 0, Math.PI * 2);
            ctx.fill();
            
            // 添加发光效果
            ctx.shadowBlur = 10;
            ctx.shadowColor = '#ffff00';
            ctx.restore();
        }
        
        // 绘制粒子
        function drawParticle(particle) {
            ctx.save();
            ctx.globalAlpha = particle.alpha;
            ctx.fillStyle = particle.color;
            ctx.beginPath();
            ctx.arc(particle.x, particle.y, particle.size, 0, Math.PI * 2);
            ctx.fill();
            ctx.restore();
        }
        
        // 绘制星星背景
        function drawStars() {
            ctx.fillStyle = '#ffffff';
            gameState.stars.forEach(star => {
                ctx.beginPath();
                ctx.arc(star.x, star.y, star.size, 0, Math.PI * 2);
                ctx.fill();
            });
        }
        
        // 更新星星位置
        function updateStars() {
            gameState.stars.forEach(star => {
                star.y += star.speed;
                if (star.y > canvas.height) {
                    star.y = 0;
                    star.x = Math.random() * canvas.width;
                }
            });
        }
        
        // 生成敌机
        function spawnEnemy() {
            const type = Math.random() > 0.7 ? 2 : 1; // 30%概率生成特殊敌机
            const width = type === 1 ? 40 : 60;
            const height = type === 1 ? 30 : 45;
            const speed = type === 1 ? 2 + gameState.level * 0.2 : 1.5 + gameState.level * 0.15;
            const health = type === 1 ? 1 : 2;
            
            gameState.enemies.push({
                x: Math.random() * (canvas.width - width),
                y: -height,
                width: width,
                height: height,
                speed: speed,
                type: type,
                health: health
            });
        }
        
        // 玩家射击
        function playerShoot() {
            if (gameState.player.shootCooldown <= 0) {
                gameState.bullets.push({
                    x: gameState.player.x + gameState.player.width / 2,
                    y: gameState.player.y,
                    radius: 4,
                    speed: 10
                });
                
                gameState.player.shootCooldown = 15; // 射击冷却时间
                
                // 添加射击粒子效果
                for (let i = 0; i < 5; i++) {
                    gameState.particles.push({
                        x: gameState.player.x + gameState.player.width / 2,
                        y: gameState.player.y,
                        size: Math.random() * 3 + 1,
                        speedX: (Math.random() - 0.5) * 3,
                        speedY: Math.random() * -2 - 1,
                        color: '#ffff00',
                        alpha: 1,
                        life: 30
                    });
                }
            }
        }
        
        // 创建爆炸粒子
        function createExplosion(x, y, color, count) {
            for (let i = 0; i < count; i++) {
                gameState.particles.push({
                    x: x,
                    y: y,
                    size: Math.random() * 4 + 2,
                    speedX: (Math.random() - 0.5) * 6,
                    speedY: (Math.random() - 0.5) * 6,
                    color: color,
                    alpha: 1,
                    life: Math.random() * 30 + 20
                });
            }
        }
        
        // 检测碰撞
        function checkCollision(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 updateGame(timestamp) {
            if (!gameState.isRunning) return;
            
            const deltaTime = timestamp - gameState.lastTime;
            gameState.lastTime = timestamp;
            
            // 更新玩家射击冷却
            if (gameState.player.shootCooldown > 0) {
                gameState.player.shootCooldown--;
            }
            
            // 移动玩家
            if (gameState.player.isMovingLeft) {
                gameState.player.x = Math.max(0, gameState.player.x - gameState.player.speed);
            }
            if (gameState.player.isMovingRight) {
                gameState.player.x = Math.min(canvas.width - gameState.player.width, gameState.player.x + gameState.player.speed);
            }
            
            // 生成敌机
            gameState.enemySpawnTimer += deltaTime;
            if (gameState.enemySpawnTimer > gameState.enemySpawnInterval) {
                spawnEnemy();
                gameState.enemySpawnTimer = 0;
                // 随着等级提高,敌机生成速度加快
                gameState.enemySpawnInterval = Math.max(200, 1000 - gameState.level * 50);
            }
            
            // 更新敌机位置
            gameState.enemies.forEach((enemy, index) => {
                enemy.y += enemy.speed;
                
                // 检测敌机与玩家碰撞
                if (checkCollision(gameState.player, enemy)) {
                    gameState.lives--;
                    createExplosion(
                        enemy.x + enemy.width / 2,
                        enemy.y + enemy.height / 2,
                        '#ff5555',
                        30
                    );
                    gameState.enemies.splice(index, 1);
                    updateUI();
                    
                    if (gameState.lives <= 0) {
                        gameOver();
                        return;
                    }
                }
                
                // 移除超出屏幕的敌机
                if (enemy.y > canvas.height) {
                    gameState.enemies.splice(index, 1);
                }
            });
            
            // 更新子弹位置
            gameState.bullets.forEach((bullet, index) => {
                bullet.y -= bullet.speed;
                
                // 检测子弹与敌机碰撞
                let hit = false;
                gameState.enemies.forEach((enemy, enemyIndex) => {
                    if (
                        bullet.x > enemy.x && 
                        bullet.x < enemy.x + enemy.width &&
                        bullet.y > enemy.y && 
                        bullet.y < enemy.y + enemy.height
                    ) {
                        enemy.health--;
                        
                        if (enemy.health <= 0) {
                            // 敌机被摧毁
                            gameState.score += enemy.type === 1 ? 100 : 200;
                            createExplosion(
                                enemy.x + enemy.width / 2,
                                enemy.y + enemy.height / 2,
                                enemy.type === 1 ? '#ff5555' : '#ffaa00',
                                40
                            );
                            gameState.enemies.splice(enemyIndex, 1);
                        } else {
                            // 敌机受伤但没有被摧毁
                            createExplosion(
                                bullet.x,
                                bullet.y,
                                '#ffff00',
                                10
                            );
                        }
                        
                        hit = true;
                        gameState.bullets.splice(index, 1);
                        
                        // 更新等级
                        const newLevel = Math.floor(gameState.score / 1000) + 1;
                        if (newLevel > gameState.level) {
                            gameState.level = newLevel;
                        }
                        
                        updateUI();
                    }
                });
                
                // 移除超出屏幕的子弹
                if (!hit && bullet.y < 0) {
                    gameState.bullets.splice(index, 1);
                }
            });
            
            // 更新粒子
            gameState.particles.forEach((particle, index) => {
                particle.x += particle.speedX;
                particle.y += particle.speedY;
                particle.life--;
                particle.alpha = particle.life / 30;
                
                if (particle.life <= 0) {
                    gameState.particles.splice(index, 1);
                }
            });
            
            // 更新星星
            updateStars();
            
            // 继续游戏循环
            if (!gameState.gameOver) {
                requestAnimationFrame(updateGame);
            }
        }
        
        // 绘制游戏
        function drawGame() {
            if (!gameState.isRunning) return;
            
            // 清除画布
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            
            // 绘制背景
            drawStars();
            
            // 绘制粒子
            gameState.particles.forEach(particle => {
                drawParticle(particle);
            });
            
            // 绘制子弹
            gameState.bullets.forEach(bullet => {
                drawBullet(bullet);
            });
            
            // 绘制敌机
            gameState.enemies.forEach(enemy => {
                drawEnemy(enemy);
            });
            
            // 绘制玩家
            drawPlayer();
            
            // 继续绘制循环
            requestAnimationFrame(drawGame);
        }
        
        // 游戏结束
        function gameOver() {
            gameState.gameOver = true;
            gameState.isRunning = false;
            document.getElementById('finalScore').textContent = gameState.score;
            document.getElementById('gameOverScreen').classList.remove('hidden');
        }
        
        // 开始游戏
        function startGame() {
            initGame();
            gameState.isRunning = true;
            gameState.gameOver = false;
            gameState.lastTime = performance.now();
            document.getElementById('startScreen').classList.add('hidden');
            document.getElementById('gameOverScreen').classList.add('hidden');
            updateGame(gameState.lastTime);
            drawGame();
        }
        
        // 事件监听
        document.getElementById('startBtn').addEventListener('click', startGame);
        document.getElementById('restartBtn').addEventListener('click', startGame);
        
        // 键盘控制
        window.addEventListener('keydown', (e) => {
            if (!gameState.isRunning) return;
            
            switch(e.key) {
                case 'ArrowLeft':
                    gameState.player.isMovingLeft = true;
                    break;
                case 'ArrowRight':
                    gameState.player.isMovingRight = true;
                    break;
                case ' ':
                    playerShoot();
                    e.preventDefault();
                    break;
            }
        });
        
        window.addEventListener('keyup', (e) => {
            if (!gameState.isRunning) return;
            
            switch(e.key) {
                case 'ArrowLeft':
                    gameState.player.isMovingLeft = false;
                    break;
                case 'ArrowRight':
                    gameState.player.isMovingRight = false;
                    break;
            }
        });
        
        // 鼠标控制射击
        canvas.addEventListener('click', () => {
            if (gameState.isRunning) {
                playerShoot();
            }
        });
        
        // 初始化星星背景
        initStars();
        
        // 初始绘制
        drawGame();
    </script>
</body>
</html>

游戏特点

  1. 视觉效果

    • 太空背景与动态星星
    • 粒子爆炸效果
    • 战机引擎火焰动画
    • 发光子弹效果
  2. 游戏机制

    • 玩家控制战机左右移动
    • 空格键或鼠标点击发射子弹
    • 两种类型的敌机(普通和特殊)
    • 分数系统和等级提升
    • 生命值系统
  3. 游戏状态

    • 开始界面
    • 游戏进行界面
    • 游戏结束界面
  4. 控制方式

    • 键盘左右方向键控制移动
    • 空格键或鼠标点击射击

如何玩

  1. 点击"开始游戏"按钮进入游戏
  2. 使用左右方向键移动战机
  3. 按空格键或鼠标点击发射子弹
  4. 射击敌机获得分数,每1000分提升一个等级
  5. 躲避敌机和陨石,被撞击会减少生命值
  6. 生命值归零时游戏结束

这个游戏包含了完整的游戏循环、碰撞检测、粒子效果和UI界面,可以直接复制代码到HTML文件中运行!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值