2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > 原生JS 实现小游戏 打砖块

原生JS 实现小游戏 打砖块

时间:2024-07-25 21:53:53

相关推荐

原生JS 实现小游戏 打砖块

文章目录

1. 概述2. 游戏场景3. 实现砖块布局4.小球和挡板5.挡板运动6.挡板边界7.小球运动8.小球边界9.碰撞检测 (重点复杂点)10.音效处理

1. 概述

这是一个游戏,这不仅仅是一个游戏,我们的目标不是为了开发游戏,而是为了掌握常见函数和基本开发思路 (多练多练)

实现代码之前 先有思路 实现具体的功能 和进行不断的调式

以下是本人在培训时期老师写的代码 思路图为老师所画

2. 游戏场景

场景为css 和 html 组成

直接上代码

代码如下

<style>* {margin: 0;padding: 0;box-sizing: border-box;}html,body {background-color: aliceblue;}h2 {text-align: center;margin: 20px auto;}#box {background-color: white;width: 1000px;height: 500px;box-shadow: 0 0 3px darkcyan;margin: 20px auto;position: relative;}P {display: block;width: 100px;/* 砖块样式 */height: 40px;position: absolute;box-shadow: -2px -3px -6px black;}#baffle {position: absolute;width: 200px;height: 16px;border-radius: 8px;background-color: brown;left: 454px;top: 484px;}#ball {z-index: 99;width: 30px;height: 30px;background: rgb(117, 85, 74);box-shadow: #888 2px 2px 3px;position: absolute;top: 454px;left: 534px;border-radius: 50%;}</style></head><body><h2>打砖块</h2><div id="box"><!-- 小球 --><div id="ball"></div><!-- 挡板 --><div id="baffle"></div></div>

网页效果如下:

3. 实现砖块布局

技术准备:

代码实现:

// 让js代码在网页加载后执行window.onload = function () {//获取场景对象var _box = document.querySelector("#box");// ----------------------- 砖块处理部分//定义行数var rows = 3;//计算一行放多少砖块var cols = Math.floor(_box.offsetWidth / 100);//声明一个保存砖数的数组var brickArrs = []//循环 创建砖块for (var i = 0; i < rows; i++) {//循环创建多行for (var j = 0; j < cols; j++) {//循环创建一行中的多个砖块//创建砖块 p 标签var _p = document.createElement("p");_p.style.backgroundColor ="#" + Math.random().toString(16).substr(2, 6);//p 标签定位;位置_p.style.left = j * 100 + "px";_p.style.top = i * 40 + "px";//将砖块添加到场景中_box.appendChild(_p);//将砖块保存到数组中brickArrs.push(_p)}}

网页实现效果:

4.小球和挡板

代码详情在第一段里

5.挡板运动

技术实现:

让挡板运动起来 用左右方向键控制

代码实现:

//-----------挡板运动var _baffle = document.querySelector("#baffle")var _speed = 20document.onkeydown = function(e) {//获取事件对象var e = e || window.event//判断用户按下的按键var keyCode = e.keyCode//用户按下,控制挡板运动switch(keyCode) {case 37:console.log("向左移动")_baffle.style.left = _baffle.offsetLeft - _speed + "px"breakcase 39:console.log("向右移动")_baffle.style.left = _baffle.offsetLeft + _speed + "px"break}

6.挡板边界

左右不超出场景边缘

代码实现:

//挡板边界判断,挡板不能超出边界if(_baffle.offsetLeft < 0) {_baffle.style.left = 0}else if(_baffle.offsetLeft >= (_box.offsetWidth - _baffle.offsetWidth)){_baffle.style.left = (_box.offsetWidth - _baffle.offsetWidth) + "px"}}

网页实现效果:

7.小球运动

需求:小球在游戏区域可以运动起来,碰撞墙壁的时候需要反弹

分析图如下图

代码实现:

//----------小球运动var _ball = document.querySelector("#ball")var speedX = 3 //垂直速度var speedY = -5 //水平速度// ballInterval 全部间隔//setInterval 设置间隔var ballInterval = setInterval(function () {//小球运动起来_ball.style.left = _ball.offsetLeft + speedX + "px"_ball.style.top = _ball.offsetTop + speedY + "px"

8.小球边界

需求:小球不能碰撞下边界,一旦碰撞到下边界游戏结束;下边界上必须让小球碰撞到挡板进行反弹

分析图解:

代码实现:

//边界判断if(_ball.offsetLeft < 0 ) {//左边界speedX = 3}else if(_ball.offsetLeft > (_box.offsetWidth - _ball.offsetWidth)) {speedX = -3}if(_ball.offsetTop < 0 ) {//上边界speedY = 5} else if(( _ball.offsetLeft >= (_baffle.offsetLeft - _ball.offsetWidth/2))&&(_ball.offsetLeft <= (_baffle.offsetLeft + _baffle.offsetWidth - _ball.offsetWidth/2))&&(_ball.offsetTop >= (_baffle.offsetTop -_ball.offsetHeight))) {// 碰到挡板speedY = -5}else if(_ball.offsetTop > (_box.offsetHeight - _ball.offsetHeight)){clearInterval(ballInterval)// clearInterval 清除间隔alert("你漏球了,结束") //弹窗 阻止代码执行 计时器仍然执行 location.reload()//重新加载当前位置 刷新网页}

9.碰撞检测 (重点复杂点)

小球和砖块之间的碰撞检测,小球碰到砖块,砖块消失/小球反弹,

具体操作如图

如果碰撞过程中,按照每一个碰撞面去检测,很容易存在 BUG

代码中通过上下碰撞面、左右碰撞面进行同时检测,检测小球坐标一旦进入砖块

内部就算碰撞成功,让砖块消失/代码中通过 DOM removeChild() 函数移除标签,小球的运动反弹 左右碰撞面-水平速度取反、上下碰撞面-垂直速度取反

代码实现:

//判断小球是否和砖块发生碰撞for(var x = 0; x < brickArrs.length; x++) {//获取一个砖块var brick = brickArrs[x]//碰撞检测collide(brick, _ball)}}, 20)//--------------------- 碰撞检测:小球、砖块// brick :砖块// ball:小球function collide(brick, ball) {console.log("--------------------------------------")// console.log(brick.offsetLeft, brick.offsetTop, brick.offsetWidth, brick.offsetHeight, "砖块")// console.log(ball.offsetLeft, ball.offsetTop, ball.offsetWidth, ball.offsetHeight, "小球")console.log("--------------------------------------")// 底部碰撞、左侧碰撞、顶部碰撞、右侧碰撞if(//offset 抵消(ball.offsetLeft > (brick.offsetLeft - ball.offsetWidth/2))&&(ball.offsetLeft < (brick.offsetLeft + brick.offsetWidth - ball.offsetWidth/2))&&(ball.offsetTop < (brick.offsetTop + brick.offsetHeight))&&(ball.offsetTop > (brick.offsetTop - brick.offsetHeight))) {// 底部碰撞 或者 顶部碰撞// 碰撞发生,砖块:消失,小球:反弹console.log("碰撞发生,砖块消失,小球反弹.....")speedY = -speedY // 垂直速度取反_box.removeChild(brick)} else if(//offset 抵消(ball.offsetTop > (brick.offsetTop - ball.offsetHeight/2))&&(ball.offsetTop < (brick.offsetTop + brick.offsetHeight - ball.offsetHeight/2))&&(ball.offsetLeft > (brick.offsetLeft - ball.offsetWidth))&&(ball.offsetLeft < (brick.offsetLeft + brick.offsetWidth))) {// 左侧碰撞 或者 右侧碰撞speedX = -speedX_box.removeChild(brick)boom()}}

10.音效处理

当小球和砖块发生碰撞时

创建 audio 标签

设置 src 属性,添加音效文件

不设置 autoplay=true 自动播放

碰撞时调用 audio.play() 播放音效即可

代码如下:

// 音效处理 var _audio = document.createElement("audio") _audio.src = "./img/y993.wav"// _audio.autoplay = true document.appendChild(_audio) function boom() {_audio.play() }

整体代码如下:

<!DOCTYPE html><html lang="zh"><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>* {margin: 0;padding: 0;box-sizing: border-box;}html,body {background-color: aliceblue;}h2 {text-align: center;margin: 20px auto;}#box {background-color: white;width: 1000px;height: 500px;box-shadow: 0 0 3px darkcyan;margin: 20px auto;position: relative;}P {display: block;width: 100px;/* 砖块样式 */height: 40px;position: absolute;box-shadow: -2px -3px -6px black;}#baffle {position: absolute;width: 200px;height: 16px;border-radius: 8px;background-color: brown;left: 454px;top: 484px;}#ball {z-index: 99;width: 30px;height: 30px;background: rgb(117, 85, 74);box-shadow: #888 2px 2px 3px;position: absolute;top: 454px;left: 534px;border-radius: 50%;}</style></head><body><h2>打砖块</h2><div id="box"><!-- 小球 --><div id="ball"></div><!-- 挡板 --><div id="baffle"></div></div><script>// 让js代码在网页加载后执行window.onload = function () {//获取场景对象var _box = document.querySelector("#box");// ----------------------- 砖块处理部分//定义行数var rows = 3;//计算一行放多少砖块var cols = Math.floor(_box.offsetWidth / 100);//声明一个保存砖数的数组var brickArrs = []//循环 创建砖块for (var i = 0; i < rows; i++) {//循环创建多行for (var j = 0; j < cols; j++) {//循环创建一行中的多个砖块//创建砖块 p 标签var _p = document.createElement("p");_p.style.backgroundColor ="#" + Math.random().toString(16).substr(2, 6);//p 标签定位;位置_p.style.left = j * 100 + "px";_p.style.top = i * 40 + "px";//将砖块添加到场景中_box.appendChild(_p);//将砖块保存到数组中brickArrs.push(_p)}}//-----------挡板运动var _baffle = document.querySelector("#baffle")var _speed = 20document.onkeydown = function(e) {//获取事件对象var e = e || window.event//判断用户按下的按键var keyCode = e.keyCode//用户按下,控制挡板运动switch(keyCode) {case 37:console.log("向左移动")_baffle.style.left = _baffle.offsetLeft - _speed + "px"breakcase 39:console.log("向右移动")_baffle.style.left = _baffle.offsetLeft + _speed + "px"break}//挡板边界判断,挡板不能超出边界if(_baffle.offsetLeft < 0) {_baffle.style.left = 0}else if(_baffle.offsetLeft >= (_box.offsetWidth - _baffle.offsetWidth)){_baffle.style.left = (_box.offsetWidth - _baffle.offsetWidth) + "px"}}//----------小球运动var _ball = document.querySelector("#ball")var speedX = 3 //垂直速度var speedY = -5 //水平速度// ballInterval 全部间隔//setInterval 设置间隔var ballInterval = setInterval(function () {//小球运动起来_ball.style.left = _ball.offsetLeft + speedX + "px"_ball.style.top = _ball.offsetTop + speedY + "px"//边界判断if(_ball.offsetLeft < 0 ) {//左边界speedX = 3}else if(_ball.offsetLeft > (_box.offsetWidth - _ball.offsetWidth)) {speedX = -3}if(_ball.offsetTop < 0 ) {//上边界speedY = 5} else if(( _ball.offsetLeft >= (_baffle.offsetLeft - _ball.offsetWidth/2))&&(_ball.offsetLeft <= (_baffle.offsetLeft + _baffle.offsetWidth - _ball.offsetWidth/2))&&(_ball.offsetTop >= (_baffle.offsetTop -_ball.offsetHeight))) {// 碰到挡板speedY = -5}else if(_ball.offsetTop > (_box.offsetHeight - _ball.offsetHeight)){clearInterval(ballInterval)// clearInterval 清除间隔alert("你漏球了,结束") //弹窗 阻止代码执行 计时器仍然执行 location.reload()//重新加载当前位置 刷新网页}//判断小球是否和砖块发生碰撞for(var x = 0; x < brickArrs.length; x++) {//获取一个砖块var brick = brickArrs[x]//碰撞检测collide(brick, _ball)}}, 20)//--------------------- 碰撞检测:小球、砖块// brick :砖块// ball:小球function collide(brick, ball) {console.log("--------------------------------------")// console.log(brick.offsetLeft, brick.offsetTop, brick.offsetWidth, brick.offsetHeight, "砖块")// console.log(ball.offsetLeft, ball.offsetTop, ball.offsetWidth, ball.offsetHeight, "小球")console.log("--------------------------------------")// 底部碰撞、左侧碰撞、顶部碰撞、右侧碰撞if(//offset 抵消(ball.offsetLeft > (brick.offsetLeft - ball.offsetWidth/2))&&(ball.offsetLeft < (brick.offsetLeft + brick.offsetWidth - ball.offsetWidth/2))&&(ball.offsetTop < (brick.offsetTop + brick.offsetHeight))&&(ball.offsetTop > (brick.offsetTop - brick.offsetHeight))) {// 底部碰撞 或者 顶部碰撞// 碰撞发生,砖块:消失,小球:反弹console.log("碰撞发生,砖块消失,小球反弹.....")speedY = -speedY // 垂直速度取反_box.removeChild(brick)} else if(//offset 抵消(ball.offsetTop > (brick.offsetTop - ball.offsetHeight/2))&&(ball.offsetTop < (brick.offsetTop + brick.offsetHeight - ball.offsetHeight/2))&&(ball.offsetLeft > (brick.offsetLeft - ball.offsetWidth))&&(ball.offsetLeft < (brick.offsetLeft + brick.offsetWidth))) {// 左侧碰撞 或者 右侧碰撞speedX = -speedX_box.removeChild(brick)boom()}}// 音效处理 var _audio = document.createElement("audio") _audio.src = "./img/y993.wav"// _audio.autoplay = true document.appendChild(_audio) function boom() {_audio.play() }};</script></body></html>

网页效果展现如下图:

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。