基于HTML+JS实现的简单飞机大战小游戏

1.效果图

2.代码实现

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>太空射击游戏</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            background: linear-gradient(to bottom, #000046, #1d1d1d);
            color: #fff;
            font-family: Arial, sans-serif;
        }
        canvas {
            border: 2px solid #fff;
            background: url('https://www.transparenttextures.com/patterns/dark-matter.png');
            background-size: cover;
        }
        #score {
            position: absolute;
            top: 20px;
            left: 20px;
            font-size: 24px;
        }
        #lives {
            position: absolute;
            top: 20px;
            right: 20px;
            font-size: 24px;
        }
    </style>
</head>
<body>
<canvas id="gameCanvas" width="800" height="600"></canvas>
<div id="score">得分: 0</div>
<div id="lives">生命: 3</div>
<script>
    const canvas = document.getElementById('gameCanvas');
    const ctx = canvas.getContext('2d');

    // 玩家设置
    const playerWidth = 50;
    const playerHeight = 30;
    const playerSpeed = 5;
    let playerX = (canvas.width - playerWidth) / 2;
    let rightPressed = false;
    let leftPressed = false;

    // 子弹设置
    const bulletWidth = 5;
    const bulletHeight = 20;
    const bulletSpeed = 4;
    let bullets = [];

    // 敌人设置
    const enemyWidth = 50;
    const enemyHeight = 30;
    const enemyRowCount = 3;
    const enemyColumnCount = 5;
    const enemyPadding = 10;
    const enemyOffsetTop = 30;
    const enemyOffsetLeft = 30;
    let enemies = [];
    for (let c = 0; c < enemyColumnCount; c++) {
        enemies[c] = [];
        for (let r = 0; r < enemyRowCount; r++) {
            enemies[c][r] = {
                x: c * (enemyWidth + enemyPadding) + enemyOffsetLeft,
                y: r * (enemyHeight + enemyPadding) + enemyOffsetTop,
                status: 1
            };
        }
    }

    // 游戏状态
    let score = 0;
    let lives = 3;
    let enemySpeed = 1;
    let enemyDirection = 1; // 1 = 右, -1 = 左

    // 事件监听
    document.addEventListener('keydown', keyDownHandler);
    document.addEventListener('keyup', keyUpHandler);
    document.addEventListener('keydown', shootBullet);

    function keyDownHandler(e) {
        if (e.key === 'Right' || e.key === 'ArrowRight') {
            rightPressed = true;
        } else if (e.key === 'Left' || e.key === 'ArrowLeft') {
            leftPressed = true;
        }
    }

    function keyUpHandler(e) {
        if (e.key === 'Right' || e.key === 'ArrowRight') {
            rightPressed = false;
        } else if (e.key === 'Left' || e.key === 'ArrowLeft') {
            leftPressed = false;
        }
    }

    function shootBullet(e) {
        if (e.key === ' ' || e.key === 'Enter') {
            bullets.push({ x: playerX + playerWidth / 2, y: canvas.height - playerHeight });
        }
    }

    function drawPlayer() {
        ctx.beginPath();
        ctx.rect(playerX, canvas.height - playerHeight, playerWidth, playerHeight);
        ctx.fillStyle = '#00f';
        ctx.fill();
        ctx.closePath();
    }

    function drawBullet() {
        ctx.beginPath();
        bullets.forEach(bullet => {
            ctx.rect(bullet.x, bullet.y, bulletWidth, bulletHeight);
            ctx.fillStyle = '#f00';
            ctx.fill();
        });
        ctx.closePath();
    }

    function drawEnemies() {
        for (let c = 0; c < enemyColumnCount; c++) {
            for (let r = 0; r < enemyRowCount; r++) {
                if (enemies[c][r].status === 1) {
                    const enemyX = enemies[c][r].x;
                    const enemyY = enemies[c][r].y;
                    ctx.beginPath();
                    ctx.rect(enemyX, enemyY, enemyWidth, enemyHeight);
                    ctx.fillStyle = '#0f0';
                    ctx.fill();
                    ctx.closePath();
                }
            }
        }
    }

    function collisionDetection() {
        bullets.forEach((bullet, index) => {
            for (let c = 0; c < enemyColumnCount; c++) {
                for (let r = 0; r < enemyRowCount; r++) {
                    const enemy = enemies[c][r];
                    if (enemy.status === 1) {
                        if (bullet.x > enemy.x && bullet.x < enemy.x + enemyWidth &&
                            bullet.y > enemy.y && bullet.y < enemy.y + enemyHeight) {
                            enemy.status = 0;
                            bullets.splice(index, 1);
                            score += 10;
                        }
                    }
                }
            }
        });

        enemies.forEach((column) => {
            column.forEach((enemy) => {
                if (enemy.status === 1 && enemy.y + enemyHeight >= canvas.height - playerHeight) {
                    lives -= 1;
                    enemy.status = 0;
                    if (lives <= 0) {
                        alert('游戏结束');
                        document.location.reload();
                    }
                }
            });
        });
    }

    function updateBulletPosition() {
        bullets.forEach(bullet => {
            bullet.y -= bulletSpeed;
        });
        bullets = bullets.filter(bullet => bullet.y > -bulletHeight);
    }

    function drawScore() {
        document.getElementById('score').innerText = `得分: ${score}`;
    }

    function drawLives() {
        document.getElementById('lives').innerText = `生命: ${lives}`;
    }

    function moveEnemies() {
        let moveDown = false;
        enemies.forEach((column) => {
            column.forEach((enemy) => {
                if (enemy.status === 1) {
                    enemy.x += enemySpeed * enemyDirection;
                    if (enemy.x + enemyWidth > canvas.width || enemy.x < 0) {
                        moveDown = true;
                    }
                }
            });
        });

        if (moveDown) {
            enemyDirection *= -1;
            enemies.forEach((column) => {
                column.forEach((enemy) => {
                    if (enemy.status === 1) {
                        enemy.y += enemyHeight / 2;
                    }
                });
            });
        }
    }

    function draw() {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        drawPlayer();
        drawBullet();
        drawEnemies();
        collisionDetection();
        updateBulletPosition();
        moveEnemies();
        drawScore();
        drawLives();

        if (rightPressed && playerX < canvas.width - playerWidth) {
            playerX += playerSpeed;
        } else if (leftPressed && playerX > 0) {
            playerX -= playerSpeed;
        }

        requestAnimationFrame(draw);
    }

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java小诚

新手一个,望包涵

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值