The sand accumulates to form a pagoda

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

✨ 写在前面

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


✨ 功能介绍

白色方块为我们游戏中的主角,游戏开始后回随机坠落红色方块,我们可以通过键盘的左右键来控制白色方块的移动,来躲避白色方块,被撞击到游戏结束汇算分数,每次成功躲避都加一分,60秒自动结束汇算得分;你可以通过修改游戏的参数来控制难度等级!


✨ 页面搭建

创建文件

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

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

DOM结构搭建

这段代码定义了一个 HTML 游戏页面,包含了三个 <div> 元素。<div id="game"> 表示游戏主界面,游戏中的元素都将显示在这个 <div> 元素中。<div id="player"></div> 表示玩家的角色,即小人,将显示在游戏主界面中央的底部。<div id="score">分数: 0</div> 表示游戏得分,将显示在游戏主界面的顶部。<div id="message"></div> 表示游戏结束时弹出的提示框,将显示在游戏主界面中央。

<div id="game"><div id="player"></div><div id="score">分数: 0</div><div id="message"></div>
</div>


✨ 样式设置

我们看到了上面的的DOM已经搭建好了,但是很显然样式比较随意了,我们简单的来配置一下样式吧,其实我们本专栏也是想带领大家掌握一些逻辑所以样式方面我们就一切从简;其中,body 元素的样式设置了外边距、内边距和隐藏滚动条。#game 元素是整个游戏的容器,设置了宽度、高度、背景颜色和相对定位。#player 元素是玩家,设置了宽度、高度、背景颜色、绝对定位、底部对齐、左侧距离容器中心点的距离,并通过 transform 属性将其水平居中。.obstacle 类表示障碍物,设置了宽度、高度、背景颜色、绝对定位、顶部距离为负数(使其从游戏容器顶部开始落下)、左侧距离容器中心点的距离,并通过 transform 属性将其水平居中。#score 元素是得分标签,设置了绝对定位、顶部距离和左侧距离,并设置了颜色和字体大小。#message 元素是游戏结束提示信息,设置了绝对定位、上、左偏移和颜色、字体大小,并通过 display 属性将其隐藏。

body {margin: 0;padding: 0;overflow: hidden;
}#game {width: 100vw;height: 100vh;background-color: #222;position: relative;overflow: hidden;
}#player {width: 50px;height: 50px;background-color: white;position: absolute;bottom: 0;left: 50%;transform: translateX(-50%);
}.obstacle {width: 50px;height: 50px;background-color: red;position: absolute;top: -50px;left: 50%;transform: translateX(-50%);
}#score {position: absolute;top: 10px;left: 10px;color: white;font-size: 24px;
}#message {position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);color: white;font-size: 48px;display: none;
}


✨ 逻辑部分

首先,通过 document.getElementById 方法获取了 game、player、score 和 message 等 DOM 元素对象。这些元素分别对应游戏区域、玩家方块、得分标签和游戏结束提示信息。在游戏参数部分,定义了一些游戏的参数,包括得分、游戏是否结束、障碍物下落间隔、障碍物下落速度、障碍物宽度、障碍物高度和玩家移动速度等。

// 获取DOM元素
const game = document.getElementById('game');
const player = document.getElementById('player');
const score = document.getElementById('score');
const message = document.getElementById('message');// 初始化游戏参数
let scoreValue = 0; // 得分
let isGameOver = false; // 游戏是否结束
let obstacleInterval; // 障碍物下落间隔
let gameTimer; // 游戏计时器
const obstacleSpeed = 5; // 障碍物下落速度
const obstacleWidth = 50; // 障碍物宽度
const obstacleHeight = 50; // 障碍物高度
const playerSpeed = 10; // 玩家移动速度

接着,通过 document.addEventListener 监听键盘事件,控制玩家方块左右移动。在 dropObstacle 函数中,创建障碍物并添加到游戏区域中,并设置障碍物下落动画,同时进行碰撞检测,如果玩家方块与障碍物相撞,游戏结束。

// 监听键盘事件,控制玩家左右移动
document.addEventListener('keydown', event => {if (event.key === 'ArrowLeft') {player.style.left = Math.max(0, player.offsetLeft - playerSpeed) + 'px';} else if (event.key === 'ArrowRight') {player.style.left = Math.min(game.clientWidth - player.offsetWidth, player.offsetLeft + playerSpeed) + 'px';}
});// 检测碰撞
function detectCollision() {// 玩家和每个障碍物都进行碰撞检测const obstacles = document.querySelectorAll('.obstacle');obstacles.forEach(obstacle => {if (isCollided(player, obstacle)) {endGame();}});
}// 碰撞检测函数
function isCollided(element1, element2) {const rect1 = element1.getBoundingClientRect();const rect2 = element2.getBoundingClientRect();return !(rect1.bottom < rect2.top || rect1.top > rect2.bottom || rect1.right < rect2.left || rect1.left > rect2.right);
}// 障碍物下落
function dropObstacle() {// 创建障碍物const obstacle = document.createElement('div');obstacle.classList.add('obstacle');obstacle.style.width = obstacleWidth + 'px';obstacle.style.height = obstacleHeight + 'px';obstacle.style.top = -obstacleHeight + 'px';obstacle.style.left = Math.floor(Math.random() * (game.clientWidth - obstacleWidth)) + 'px';game.appendChild(obstacle);// 障碍物下落动画const obstacleDrop = setInterval(() => {if (!isGameOver) {obstacle.style.top = obstacle.offsetTop + obstacleSpeed + 'px';if (obstacle.offsetTop >= game.clientHeight) {game.removeChild(obstacle);clearInterval(obstacleDrop);scoreValue++;score.innerHTML = 'Score: ' + scoreValue;}detectCollision();}}, 10);
}// 开始游戏
function startGame() {scoreValue = 0;isGameOver = false;obstacleInterval = setInterval(dropObstacle, 1000);gameTimer = setTimeout(() => {endGame();}, 60000);
}// 结束游戏
function endGame() {isGameOver = true;clearInterval(obstacleInterval);clearTimeout(gameTimer);message.innerHTML = 'Game Over! Your score is ' + scoreValue;message.style.display = 'block';
}// 监听重新开始按钮
message.addEventListener('click', () => {message.style.display'none';while (game.firstChild) {game.removeChild(game.firstChild);}startGame();
});// 开始游戏
startGame();

通过 setInterval 定时器循环调用 dropObstacle 函数,实现障碍物不断下落。同时,通过 setTimeout 定时器设置游戏时间,如果游戏时间到了,则游戏结束。最后,在 endGame 函数中,设置游戏结束的一些行为,包括清除障碍物下落定时器、游戏时间定时器,显示游戏结束信息等。同时,在 message 元素上添加点击事件,用于重新开始游戏。当然这里大家可以通过自己配置参数来增加游戏的难度!你也可以将元素替换成图片让游戏更加生动!

完整代码

<!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>小人逃脱</title><style>body {margin: 0;padding: 0;overflow: hidden;}#game {width: 100vw;height: 100vh;background-color: #222;position: relative;overflow: hidden;}#player {width: 50px;height: 50px;background-color: white;position: absolute;bottom: 0;left: 50%;transform: translateX(-50%);}.obstacle {width: 50px;height: 50px;background-color: red;position: absolute;top: -50px;left: 50%;transform: translateX(-50%);}#score {position: absolute;top: 10px;left: 10px;color: white;font-size: 24px;}#message {position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);color: white;font-size: 48px;display: none;}</style>
</head><body><div id="game"><div id="player"></div><div id="score">分数: 0</div><div id="message"></div></div></body>
<script>// 获取DOM元素const game = document.getElementById('game');const player = document.getElementById('player');const score = document.getElementById('score');const message = document.getElementById('message');// 初始化游戏参数let scoreValue = 0; // 得分let isGameOver = false; // 游戏是否结束let obstacleInterval; // 障碍物下落间隔let gameTimer; // 游戏计时器const obstacleSpeed = 5; // 障碍物下落速度const obstacleWidth = 50; // 障碍物宽度const obstacleHeight = 50; // 障碍物高度const playerSpeed = 10; // 玩家移动速度// 监听键盘事件,控制玩家左右移动document.addEventListener('keydown', event => {if (event.key === 'ArrowLeft') {player.style.left = Math.max(0, player.offsetLeft - playerSpeed) + 'px';} else if (event.key === 'ArrowRight') {player.style.left = Math.min(game.clientWidth - player.offsetWidth, player.offsetLeft + playerSpeed) + 'px';}});// 检测碰撞function detectCollision() {// 玩家和每个障碍物都进行碰撞检测const obstacles = document.querySelectorAll('.obstacle');obstacles.forEach(obstacle => {if (isCollided(player, obstacle)) {endGame();}});}// 碰撞检测函数function isCollided(element1, element2) {const rect1 = element1.getBoundingClientRect();const rect2 = element2.getBoundingClientRect();return !(rect1.bottom < rect2.top || rect1.top > rect2.bottom || rect1.right < rect2.left || rect1.left > rect2.right);}// 障碍物下落function dropObstacle() {// 创建障碍物const obstacle = document.createElement('div');obstacle.classList.add('obstacle');obstacle.style.width = obstacleWidth + 'px';obstacle.style.height = obstacleHeight + 'px';obstacle.style.top = -obstacleHeight + 'px';obstacle.style.left = Math.floor(Math.random() * (game.clientWidth - obstacleWidth)) + 'px';game.appendChild(obstacle);// 障碍物下落动画const obstacleDrop = setInterval(() => {if (!isGameOver) {obstacle.style.top = obstacle.offsetTop + obstacleSpeed + 'px';if (obstacle.offsetTop >= game.clientHeight) {game.removeChild(obstacle);clearInterval(obstacleDrop);scoreValue++;score.innerHTML = 'Score: ' + scoreValue;}detectCollision();}}, 10);}// 开始游戏function startGame() {scoreValue = 0;isGameOver = false;obstacleInterval = setInterval(dropObstacle, 1000);gameTimer = setTimeout(() => {endGame();}, 60000);}// 结束游戏function endGame() {isGameOver = true;clearInterval(obstacleInterval);clearTimeout(gameTimer);message.innerHTML = 'Game Over! Your score is ' + scoreValue;message.style.display = 'block';}// 监听重新开始按钮message.addEventListener('click', () => {message.style.display'none';while (game.firstChild) {game.removeChild(game.firstChild);}startGame();});// 开始游戏startGame();
</script></html>

本期推荐

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

前端搭建小人逃脱游戏(内附源码)相关推荐

  1. 前端搭建名言生成器(内附源码)

    The sand accumulates to form a pagoda ✨ 写在前面 ✨ JS是什么? ✨ 名言生成器 ✨ 页面搭建 ✨ 功能实现 ✨ 写在前面 在上周我们通过HTML.CSS实现 ...

  2. 【C语言】第一个C语言项目——“猜数字”游戏(内附源码)

    君兮_的个人主页 勤时当勉励 岁月不待人 C/C++ 游戏开发 Hello米娜桑,这里是君兮_,今天又抽空为大家更新我们的主线0基础C语言啦!鉴于最近讲解了非常多的选择语句与循环语句,咱们今天就来讲讲 ...

  3. web python 自动化是什么_Selenium 凭什么成为 Web 自动化测试的首选?(内附源码)...

    原标题:Selenium 凭什么成为 Web 自动化测试的首选?(内附源码) 自动化 · 工具 1.QTP QTP是一个商业化的功能测试工具,收费,支持web,桌面自动化测试. 2. Selenium ...

  4. Selenium 凭什么成为 Web 自动化测试的首选?(内附源码)

    <自动化>工具 1.QTP QTP是一个商业化的功能测试工具,收费,支持web,桌面自动化测试. 2. Selenium(文章重点讲) Selenium是一个开源的web自动化测试工具,免 ...

  5. 小鸟飞行游戏【附源码】

    小鸟飞行游戏,java精品项目,毕业设计,计算机系,计算机毕业设计,程序设计,设计与实现,源码, 小鸟飞行游戏[附源码] 我的网站已经上线了 http://javapub.net.cn/ 博主介绍:

  6. CTP接口开发案例(内附源码)

    CTP接口开发(内附源码) 提示:在看本博客之前建议先阅读上期所官方的开发文档(SimNow官网中去下载CTP接口文件),然后在SimNow官网注册模拟账号. 提示:股票CTP接口和期货CTP接口类似 ...

  7. C语言小游戏大全,C语言贪吃蛇小游戏(附源码)

    一.C语言小游戏大全,C语言贪吃蛇小游戏(附源码) 贪吃蛇小游戏源码和更多C语言课设项目小游戏源码免 费 下 载 链 接 如下: c语言项目课设小游戏源码资料压缩包.zip-C文档类资源-CSDN下载 ...

  8. 吃豆人游戏【附源码】

    吃豆游戏[附源码] 吃豆人游戏[附源码] 我的网站已经上线了 http://javapub.net.cn/ 博主介绍:

  9. wallpaper代码_五行Python代码自动换你的电脑桌面壁纸(内附源码和exe)

    很多行友问行哥,Python能不能自动更换电脑壁纸呀,今天它来了 只需要一行代码,指定图片地址即可更换电脑桌面.加上壁纸文件夹路径,让你随机更换电脑桌面,带来不期而遇的新鲜.使用爬虫技术,自动下载壁纸 ...

最新文章

  1. 入住两年的CSDN,在今天2020年8月27日,成为CSDN博客专家
  2. plotplay恢复默认设置_PotPlayer如何调整常用设置?PotPlayer调整常用设置的方法步骤...
  3. (*长期更新)软考网络工程师学习笔记——Section 8 传输层
  4. java源程序可以有几个主类_Java源程序是由类定义组成的,每个程序可以定义若干个类,但只有一个类是主类。_学小易找答案...
  5. 看徐坤的话剧《性情男女》
  6. hackgame汇总
  7. discard python_Netty入门教程(一) 实现DISCARD服务
  8. 电脑上玩和平精英_《和平精英》怎么投屏到电脑上?手把手教你电脑键鼠玩手游...
  9. ML.NET 1.3.1 发布,.NET 跨平台机器学习框架
  10. tensorflow2 unet加载自己的图像进行训练
  11. F28335的ePWM模块
  12. 8g内存和16g内存区别 mac_8G和16GB内存,体验差异大吗?实测新版M1处理器苹果MacBook...
  13. 文献检索--系统综述与meta分析
  14. 实战HTML:部分美团首页静态界面
  15. C语言外推法求搜索区间程序,一维搜索外推法程序设计实验报告.doc
  16. 【opencv】【python】libpng warning: iCCP: known incorrect sRGB profile 解决
  17. 一张图片,根据区域,跳转不同链接
  18. 2021-2027全球与中国便携式X射线荧光光谱仪市场现状及未来发展趋势
  19. Python--Flask在使用 SQLAlchemy出现'SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and '
  20. Elastic Job Lite调度中心和Cron表达式

热门文章

  1. reporting services报表部署错误:运行配置文件中指定的扩展时出现异常。 ---> 超过了最大请求长度。
  2. cuda 和 pytorch 安装
  3. 怎么把彩色的照片变黑白色?
  4. 原生JS --360度全景展示
  5. 有一个已排好序的数组,要求输入一个数后,按原来排序的规律将它插入数组中
  6. 南京大学计算机专业拂晓,南京大学2020年计算机学科录取推免生222人,全部来自211高校...
  7. html平板电脑打不开,平板电脑浏览器打不开网页
  8. python下对bin文件的处理
  9. Spatial-Spectral Transformer for Hyperspectral Image Classification
  10. 程序员在技术之外,还要掌握一个技能——自我营销能力