[js mini-game & case] Pure front-end realization of aircraft war, with source code

Skill:

Use html js css to realize the small game of airplane war

need:

Our aircraft moves left and right, and press the space to launch artillery shells. The enemy aircraft flies from top to bottom. The aircraft that touches our artillery shells will be annihilated. Our army will also be annihilated when it touches the enemy aircraft. Our aircraft will get props Can increase ballistics

Ideas:

Initialization: Initially create our aircraft, use a timer to create an enemy aircraft at regular intervals, and the position of the enemy aircraft is randomly generated by random()

Movement: use position: absolute in the aircraft style, and then listen to the keyboard being pressed and use the left position to move our aircraft, and the enemy aircraft also has a timer to move down regularly

Launch cannonballs: creating cannonballs is similar to creating an enemy, the difference is that the position of the cannonball is initialized according to the position of our aircraft, while the position of the enemy's aircraft is random

Enemy annihilation: Obtain location information through getBoundingClientRect() to determine whether it is in contact; our army annihilation is similar

Energy balls: The small balls produced are similar to the enemy army, just stop changing the style

Renderings:

 Full code:

<!DOCTYPE html>
<html>

<head>
    <title>飞机大战</title>
    <style>
        html,
        body {
            margin: 0;
            padding: 0;
        }

        /* 游戏边框 */
        .game-board {
            width: 400px;
            height: 600px;
            border: 1px solid black;
            position: relative;
            overflow: hidden;
        }

        /* 我方飞机 */
        .player {
            width: 50px;
            height: 50px;
            background-color: blue;
            position: absolute;
            bottom: 0;
        }

        /* 敌方飞机 */
        .enemy {
            width: 30px;
            height: 30px;
            background-color: red;
            position: absolute;
            top: 0;
        }

        /* 子弹 */
        .bullet {
            width: 2px;
            height: 10px;
            background-color: black;
            position: absolute;
        }

        /* 分数 */
        .score {
            font-size: 18px;
            position: absolute;
            top: 10px;
            right: 10px;
        }

        /* 能量小球 */
        .power-up {
            width: 20px;
            height: 20px;
            background-color: green;
            position: absolute;
        }
    </style>
</head>

<body>
    <div class="game-board" id="game-board">
        <div class="score">分数: <span id="score">0</span></div>
    </div>

    <script>
        const gameBoard = document.getElementById('game-board');
        // 创建我方飞机
        const player = document.createElement('div');
        // 我军飞机初始位置
        let playerLeft = 175;
        player.style.left = `${playerLeft}px`;
        // 游戏是否结束
        let isGameOver = false;
        // 是否在发射子弹的状态
        let isShooting = false;
        // 初始化分数
        let score = 0;
        const scoreElement = document.getElementById('score');
        // 初始化我军飞机样式
        player.classList.add('player');
        gameBoard.appendChild(player);

        // 创造敌军飞机
        function createEnemy() {
            const enemy = document.createElement('div');
            // 随机位置
            let enemyLeft = Math.floor(Math.random() * 350);
            enemy.classList.add('enemy');
            enemy.style.left = `${enemyLeft}px`;
            gameBoard.appendChild(enemy);
            moveEnemy(enemy);
        }

        // 每30ms敌军就会向下移动五像素,如果到达边界就会取消移动 并且移除样式
        function moveEnemy(enemy) {
            let enemyTop = 0;
            let enemyInterval = setInterval(() => {
                if (enemyTop > 600 || isGameOver) {
                    clearInterval(enemyInterval);
                    // 出界 清除dom
                    gameBoard.removeChild(enemy);
                }

                enemy.style.top = `${enemyTop}px`;
                enemyTop += 5;

                // 如果两个接触到 就结束游戏
                if (checkCollision(player, enemy)) {
                    gameOver();
                }
            }, 30);
        }

        // 创建能量小球
        function createPowerUp() {
            const powerUp = document.createElement('div');
            // 随机水平位置
            let powerUpLeft = Math.floor(Math.random() * 350);
            powerUp.classList.add('power-up');
            powerUp.style.left = `${powerUpLeft}px`;
            gameBoard.appendChild(powerUp);

            movePowerUp(powerUp);
        }

        // 移动绿色小球
        // 每30ms绿色小球就会向下移动五像素,如果到达边界就会取消移动 并且移除样式
        function movePowerUp(powerUp) {
            let powerUpTop = 0;
            let powerUpInterval = setInterval(() => {
                if (powerUpTop > 600 || isGameOver) {
                    clearInterval(powerUpInterval);
                    // 出界 清除dom
                    gameBoard.removeChild(powerUp);
                }

                powerUp.style.top = `${powerUpTop}px`;
                powerUpTop += 5;

                // 我方飞机吃到绿色小球
                if (checkCollision(player, powerUp)) {
                    gameBoard.removeChild(powerUp);
                    powerUpEffect();
                }
            }, 30);
        }


        let isDoubleBullet = false;
        let numBullets = 1;

        // 新增函数,处理绿色小球效果
        function powerUpEffect() {
            isDoubleBullet = true;
            numBullets++;
        }

        // 创造子弹
        function createBullet(left, bottom) {
            // console.log(left, bottom)
            const bullet = document.createElement('div');
            bullet.classList.add('bullet');
            bullet.style.left = `${left + 25}px`;
            bullet.style.bottom = `50px`;
            gameBoard.appendChild(bullet);

            moveBullet(bullet);
        }
        // 子弹移动
        function moveBullet(bullet) {
            let bulletBottom = 50;
            let bulletInterval = setInterval(() => {
                if (bulletBottom > 600 || isGameOver) {
                    clearInterval(bulletInterval);
                    gameBoard.removeChild(bullet);
                }

                bullet.style.bottom = `${bulletBottom}px`;
                bulletBottom += 10;

                const enemies = document.querySelectorAll('.enemy');
                // 判断子弹是否接触到敌军飞机
                enemies.forEach(enemy => {
                    if (checkCollision(bullet, enemy)) {
                        clearInterval(bulletInterval);
                        gameBoard.removeChild(bullet);
                        gameBoard.removeChild(enemy);
                        increaseScore();
                    }
                });
            }, 30);
        }

        // 检测是否接触
        function checkCollision(a, b) {
            // getBoundingClientRect()是一个DOM元素对象的方法,用于获取该元素相对于视口(viewport)的位置和尺寸信息
            // 从而进行碰撞检测、位置计算等操作
            const aRect = a.getBoundingClientRect();
            const bRect = b.getBoundingClientRect();

            return !(
                // 我军飞机的top如果小于敌军的bottom 说明已经两机已经接触了
                aRect.top > bRect.bottom ||
                aRect.bottom < bRect.top ||
                aRect.right < bRect.left ||
                aRect.left > bRect.right
            );
        }

        // 游戏结束
        function gameOver() {
            isGameOver = true;
            // 移除gameBoard元素的所有子元素,即清空游戏面板
            while (gameBoard.firstChild) {
                gameBoard.removeChild(gameBoard.firstChild);
            }
            // 停止创造敌军飞机
            clearInterval(enemyInterval)
            gameBoard.innerHTML = '游戏结束!最终分数为: ' + score;
        }

        // 分数增加
        function increaseScore() {
            score++;
            scoreElement.textContent = score;

            if (score % 8 === 0) { // 每射杀十个敌方飞机,创建绿色小球
                createPowerUp();
            }
        }

        document.addEventListener('keydown', function (event) {
            // 空格键
            if (event.keyCode === 32 && !isGameOver) {
                // 发射与停止发射子弹
                if (!isShooting) {
                    isShooting = true;
                    shoot();
                }
            } else if (event.keyCode === 37) { // 左箭头键
                if (playerLeft > 0) playerLeft -= 10;
            } else if (event.keyCode === 39) { // 右箭头键
                if (playerLeft < 350) playerLeft += 10;
            }

            player.style.left = playerLeft + 'px';
        });

        // 控制发射子弹
        function shoot() {
            if (isShooting) {
                const plane = document.querySelector('.player');
                const planeLeft = parseInt(plane.style.left);
                const planeBottom = parseInt(plane.style.bottom);
                console.log(plane.style.left)

                // 增加子弹
                for (let i = 0; i < numBullets; i++) {
                    if (isDoubleBullet) {
                        createBullet(planeLeft - 5 + 10 * i , planeBottom);
                    } else {
                        createBullet(planeLeft, planeBottom);
                    }
                }
                // 设置发射子弹的频率,这里是每隔200毫秒发射一颗子弹
                setTimeout(shoot, 200);
            }
        }

        document.addEventListener('keyup', function (event) {
            if (event.keyCode === 32) { // 当松开空格键时,关闭发射状态
                isShooting = false;
            }
        });

        let enemyInterval = setInterval(createEnemy, 1000); // 每隔1秒创建一个敌方飞机
    </script>
</body>

</html>

If you have other questions, please leave a comment

Guess you like

Origin blog.csdn.net/weixin_52479803/article/details/131896737