最近有朋友让我用JS帮我模仿一个不踩白块的小游戏程序。但是他给出的源代码比较麻烦,没有评论,所以我无法理解。我用自己的想法做了这个小游戏,主要是用JS来操作DOM和数组。
程序思路:如图:在游戏区设置CSS为相对定位,溢出隐藏;两个“游戏板”分别排列24个方块,每条黑线随机生成一个。“游戏板”向下滚动交替显示,每个操作板的黑块位置都存储在一个数组中,每次点击都弹出数组进行比较(我觉得亮点在这里……)。
这是游戏的GitHub地址。你可以点击中间菜单最右边的下载ZIP按钮,下载到桌面上试试,HTML和JS都不用服务器。
下载地址
以下是具体实现,并对关键部分进行了评论。
HTML第:节。
!DOCTYPE htmlhtmlheadtitle,不要踩白块/title/head body div id=' game zone ' div id=' board b ' style=' position : absolute;top: 0px'/div/div//初始化一个boardb,使ab同时存在于/body/htmlCSS部分:
复制的代码如下: * { margin: 0pxpadding: 0px盒子尺寸:边框盒子;}//简单的重置,使用box-size设置框大小,计算边框,以便后期计算小方块的位置。
# gameZone { width: 302pxheight: 602pxborder: 1px纯绿色;margin: 20px自动;相对位置:飞越:隐藏;}//在游戏区,多了两个像素可以去掉边框,有足够的300*600的空间。方形{ width: 75px高度: 100像素;向左浮动:border: 1px纯黑;}。squareBlack { width: 75px高度: 100像素;border: 1px纯黑;向左浮动:背景:黑色;}//每个小方块为75*100,设置黑色小方块的背景色。
JS部分:
下面介绍子功能:
全局变量初始化
var loc=600//黑块落地失败,判断var count=0;//初始化命中var locArr=[]的黑块总数;//在游戏棋盘上的黑块位置初始化var order=(function(){ var order=' A ';return function(){ if(order==' boarda ')order=' boardb ';else order=' boarda ';退货单;} })))//使用闭包函数使每次boarda和boardb创建的游戏板的ID。事实上,使用全局变量是可以的,但是为了有点约束。
每次点击判断结果的功能。
函数judge () {var num=this。ID . substr(3)//获取元素的id号if(num!=locArr.pop()){ //与位置数组clearTimeout(timer)的pop进行比较;Alert('你的分数是:'数'分!');返回;//故障清除计时器,结算得分。} else { loc=100this . style . background=' silver ';计数=1;//成功将落地标志添加到网格的高度,更改网格的背景颜色,点击数字1}if(计数!=0count==0){cleartimeout(timer);new timer=50-count/15 * 5;timer=setInterval('fall()',new timer);}//每15次点击后加速一点。这个公式可以自己定义。}生成小黑盒在大盒子中位置的随机数,每次创建游戏棋盘时调用该函数,根据生成的数字定义小黑盒的位置。
函数generateRand(){ var Numarr=[];for(var j=0;j6;j){ var num=math . floor(math . random()* 4)j * 4;numar . push(num);}返回numArr}每次调用都会生成一个游戏板在游戏区上方向下滚动,并将游戏板的黑色部分PUSH到locArr中。
函数draw board(){ var temArr=generateRand();//这里应用了临时位置数组,防止两个游戏棋盘之间的位置冲突。loc arr=temarr . concat(loc arr);//将临时数组连接到全局位置数组。varboard=document . create element(' div ');board.setAttribute('id ',order());board.style.position=“绝对”;board . style . top='-600 px ';for(var I=0;i24I){ var ele=document . create element(' div ');ele.setAttribute('id ',' ele ' I);If(temArr.indexOf(i)-1){ //判断当前创建的小方块的ID序列是否属于临时位置数组ele。setattribute ('class ',' square black')} else {ele。setattribute ('class ',' square ');}ele.addEventListener('click ',judge,false);//在每个小方块中加入点击判断功能judge board . appendchild(ele);} var gameZone=document . getelementbyid(' gameZone ');gameZone.appendChild(棋盘);}在脚本中找到两个游戏板并向下滚动。
函数fall(){ gameZone=document . getelementbyid(' gameZone ');var boarda=document . getelementbyid(' boarda ');//因为ab两个游戏板总是全局存在的,所以找不到的时候不需要定义逻辑:var anow top=par sent(boarda . style . top);//因为得到的顶部位置是xxxpx类型,所以用parseInt()将其转换成整数比较方便。If(anowtop==595){ //这里的数字是595而不是600,因为删除了这一帧后,下一帧刚好是600px,正好让两个游戏板完美衔接。gameZone . remove child(boarda);draw board();//删除游戏区的游戏板,在顶部新建一个。} anowtop=5;boarda . style . top=anowtop ' px ';var board b=document . getelementbyid(' board b ');var b now top=ParSeint(board b . style . top);if(b now top==595){ GameZone . remove child(board b);draw board();} b now top=5;board b . style . top=b now top ' px ';loc-=5;if(loc==0){clearTimeout(定时器);Alert('你的分数是:'数'分!');返回;}//每一帧会减少5点落地判断。落地判定为0时,表示落地,分数就定了。}在window.onload函数中写主体调用,这样就可以在页面的游戏区加载后调用该函数。
window . onload=function(){ draw board();fall();var timer=setInterval('fall()',50);}游戏扩展:
添加页面UI:因为开头的HTML非常简单,所以UI很容易修改。设置按钮并点击以触发启动功能。
改变游戏难度:修改setInterval的值,修改判断函数中的区间数,或者优化下落加速度的表达式。
增加分数排名等。用ajax连接服务器,游戏结束后将结果写入数据库,参考数据中的排名。
改成街机模式:去掉计时,修改判断功能,让它每次点击游戏棋盘,都降到一个小方块的高度。设置总数、开始时间和结束时间。