html5实现简单别踩白块小游戏 内容介绍 1.简介 别踩白块这个游戏相信很多人都在手机上玩过,今天我们就来做一个网页版的,先上一张游戏效果图:
属于简化版别踩白块,代码相对较为简单易学,主要涉及通过 javascript 操作元素节点的增删以及属性节点(class)的操作。
2.知识点
HTML/CSS
JavaScript
元素节点增删
属性节点操作
3.项目架构 1 2 3 4 puzzle |index.html |css/index.css |js/index.js
项目原理 在开始编程之前,让我们先来分析下整个游戏的流程:一定的速度下移,点击黑块,黑块消失,新的黑块出现在普通游戏玩家眼中,应该是游戏开始,黑块不断向下移动,若黑块触底则游戏结束;
而以开发者来说,应将每一个黑块和白块抽象成一个个的数据结构,黑块的消失和出现其实就是数据结构的创造和销毁 ,我们来看一张游戏的流程图,对于要编写的功能有一个大概的了解:
实现步骤 页面布局 可以用 div+css 布局来实现别踩白块的静态效果展示,直接上 HTML 代码,我来简要说下 HTML 思路,将主界面分解成一个 4x4 的大矩形格子,每一个方块代表其中一个小的矩形格,其中每一行的四个白块中有一个黑块,每一行中黑块位于哪一列是随机生成的,但是我们这里现在是静态页面就自己确定了,然后通过 css 控制样式。
创建 index.html 文件,并输入以下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 <!DOCTYPE html > <html > <head > <meta charset ="utf-8" /> <title > 别踩白块</title > <link rel ="stylesheet" href ="css/index.css" /> </head > <body > <div id ="main" > <div id ="con" > <div class ="row" > <div class ="cell" > </div > /*白块*/ <div class ="cell black" > </div > /*黑块*/ <div class ="cell" > </div > <div class ="cell" > </div > </div > <div class ="row" > <div class ="cell" > </div > <div class ="cell black" > </div > <div class ="cell" > </div > <div class ="cell" > </div > </div > <div class ="row" > <div class ="cell" > </div > <div class ="cell" > </div > <div class ="cell black" > </div > <div class ="cell" > </div > </div > <div class ="row" > <div class ="cell black" > </div > <div class ="cell" > </div > <div class ="cell" > </div > <div class ="cell" > </div > </div > </div > </div > </body > <script src ="js/index.js" > </script > </html >
添加样式 下面是 css 代码,这里有一个要注意的地方,我将 div#con
块级元素向上提了 100 px,这样在游戏的开始就出现了最底一行的空白,隐藏最上面那行,为什么要这样呢,继续往下看就知道了。设置黑白块的样式,为 js 部分动态插入黑白块做准备。
创建 css/index.css
文件,并输入以下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 #main { width : 408px ; height : 408px ; background : white; border : 2px solid gray; margin : 0 auto; overflow : hidden; } h2 { text-align : center; } #con { width : 100% ; height : 400px ; position : relative; top : -408px ; border-collapse : collapse; } .row { height : 100px ; width : 100% ; } .cell { height : 100px ; width : 100px ; float : left; border : rgb (54 , 74 , 129 ) 1px solid; } .black { background : black; } .btn { width : 100% ; text-align : center; } .start { margin : 20px auto; width : 150px ; height : 50px ; border-radius : 10px ; background : yellowgreen; line-height : 50px ; color : #fff ; }
如果以上部分你都能够理解并且对应着代码实现的话,那么我们看到的应该是一个空格子,我们设置 id 为 con 的 div 的 top 属性为 0 px: #con {top: 0px;}
,这样我们就可以看见:
是不是很像别踩白块的界面了呢,我们已经成功了一大步,然后就是通过 js 来实现动态的插入黑块或白块,以及操作。
游戏初始化 根据前面的 HTML 部分我们可以知道,每个 <div class="cell">
就代表一个白块,<div class="cell black">
就代表一个黑块,每点击一个黑块消失其实是删除了一个 <div class="row">
然后从上面添加一个新的 <div class="row">
所以我们首先要通过 js 来控制 <div class="row">
的创造和生成(记得删除在编写静态页面时候指定生成的 4 个 div.row
)。具体方法如下:
删除之前写的 4 个 div.row,将 index.html 文件改为以下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <!DOCTYPE html > <html > <head > <meta charset ="utf-8" /> <title > 别踩白块</title > <link rel ="stylesheet" href ="css/index.css" /> </head > <body > <h2 > score</h2 > <h2 id ="score" > 0</h2 > <div id ="main" > <div id ="con" > </div > </div > <div class ="btn" > <button class ="start" onclick ="start()" > 开始游戏 </button > </div > </body > <script src ="js/index.js" > </script > </html >
对游戏进行初始化,在 js/index.js
文件中写入以下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 function creatediv (className ) { var div = document .createElement('div' ); div.className = className; return div; } function createrow ( ) { var con = $('con' ); var row = creatediv('row' ); var arr = creatcell(); con.appendChild(row); for (var i = 0 ; i < 4 ; i++) { row.appendChild(creatediv(arr[i])); } if (con.firstChild == null ) { con.appendChild(row); } else { con.insertBefore(row, con.firstChild); } } function delrow ( ) { var con = $('con' ); if (con.childNodes.length == 6 ) { con.removeChild(con.lastChild); } } function creatcell ( ) { var temp = ['cell' , 'cell' , 'cell' , 'cell' ]; var i = Math .floor(Math .random() * 4 ); temp[i] = 'cell black' ; return temp; }
让黑块动起来 在可以通过 js 来创造和销毁 div
后,我们就要让黑块动起来,这个时候我们就用到了之前 css 提到的设定 <div id="con">
隐藏了一行的 <div id="row">
,我们通过 js 的 DOM 操作使其向下方移动,并设置定时器每 30 毫秒移动一次,这样就实现了黑块的平滑移动,在黑块移动的同时,我们要判断黑块是否已经触底,触底则游戏失败,停止调用 move()
,触底后调用函数 fail()
游戏失败,具体方法如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 function move ( ) { var con = $('con' ); var top = parseInt (window .getComputedStyle(con, null )['top' ]); if (speed + top > 0 ) { top = 0 ; } else { top += speed; } con.style.top = top + 'px' ; over(); if (top == 0 ) { createrow(); con.style.top = '-102px' ; delrow(); } } function speedup ( ) { speed += 2 ; if (speed == 20 ) { alert('你超神了' ); } } function over ( ) { var rows = con.childNodes; if (rows.length == 5 && rows[rows.length - 1 ].pass !== 1 ) { fail(); } for (let i = 0 ; i < rows.length; i++) { if (rows[i].pass1 == 1 ) { fail(); } } } function fail ( ) { clearInterval (clock); flag = false ; confirm('你的最终得分为 ' + parseInt ($('score' ).innerHTML)); var con = $('con' ); con.innerHTML = '' ; $('score' ).innerHTML = 0 ; con.style.top = '-408px' ; }
点击黑块事件 让黑块动起来之后呢,我们就来考虑怎么判断用户有没有点击到黑块呢,同时用户若点击到黑块,我们要让所在那一行消失,那么我们需要一个 judge
方法,具体如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 function judge (ev ) { if ( ev.target.className.indexOf('black' ) == -1 && ev.target.className.indexOf('cell' ) !== -1 ) { ev.target.parentNode.pass1 = 1 ; } if (ev.target.className.indexOf('black' ) !== -1 ) { ev.target.className = 'cell' ; ev.target.parentNode.pass = 1 ; score(); } }
其实程序写到这里,几个核心的功能点都已经实现了,是不是感觉很简单呢。剩下来的就是将这些方法组合起来,组成完整的逻辑关系,在我给出的源码里添加有一个记分器记录用户分数的功能,同时设置加速方法,使黑块的移动越来越快等等。有兴趣的的同学可以尝试着添加事件按钮,使这个游戏更接近 APP 版本。
js 完整代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 function $ (id ) { return document .getElementById(id); } function creatediv (className ) { var div = document .createElement('div' ); div.className = className; return div; } var clock = null ;var state = 0 ;var speed = 6 ;var flag = false ;function start ( ) { if (!flag) { init(); } else { alert('游戏已经开始,无须再次点击!' ); } } function init ( ) { flag = true ; for (var i = 0 ; i < 4 ; i++) { createrow(); } $('main' ).onclick = function (ev ) { ev = ev || event; judge(ev); }; clock = window .setInterval('move()' , 30 ); } function judge (ev ) { if ( ev.target.className.indexOf('black' ) == -1 && ev.target.className.indexOf('cell' ) !== -1 ) { ev.target.parentNode.pass1 = 1 ; } if (ev.target.className.indexOf('black' ) !== -1 ) { ev.target.className = 'cell' ; ev.target.parentNode.pass = 1 ; score(); } } function over ( ) { var rows = con.childNodes; if (rows.length == 5 && rows[rows.length - 1 ].pass !== 1 ) { fail(); } for (let i = 0 ; i < rows.length; i++) { if (rows[i].pass1 == 1 ) { fail(); } } } function fail ( ) { clearInterval (clock); flag = false ; confirm('你的最终得分为 ' + parseInt ($('score' ).innerHTML)); var con = $('con' ); con.innerHTML = '' ; $('score' ).innerHTML = 0 ; con.style.top = '-408px' ; } function createrow ( ) { var con = $('con' ); var row = creatediv('row' ); var arr = creatcell(); con.appendChild(row); for (var i = 0 ; i < 4 ; i++) { row.appendChild(creatediv(arr[i])); } if (con.firstChild == null ) { con.appendChild(row); } else { con.insertBefore(row, con.firstChild); } } function creatcell ( ) { var temp = ['cell' , 'cell' , 'cell' , 'cell' ]; var i = Math .floor(Math .random() * 4 ); temp[i] = 'cell black' ; return temp; } function move ( ) { var con = $('con' ); var top = parseInt (window .getComputedStyle(con, null )['top' ]); if (speed + top > 0 ) { top = 0 ; } else { top += speed; } con.style.top = top + 'px' ; over(); if (top == 0 ) { createrow(); con.style.top = '-102px' ; delrow(); } } function speedup ( ) { speed += 2 ; if (speed == 20 ) { alert('你超神了' ); } } function delrow ( ) { var con = $('con' ); if (con.childNodes.length == 6 ) { con.removeChild(con.lastChild); } } function score ( ) { var newscore = parseInt ($('score' ).innerHTML) + 1 ; $('score' ).innerHTML = newscore; if (newscore % 10 == 0 ) { speedup(); } }
总结 仅仅一百多行代码我们就实现了一个简单有趣的 Web 小游戏。如果你刚入门前端,相信本项目可以很好的让你理解,练习如何使用 JavaScript 操作 DOM.
联系方式 qq:2061302791
微信:xie2061302791
电话:15284524485
个人网站:https://xieyingpeng.github.io
Github:https://github.com/xieyingpeng/
博客园:https://www.cnblogs.com/Xieyingpengz
知乎:https://www.zhihu.com/people/nan-qiao-12-73
gitee:https://gitee.com/xie-yingpeng/project-1.git
bilibili:https://space.bilibili.com/617198338?share_medium=android&share_source=copy_link&bbid=XY2BDF522C748A159BE7DD354D6DFFB963728&ts=1612520115798