前端技术搭建飞机大战小游戏(内含源码)

news2024/9/21 14:29:39

The sand accumulates to form a pagoda

  • ✨ 写在前面
  • ✨ 功能介绍
  • ✨ 页面搭建
  • ✨ 样式设置
  • ✨ 逻辑部分


✨ 写在前面

上周我们实通过前端基础实现了弹珠游戏,当然很多伙伴再评论区提出了想法,后续我们会考虑实现的,今天还是继续按照我们原定的节奏来带领大家完成一个飞机大战游戏,功能也比较简单简单,也是想借助这样一个简单的功能,然后来帮助大家了解我们JavaScript在前端中的作用, 在前面的文章当中我们也提及到我们在本系列的专栏是循序渐进从简单到复杂的过程,后续会带领大家用前端实现翻卡片、扫雷、贪吃蛇等有趣的小游戏,纯前端语言实现,都会陆续带给大家。欢迎大家订阅我们这份前端小游戏的专栏。


✨ 功能介绍

在这里插入图片描述

飞机射击游戏是一款经典的射击游戏,让你化身为一名勇敢的飞行员,驾驶着一架战斗机,与敌机展开激烈的空中战斗。你的任务是摧毁敌机并尽可能获得高分。准备好挑战吧!控制飞机移动: 使用键盘上的左右箭头键来控制飞机左右移动,躲避敌机的攻击。发射子弹: 按下空格键发射子弹,瞄准并摧毁敌机。摧毁敌机: 当你的子弹与敌机发生碰撞时,敌机将被击中并炸毁,你将获得分数。注意躲避: 避免敌机的攻击,不要让敌机碰撞到你的飞机,否则游戏结束(这个功能留给大家实现哦)实时分数: 游戏界面会实时显示你的得分,挑战自己,争取创造最高分数。

准备好了吗?驾驶你的战斗机,击败所有敌人,成为空中的王者吧!当然你也可以通过修改游戏的参数来控制难度等级!


✨ 页面搭建

创建文件

首先呢我们创建我们的HTML文件,这里我就直接命名为 飞机大战.html 了,大家可以随意命名, 文件创建生成后我们通过编辑器打开,这里我用的是VScode, 然后初始化我们的代码结构,那在这里告诉大家一个快捷键,就是我们敲上我们英文的一个 ! 我们敲击回车直接就会给我们生成基础版本的前端代码结构。

在这里插入图片描述

文档声明和编码设置: 在HTML文档的头部,使用<!DOCTYPE>声明HTML文档类型,确保浏览器以正确的方式渲染网页内容。同时,设置UTF-8编码,以确保浏览器能够正确地解析和显示中文字符。下面我就开始搭建我们的DOM结构了!

DOM结构搭建

  • <div id="game-board">:这是游戏的主要容器,包含了游戏中的所有元素,如玩家飞机、敌机和得分信息。
  • <div id="player">:这是表示玩家飞机的元素,玩家将控制它来躲避敌机的攻击并射击敌机。
  • <div id="score">:这是显示玩家得分的元素,初始值为 0,玩家击败敌机后,得分将实时更新并显示在这个元素中。

这段代码是游戏界面的基础结构,它创建了一个游戏板,包含了玩家飞机和得分信息,为游戏提供了一个可视化的界面。玩家将在这个界面上操控飞机,与敌机进行激烈的空战,尽可能地躲避敌机的攻击并击败敌机,以获得更高的得分。

<div id="game-board">
    <div id="player"></div>
    <div id="score">Score: 0</div>
</div>

在这里插入图片描述


✨ 样式设置

我们看到了上面的的DOM已经搭建好了,但是很显然样式比较随意了,我们简单的来配置一下样式吧,其实我们本专栏也是想带领大家掌握一些逻辑所以样式方面我们就一切从简;

  • #game-board:定义游戏板的样式,设置了宽度、高度和边框,并将其定位为相对位置,并通过margin: 0 auto;使其水平居中显示。
  • #player:定义玩家飞机的样式,设置了宽度、高度和背景颜色。使用绝对定位,将其置于游戏板底部,并通过left: 50%; transform: translateX(-50%);使其水平居中显示。
  • .bullet:定义子弹的样式,设置了宽度、高度和背景颜色。使用绝对定位,用于表示玩家飞机发射的子弹。
  • .enemy:定义敌机的样式,设置了宽度、高度和背景颜色。使用绝对定位,用于表示敌机。
  • #score:定义得分信息的样式,设置了字体大小和居中对齐。

这段代码主要是为游戏界面中的各个元素定义了基本的样式,包括游戏板、玩家飞机、子弹和敌机。通过设置不同的样式,使得这些元素在游戏界面中能够以合适的尺寸和颜色进行显示,提供了良好的可视化效果,让玩家能够清晰地辨别游戏中的各个元素。

<style>
    /* CSS 样式 */

    #game-board {
        width: 480px;
        height: 500px;
        border: 1px solid black;
        position: relative;
        margin: 0 auto;
    }

    #player {
        width: 50px;
        height: 50px;
        background-color: red;
        position: absolute;
        bottom: 0;
        left: 50%;
        transform: translateX(-50%);
    }

    .bullet {
        width: 5px;
        height: 20px;
        background-color: black;
        position: absolute;
    }

    .enemy {
        width: 40px;
        height: 40px;
        background-color: blue;
        position: absolute;
    }

    #score {
        font-size: 24px;
        text-align: center;
    }
</style>

在这里插入图片描述

✨ 逻辑部分

上面我们搭建了基本的样式,下面呢我们就通过js代码,实现我们游戏的功能吧;首先,我们定义了一些变量:

gameBoard:代表游戏板的 DOM 元素。
player:代表玩家飞机的 DOM 元素。
scoreElement:代表显示分数的 DOM 元素。
bullets:用于存储子弹的数组。
enemies:用于存储敌机的数组。
score:表示当前的分数。

movePlayer(direction) 函数:用于移动玩家飞机的位置。根据传入的参数 direction 来判断向左还是向右移动,然后更新玩家飞机的位置。 shoot() 函数:用于发射子弹。创建一个子弹的 DOM 元素,设置其位置,并将其添加到游戏板中和 bullets 数组中。 moveBullets() 函数:用于移动子弹。遍历 bullets 数组中的每个子弹,更新其位置。如果子弹超出了游戏板的高度,则将其移除。 createEnemy() 函数:用于创建敌机。创建一个敌机的 DOM 元素,设置其位置,并将其添加到游戏板中和 enemies 数组中。

moveEnemies() 函数:用于移动敌机。遍历 enemies 数组中的每个敌机,更新其位置。如果敌机超出了游戏板的高度,则将其移除。 detectCollision() 函数:用于检测碰撞。遍历子弹和敌机数组,判断是否发生了碰撞。如果碰撞发生,则移除相应的子弹和敌机,并增加分数。 gameLoop() 函数:游戏循环函数,用于持续更新子弹、敌机的位置,并检测碰撞。startGame() 函数:游戏开始函数,用于初始化游戏状态,包括重置分数、玩家飞机位置,清空子弹和敌机数组,以及设置定时器调用 createEnemygameLoop 函数。

监听键盘事件,当按下箭头左键时调用 movePlayer("left"),按下箭头右键时调用movePlayer("right"),按下空格键时调用 shoot()。 最后,调用 startGame() 函数来启动游戏。通过这些函数和事件监听,游戏可以实现玩家飞机的移动、子弹的发射、敌机的创建和移动,以及碰撞的检测和分数的更新。玩家需要使用箭头键控制飞机移动,通过发射子弹来摧毁敌机,并且在游戏循环中持续检测碰撞和更新分数。游戏的目标是尽可能地摧毁更多的敌机,获得高分。

<script>
    // JavaScript 代码

    let gameBoard = document.getElementById("game-board");
    let player = document.getElementById("player");
    let scoreElement = document.getElementById("score");

    let bullets = [];
    let enemies = [];
    let score = 0;

    function movePlayer(direction) {
        let currentPosition = parseInt(player.style.left) || 0;

        if (direction === "left") {
            currentPosition -= 20;
        } else if (direction === "right") {
            currentPosition += 20;
        }

        // 限制飞机移动范围在游戏板内
        currentPosition = Math.max(0, Math.min(currentPosition, gameBoard.offsetWidth - player.offsetWidth));

        player.style.left = currentPosition + "px";
    }

    function shoot() {
        let bullet = document.createElement("div");
        bullet.className = "bullet";
        bullet.style.left = parseInt(player.style.left) + player.offsetWidth / 2 - 2.5 + "px";
        bullet.style.bottom = player.offsetHeight + "px";
        gameBoard.appendChild(bullet);
        bullets.push(bullet);
    }

    function moveBullets() {
        bullets.forEach((bullet, bulletIndex) => {
            let currentPosition = parseInt(bullet.style.bottom) || 0;
            currentPosition += 10;

            if (currentPosition >= gameBoard.offsetHeight) {
                bullet.remove();
                bullets.splice(bulletIndex, 1);
            } else {
                bullet.style.bottom = currentPosition + "px";
            }
        });
    }

    function createEnemy() {
        let enemy = document.createElement("div");
        enemy.className = "enemy";
        enemy.style.left = Math.random() * (gameBoard.offsetWidth - 40) + "px";
        enemy.style.top = "0px";
        gameBoard.appendChild(enemy);
        enemies.push(enemy);
    }

    function moveEnemies() {
        enemies.forEach((enemy, enemyIndex) => {
            let currentPosition = parseInt(enemy.style.top) || 0;
            currentPosition += 5;

            if (currentPosition >= gameBoard.offsetHeight) {
                enemy.remove();
                enemies.splice(enemyIndex, 1);
            } else {
                enemy.style.top = currentPosition + "px";
            }
        });
    }

    function detectCollision() {
        bullets.forEach((bullet, bulletIndex) => {

            enemies.forEach((enemy, enemyIndex) => {
                if (
                    bullet.offsetTop <= enemy.offsetTop + enemy.offsetHeight &&
                    bullet.offsetTop + bullet.offsetHeight >= enemy.offsetTop &&
                    bullet.offsetLeft <= enemy.offsetLeft + enemy.offsetWidth &&
                    bullet.offsetLeft + bullet.offsetWidth >= enemy.offsetLeft
                ) {
                    bullet.remove();
                    bullets.splice(bulletIndex, 1);
                    enemy.remove();
                    enemies.splice(enemyIndex, 1);
                    score += 10;
                    scoreElement.innerHTML = "Score: " + score;
                }
            });
        });
    } function gameLoop() {
        moveBullets();
        moveEnemies();
        detectCollision();
    }

    function startGame() {
        score = 0;
        scoreElement.innerHTML = "Score: " + score;

        player.style.left = (gameBoard.offsetWidth - player.offsetWidth) / 2 + "px";

        bullets.forEach(bullet => bullet.remove());
        bullets = [];

        enemies.forEach(enemy => enemy.remove());
        enemies = [];

        setInterval(createEnemy, 1000);
        setInterval(gameLoop, 30);
    }

    document.addEventListener("keydown", function (event) {
        if (event.code === "ArrowLeft") {
            movePlayer("left");
        } else if (event.code === "ArrowRight") {
            movePlayer("right");
        } else if (event.code === "Space") {
            shoot();
        }
    });

    startGame();
</script>

完整代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        /* CSS 样式 */

        #game-board {
            width: 480px;
            height: 500px;
            border: 1px solid black;
            position: relative;
            margin: 0 auto;
        }

        #player {
            width: 50px;
            height: 50px;
            background-color: red;
            position: absolute;
            bottom: 0;
            left: 50%;
            transform: translateX(-50%);
        }

        .bullet {
            width: 5px;
            height: 20px;
            background-color: black;
            position: absolute;
        }

        .enemy {
            width: 40px;
            height: 40px;
            background-color: blue;
            position: absolute;
        }

        #score {
            font-size: 24px;
            text-align: center;
        }
    </style>
</head>

<body>
    <div id="game-board">
        <div id="player"></div>
        <div id="score">Score: 0</div>
    </div>
</body>
<script>
    // JavaScript 代码

    let gameBoard = document.getElementById("game-board");
    let player = document.getElementById("player");
    let scoreElement = document.getElementById("score");

    let bullets = [];
    let enemies = [];
    let score = 0;

    function movePlayer(direction) {
        let currentPosition = parseInt(player.style.left) || 0;

        if (direction === "left") {
            currentPosition -= 20;
        } else if (direction === "right") {
            currentPosition += 20;
        }

        // 限制飞机移动范围在游戏板内
        currentPosition = Math.max(0, Math.min(currentPosition, gameBoard.offsetWidth - player.offsetWidth));

        player.style.left = currentPosition + "px";
    }

    function shoot() {
        let bullet = document.createElement("div");
        bullet.className = "bullet";
        bullet.style.left = parseInt(player.style.left) + player.offsetWidth / 2 - 2.5 + "px";
        bullet.style.bottom = player.offsetHeight + "px";
        gameBoard.appendChild(bullet);
        bullets.push(bullet);
    }

    function moveBullets() {
        bullets.forEach((bullet, bulletIndex) => {
            let currentPosition = parseInt(bullet.style.bottom) || 0;
            currentPosition += 10;

            if (currentPosition >= gameBoard.offsetHeight) {
                bullet.remove();
                bullets.splice(bulletIndex, 1);
            } else {
                bullet.style.bottom = currentPosition + "px";
            }
        });
    }

    function createEnemy() {
        let enemy = document.createElement("div");
        enemy.className = "enemy";
        enemy.style.left = Math.random() * (gameBoard.offsetWidth - 40) + "px";
        enemy.style.top = "0px";
        gameBoard.appendChild(enemy);
        enemies.push(enemy);
    }

    function moveEnemies() {
        enemies.forEach((enemy, enemyIndex) => {
            let currentPosition = parseInt(enemy.style.top) || 0;
            currentPosition += 5;

            if (currentPosition >= gameBoard.offsetHeight) {
                enemy.remove();
                enemies.splice(enemyIndex, 1);
            } else {
                enemy.style.top = currentPosition + "px";
            }
        });
    }

    function detectCollision() {
        bullets.forEach((bullet, bulletIndex) => {

            enemies.forEach((enemy, enemyIndex) => {
                if (
                    bullet.offsetTop <= enemy.offsetTop + enemy.offsetHeight &&
                    bullet.offsetTop + bullet.offsetHeight >= enemy.offsetTop &&
                    bullet.offsetLeft <= enemy.offsetLeft + enemy.offsetWidth &&
                    bullet.offsetLeft + bullet.offsetWidth >= enemy.offsetLeft
                ) {
                    bullet.remove();
                    bullets.splice(bulletIndex, 1);
                    enemy.remove();
                    enemies.splice(enemyIndex, 1);
                    score += 10;
                    scoreElement.innerHTML = "Score: " + score;
                }
            });
        });
    } function gameLoop() {
        moveBullets();
        moveEnemies();
        detectCollision();
    }

    function startGame() {
        score = 0;
        scoreElement.innerHTML = "Score: " + score;

        player.style.left = (gameBoard.offsetWidth - player.offsetWidth) / 2 + "px";

        bullets.forEach(bullet => bullet.remove());
        bullets = [];

        enemies.forEach(enemy => enemy.remove());
        enemies = [];

        setInterval(createEnemy, 1000);
        setInterval(gameLoop, 30);
    }

    document.addEventListener("keydown", function (event) {
        if (event.code === "ArrowLeft") {
            movePlayer("left");
        } else if (event.code === "ArrowRight") {
            movePlayer("right");
        } else if (event.code === "Space") {
            shoot();
        }
    });

    startGame();
</script>

</html>

本期推荐

在这里插入图片描述

原创不易,还希望各位大佬支持一下 \textcolor{blue}{原创不易,还希望各位大佬支持一下} 原创不易,还希望各位大佬支持一下

👍 点赞,你的认可是我创作的动力! \textcolor{green}{点赞,你的认可是我创作的动力!} 点赞,你的认可是我创作的动力!

⭐️ 收藏,你的青睐是我努力的方向! \textcolor{green}{收藏,你的青睐是我努力的方向!} 收藏,你的青睐是我努力的方向!

✏️ 评论,你的意见是我进步的财富! \textcolor{green}{评论,你的意见是我进步的财富!} 评论,你的意见是我进步的财富!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/512064.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2023年第三届长三角高校数学建模竞赛】A 题 快递包裹装箱优化问题 详细数学建模过程

1 题目 2022 年&#xff0c;中国一年的包裹已经超过 1000 亿件&#xff0c;占据了全球快递事务量的一半以上。近几年&#xff0c;中国每年新增包裹数量相当于美国整个国家一年的包裹数量&#xff0c; 十年前中国还是物流成本最昂贵的国家&#xff0c;当前中国已经建立起全世界…

阿里云服务器建站教程来了(十分钟网站上线)

使用阿里云服务器快速搭建网站教程&#xff0c;先为云服务器安装宝塔面板&#xff0c;然后在宝塔面板上新建站点&#xff0c;阿里云服务器网以搭建WordPress网站博客为例&#xff0c;来详细说下从阿里云服务器CPU内存配置选择、Web环境、域名解析到网站上线全流程&#xff1a; …

布朗运动模拟

布朗运动模拟 文章目录 布朗运动模拟[toc]1 布朗运动定义2 布朗运动模拟3 布朗桥4 带漂移布朗运动5 几何布朗运动 1 布朗运动定义 给定随机过程 { W ( t ) , t ≥ 0 } \{W(t),t \ge 0 \} {W(t),t≥0}&#xff0c;满足以下条件&#xff0c;则称 W ( t ) W(t) W(t)为标准布朗运动…

1 ElasticSearch介绍

全文检索 Elastisearch 研究 目标 了解Elasticsearch的应用场景掌握索引维护的方法掌握基本的搜索Api的使用方法 约束 阅读本教程之前需要掌握Lucene的索引方法、搜索方法 。 1 ElasticSearch介绍 1.1 介绍 官方网址&#xff1a;https://www.elastic.co/cn/products/elas…

【OpenCV】学习课-图像获取与显示(1)!

OpenCV是一个基于Apache2.0许可&#xff08;开源&#xff09;发行的跨平台计算机视觉和机器学习软件库&#xff0c;可以运行在Linux、Windows、Android和Mac OS操作系统上。 [1] 它轻量级而且高效——由一系列 C 函数和少量 C 类构成&#xff0c;同时提供了Python、Ruby、MATLA…

JAVA-多态

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 目录 文章目录 1.多态的概念 2.多态的实现条件 3.重写 总结 1.多态的概念 什么是多态? 通俗来说&#xff0c;就是多种形态&#xff0c;具体点就是去完成某个…

【仪器控制】LAN Web 浏览器界面!

仪器支持不同的接口和协议进行远程控制。下表给出了概述 LAN web 浏览器界面 &#xff1a; LAN Web 浏览器界面允许轻松配置 LAN 和远程控制 R&S FSW&#xff0c;无需额外的安装要求。 仪器的 LAN 网络浏览器界面可与所有 W3C 兼容的浏览器正常工作。 通过 R&S FSW 的 …

React组件实例state-事件绑定(三)

类组件中的属性 我们看一个简单的类组件实例 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><title>hello_react</title></head><body><!-- 准备好一个“容器” --><div id&q…

Tech Talk | 还原照片不同亮度范围细节——RAW HDR技术

拍照时&#xff0c;你是否遇到过这些情况呢&#xff1f; 拍摄的成片暗区过暗&#xff0c;高亮区域过曝 逆光拍摄中&#xff0c;会出现“鬼影” 暗部噪声偏大导致图像出现瑕疵 ....... 照片的高光和暗区细节得总是不到完美呈现&#xff0c;这是所有拍摄设备都会出现的问题。那么…

淘宝拍立淘多码识别方案总结

本文通过拆解原始问题、发散思路优化等方式&#xff0c;记录了扫一扫从单码到多码识别的技术框架改造及多码识别率优化方案。其中涉及解码SDK的能力、码处理技术链路、码转换算法、降低漏检率策略等设计与实现。 背景与挑战 多码即在同一个界面中同时存在多个条码或二维码&…

国产自研数据库是更新换代首选

伴随着数字经济的高速发展&#xff0c;越来越多的企业都意识到了数据是现代企业最具价值的资产。而与之相对应的是&#xff0c;数据库的重要性也随之水涨船高。 近年来&#xff0c;在席卷全球的云原生大潮中&#xff0c;数据库产业迎来了极为重要的转型升级。特别是在自主创新的…

JVM系列-第7章-对象的实例化内存布局与访问定位

对象的实例化内存布局与访问定位 对象的实例化 大厂面试题 美团&#xff1a; 对象在JVM中是怎么存储的&#xff1f;对象头信息里面有哪些东西&#xff1f; 蚂蚁金服&#xff1a; 二面&#xff1a;java对象头里有什么 对象创建的方式 new&#xff1a;最常见的方式、单例…

真正的智能不仅仅是一个技术问题

智能并不是单一的技术问题&#xff0c;而是一个包括技术、人类智慧、社会制度和文化等多个方面的综合体&#xff0c;常常涉及技术变革、系统演变、运行方式创新、组织适应。智能是指人类的思考、判断、决策和创造等高级认知能力&#xff0c;可以通过技术手段来实现增强和扩展。…

【基础篇】nginx代理、动静分离、路径重写、高可用以及https配置

目录 正向代理 反向代理 负载均衡 负载均衡的策略 动静分离 alias与root UrlRewrite(资源路径重写) 防盗链配置 高可用配置 Https证书配置 安装BBS&#xff08;开源界的鼻祖&#xff09; 正向代理 用户知道nginx服务器的存在&#xff0c;与nginx服务器是一伙的。…

第五十五章 Unity 视频播放

使用视频播放器组件(Video Player)可将视频文件附加到游戏对象&#xff0c;然后在运行时在游戏对象的纹理上播放。首先&#xff0c;我们需要了解视频文件。视频文件的典型文件扩展名包括 .mp4、.mov、.webm 和 .wmv。可将许多不同的视频文件格式导入 Unity 中。Unity 将导入的视…

【Linux】编译器gcc/g++的使用

&#x1f3d6;️作者&#xff1a;malloc不出对象 ⛺专栏&#xff1a;Linux的学习之路 &#x1f466;个人简介&#xff1a;一名双非本科院校大二在读的科班编程菜鸟&#xff0c;努力编程只为赶上各位大佬的步伐&#x1f648;&#x1f648; 目录 前言一、gcc/g的介绍二、程序的翻…

基于Vue CLI搭建vue3项目

前言 使用vue官方的脚手架进行搭建Vue CLI 注意&#xff1a;create-vue是基于Vite搭建项目&#xff0c;今天我们还是基于webpack搭建使用vue create 项目名称这个命令 一、步骤 1、 使用默认配置项还是自定义配置 这里我选择自定义 2、 选择需要配置的选项 根据个人进行…

ChatGPT不会很快接管人类工作,AI也不会免费打工

ChatGPT 等大模型的相继发布&#xff0c;让很多人倍感压力&#xff0c;害怕 AI 会很快接管他们的工作。对此&#xff0c;OpenAI 也曾发表过一项研究&#xff0c;表明 ChatGPT 的影响涵盖所有收入阶层&#xff0c;且高收入工作可能面临更大的风险。事实到底如何呢&#xff1f; …

IT知识百科:什么是下一代防火墙和IPS?

引言 随着网络攻击的日益增多&#xff0c;防火墙和入侵防御系统&#xff08;Intrusion Prevention System, IPS&#xff09;已成为企业网络安全的必备设备。然而&#xff0c;传统的防火墙和IPS已经无法满足复杂多变的网络安全威胁&#xff0c;因此&#xff0c;下一代防火墙和I…

Java集合(底层设计与实现)

Java集合&#xff08;底层设计与实现&#xff09; 集合体系 List接口 基本介绍 元素有序&#xff08;即添加顺序和取出顺序一致&#xff09;、且可重复支持索引有下标&#xff0c;下标对应元素在容器中的位置 ArrayList 基本介绍&#xff1a;底层由数组实现&#xff1b;在…