当前位置:主页 > 网页前端 > JavaScript代码 >

js html5 css俄罗斯方块游戏再现

时间:2020-12-04 04:34:05 | 栏目:JavaScript代码 | 点击:

这个游戏主要分为三部份,HTML5+CSS+JAVASCRIPT来完成的。在这里详细讲一下js的代码。因为这个游戏的主要部分其实就是js。

大多数都是靠js来完成的。


完成后的效果如下:

HTML代码:

<body> 
 <div class="wrap"> 
 <div class="play_wrap"> 
 <div id="play_area"></div> 
 <div class="play_menu"> 
 <p>下一个:</p> 
 <div id="play_nextType"></div> 
 <a id="play_btn_start" class="play_btn" href="javascript:void(0);" 
 unselectable="on">开始</a><a id="play_btn_level" class="play_btn" href="javascript:void(0)" unselectable="on"><span class="level_text">中等</span class="level_icon"></span></a> 
 <div class="level_menu" id="play_menu_level"> 
 <ul> 
 <li><a href="javascript:void(0)" level=0>简单</a></li> 
 <li><a href="javascript:void(0)" level=1>中等</a></li> 
 <li><a href="javascript:void(0)" level=2>困难</a></li> 
 </ul> 
 </div> 
 <p> 
 分数:<span id="play_score">0</span> 
 </p> 
 <p> 
 方向:<span id="play_direction">bottom</span> 
 </p> 
 <p> 
 说明:<br> -“下”、“左”、“右”键控制方向,“上”为变形;<br> -游戏开始前、暂停时可调整难度;<br> 
 -难度分“简单”、“中等”、“困难”三级;<br> -对应的分值为10、20、40;<br> 
 -多行同时消去的倍数为1、4、10、20; 
 </p> 
 </div> 
 </div> 
 </div> 
 </body>

CSS代码:

<style> 
body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,button,textarea,p,blockquote,th,td 
{ 
 padding: 0; 
 margin: 0; 
} 
 
body { 
 font-family: "Helvetica Neue", "Hiragino Sans GB", "Segoe UI", 
 "Microsoft Yahei", "微软雅黑", Tahoma, Arial, STHeiti, sans-serif; 
 font-size: 12px; 
 background: #fff; 
 color: #333; 
} 
 
a{ 
 outline:none; 
 -moz-outline:none; 
 text-decoration: none; 
} 
 
.wrap{ 
 width:1000px; 
 margin:80px auto; 
} 
 
.play_wrap{ 
 padding-left:260px; 
} 
 
#play_area{ 
 float:left; 
 width:300px; 
 height:480px; 
 margin:auto; 
 background-color:#fefefe; 
 border-radius:2px; 
 color:black; 
 box-shadow:0px 0px 8px #e5e5e5; 
 padding:1px 0 0 1px; 
} 
 
#play_area .play_cell{ 
 float:left; 
 width:19px; 
 height:19px; 
 border:1px solid #eee; 
 margin:-1px 0 0 -1px; 
} 
 
#play_area .play_cell.active{ 
 background:#999; 
 border:1px solid #ccc; 
} 
 
#play_area .play_cell.goal{ 
 background:#0c0; 
} 
 
.play_menu{ 
 float:left; 
 margin-left:60px; 
 font-size:14px; 
 padding-top:20px; 
} 
 
.play_menu #play_nextType{ 
 width:60px; 
 height:60px; 
 padding:1px 0 0 1px; 
 margin:10px 0 20px 0; 
} 
 
.play_menu .play_mini_cell{ 
 float:left; 
 width:14px; 
 height:14px; 
 border:1px solid #fff; 
 margin:-1px 0 0 -1px; 
} 
 
.play_menu .play_mini_cell.active{ 
 background:#999; 
 border:1px solid #ccc; 
} 
 
.play_menu p { 
 line-height:200%; 
 clear:both; 
} 
 
.play_menu a.play_btn{ 
 display:block; 
 margin-bottom:20px; 
 width:80px; 
 height:28px; 
 line-height:28px; 
 text-align:center; 
 text-decoration: none; 
 color:#333; 
 background:#fefefe; 
 border:1px solid #eee; 
 border-radius: 2px; 
 box-shadow: 1px 1px 2px #eee; 
 border-color:#ddd #d2d2d2 #d2d2d2 #ddd; 
 outline: none; 
 -moz-outline:none; 
} 
 
.play_menu a.play_btn:hover{ 
 background-color:#fcfcfc; 
 border-color:#ccc; 
 box-shadow: inset 0 -2px 6px #eee; 
} 
 
.play_menu a#play_btn_level{ 
 position:relative; 
 margin-bottom:30px; 
} 
 
.level_text{ 
 margin-left:-10px; 
} 
 
.level_icon{ 
 display: block; 
 position:absolute; 
 top:12px; 
 right:16px; 
 width:0; 
 height:0; 
 overflow: hidden; 
 border:5px solid #FFF; 
 border-color: #999 transparent transparent transparent; 
} 
 
.level_menu{ 
 position:absolute; 
 margin:-30px 0 0 1px; 
 display:none; 
} 
.level_menu ul{ 
 list-style:none; 
} 
.level_menu li{ 
 float:left; 
} 
.level_menu li a{ 
 display:block; 
 padding:3px 10px; 
 border:1px solid #e8e8e8; 
 margin-left:-1px; 
 color:#09c; 
} 
.level_menu li a:hover{ 
 background:#09c; 
 color:#fefefe; 
} 
</style> 

HTML的代码其实就是一个游戏结构的框架,这里框架其实就是几个div的东西,所以不会太长,理解起来也是挺容易的。而CSS则是控制网页的布局与美观,所以要想吸引玩家,那CSS方面必须下功夫,而这里的CSS只是其实就将游戏区域与菜单区域分为左右两边了。而游戏域内的一个个框其实就是多个div,整齐排列在一起而已。

下面到了js了:

因为在代码已经将一些重要的部分做了注释,所以就不打算逐步分去分析了。说一下整体的写法吧。其实它首先是直接定义了一些图形的坐标,然后根据这些坐标画出一个下一个的图形出来,之后就是利用一个setInterval函数在游戏区域标出每个点,如果不能下落了就直接清除掉时间函数,之后在调用一个创建时间函数的函数出来,在画一个图形出来。具体的细节就看代码吧。

<script type="text/javascript" src="jquery-1.6.2.min.js"></script> 
 <script type="text/javascript"> 
 var Tetris = function(options){ 
 //方块区域 
 this.e_playArea = $("#play_area"); 
 //开始按钮 
 this.e_startBtn = $("#play_btn_start"); 
 //分数 
 this.e_playScore = $("#play_score"); 
 //方向 
 this.e_playDirection = $("#play_direction"); 
 //等级按钮 
 this.e_levelBtn = $("#play_btn_level"); 
 //等级菜单 
 this.e_levelMenu = $("#play_menu_level"); 
 //下一个方块的类型 
 this.e_nextType = $("#play_nextType"); 
 //总的列数 
 this.cellCol = 15; 
 //总的行数 
 this.cellRow = 24; 
 //每个小方块的属性数组 
 this.cellArr = []; 
 //保存右上方下一个那里的小图形数组 
 this.miniCellArr = []; 
 //分数 
 this.score = 0; 
 //方向 
 this.direction = "bottom"; 
 //定时器的ID 
 this.timer = null; 
 //定时器的时间数组 
 this.interval = [600,300,100]; 
 //等级的分数数组 
 this.levelScore = [10,20,40]; 
 //消除的行数多少而给的倍数 
 this.doubleScore = [1,4,10,20]; 
 //默认等级1 
 this.level = 1; 
 //游戏是否进行 
 this.playing = false; 
 //游戏暂停标记 
 this.turning = false; 
 //游戏结束标记 
 this.death = false; 
 //一开始方块列出现的位置 
 this.offsetCol = Math.floor(this.cellCol/2); 
 //一开始方块行出现的位置 
 this.offsetRow = -3; 
 
 this.tetrisArr = []; 
 /* 
 0,1,15,16 
 0,1,15,16 
 */ 
 this.tetrisArr[0] = [ 
 [0,1,this.cellCol,this.cellCol+1], 
 [0,1,this.cellCol,this.cellCol+1] 
 ]; 
 /* 
 1,14,15,16 
 0,15,30,31 
 14,15,16,29 
 -1,0,15,30 
 */ 
 this.tetrisArr[1] = [ 
 [1,this.cellCol-1,this.cellCol,this.cellCol+1], 
 [0,this.cellCol,this.cellCol*2,this.cellCol*2+1], 
 [this.cellCol-1,this.cellCol,this.cellCol+1,this.cellCol*2-1], 
 [-1,0,this.cellCol,this.cellCol*2] 
 ]; 
 /* 
 -1,14,15,16 
 0,1,15,30 
 14,15,16,31 
 0,15,29,30 
 */ 
 this.tetrisArr[2] = [ 
 [-1,this.cellCol-1,this.cellCol,this.cellCol+1], 
 [0,1,this.cellCol,this.cellCol*2], 
 [this.cellCol-1,this.cellCol,this.cellCol+1,this.cellCol*2+1], 
 [0,this.cellCol,this.cellCol*2-1,this.cellCol*2] 
 ]; 
 /* 
 0,15,16,31 
 15,16,29,30 
 */ 
 this.tetrisArr[3] = [ 
 [0,this.cellCol,this.cellCol+1,this.cellCol*2+1], 
 [this.cellCol,this.cellCol+1,this.cellCol*2-1,this.cellCol*2] 
 ]; 
 /* 
 0,14,15,29 
 14,15,30,31 
 */ 
 this.tetrisArr[4] = [ 
 [0,this.cellCol-1,this.cellCol,this.cellCol*2-1], 
 [this.cellCol-1,this.cellCol,this.cellCol*2,this.cellCol*2+1] 
 ]; 
 /* 
 0,14,15,16 
 0,15,16,30 
 14,15,16,30 
 0,14,15,30 
 */ 
 this.tetrisArr[5] = [ 
 [0,this.cellCol-1,this.cellCol,this.cellCol+1], 
 [0,this.cellCol,this.cellCol+1,this.cellCol*2], 
 [this.cellCol-1,this.cellCol,this.cellCol+1,this.cellCol*2], 
 [0,this.cellCol-1,this.cellCol,this.cellCol*2] 
 ]; 
 /* 
 0,15,30,45 
 14,15,16,17 
 */ 
 this.tetrisArr[6] = [ 
 [0,this.cellCol,this.cellCol*2,this.cellCol*3], 
 [this.cellCol-1,this.cellCol,this.cellCol+1,this.cellCol+2] 
 ]; 
 this.tetrisType = [1,1]; 
 this.tetrisType = [1,0]; 
 this.tetrisTypeArr = []; 
 
 this.preTetris = []; 
 this.thisTetris = []; 
 this.fullArr = []; 
 
 this.start(); 
 } 
 Tetris.prototype = { 
 //开始入口函数 
 start : function(){ 
 this.init(); 
 this.menu(); 
 this.control(); 
 }, 
 //选择设置 
 setOptions : function(options){ 
 this.score = options.score === 0 ? options.score 
 : (options.score || this.score); 
 this.level = options.level === 0 ? options.level 
 : (options.level || this.level); 
 }, 
 resetArea : function(){ 
 $(".play_cell.active").removeClass("active"); 
 this.setOptions({ 
 "score" : 0 
 }); 
 this.e.playScore.html(this.score); 
 }, 
 //菜单 
 menu : function(){ 
 var self = this; 
 this.e_startBtn.click(function(){ 
 self.e_levelMenu.hide(); 
 if(self.playing){ 
 self.pause(); 
 } else if(self.death){ 
 self.resetArea(); 
 self.play(); 
 } else { 
 self.play(); 
 } 
 }); 
 this.e_levelBtn.click(function(){ 
 if(self.playing)return; 
 self.e_levelMenu.toggle(); 
 }); 
 this.e_levelMenu.find("a").click(function(){ 
 self.e_levelMenu.hide(); 
 self.e_levelBtn.find(".level_text").html($(this).html()); 
 self.setOptions({ 
 "level" : $(this).attr("level") 
 }); 
 }); 
 }, 
 play : function(){ 
 var self = this; 
 this.e_startBtn.html("暂停"); 
 this.playing = true; 
 this.death = false; 
 if(this.turning){ 
 this.timer = setInterval(function(){ 
 self.offsetRow++; 
 self.showTetris(); 
 },this.interval[this.level]); 
 } else { 
 this.nextTetris(); 
 } 
 }, 
 pause : function(){ 
 this.e_startBtn.html("开始"); 
 this.playing = false; 
 clearTimeout(this.timer); 
 }, 
 //初始化游戏 
 init : function(){ 
 var self =this,_ele,_miniEle,_arr = []; 
 //创建小方块放进cellArr里 
 for(var i=0;i<this.cellCol;++i){ 
 for(var j=0;j<this.cellRow;++j){ 
 _ele = document.createElement("div"); 
 _ele.className = "play_cell"; 
 _ele.id = "play_cell_"+ i + "_" + j; 
 this.cellArr.push($(_ele)); 
 this.e_playArea.append(_ele); 
 } 
 } 
 //创建下一个图形的小方块 
 for(var m=0;m<16;++m){ 
 _miniEle = document.createElement("div"); 
 _miniEle.className = "play_mini_cell"; 
 this.miniCellArr.push($(_miniEle)); 
 this.e_nextType.append(_miniEle); 
 } 
 //保存三维数组tetrisArr的前两维数据编号,k为其第一维编号,j为其二维 
 for(var k=0,klen=this.tetrisArr.length;k<klen;++k){ 
 for(var j=0,jlen=this.tetrisArr[k].length;j<jlen;++j){ 
 this.tetrisTypeArr.push([k,j]); 
 } 
 } 
 //下一个图形的【x】【y】 
 this.nextType = this.tetrisTypeArr[Math.floor(this.tetrisTypeArr.length*Math.random())]; 
 this.showNextType(); 
 }, 
 //按键控制函数 
 control : function(){ 
 var self = this; 
 $("html").keydown(function(e){ 
 if(!self.playing) 
 return !self.playing; 
 switch(e.keyCode){ 
 case 37: 
 self.direction = "left"; 
 break; 
 case 38: 
 self.direction = "top"; 
 break; 
 case 39: 
 self.direction = "right"; 
 break; 
 case 40: 
 self.direction = "bottom"; 
 break; 
 default: 
 return; 
 break; 
 } 
 //显示当前的按键操作 
 self.e_playDirection.html(self.direction); 
 //实行按键的操作函数 
 self.drive(); 
 return false; 
 }); 
 }, 
 //改变图形的状态 
 changTetris : function(){ 
 var _len = this.tetrisArr[this.tetrisType[0]].length; 
 if(this.tetrisType[1] < _len-1){ 
 this.tetrisType[1]++; 
 } else { 
 this.tetrisType[1] = 0; 
 } 
 }, 
 //按键的操作函数 
 drive : function(){ 
 switch(this.direction){ 
 case "left": 
 if(this.offsetCol>0){ 
 this.offsetCol--; 
 } 
 break; 
 case "top": 
 this.changTetris(); 
 break; 
 case "right": 
 this.offsetCol++; 
 break; 
 case "bottom": 
 if(this.offsetRow<this.cellRow-2){ 
 this.offsetRow++; 
 } 
 break; 
 default: 
 break; 
 } 
 //显示图形的函数 
 this.showTetris(this.direction); 
 }, 
 //显示图形的函数 
 showTetris : function(dir){ 
 var _tt = this.tetrisArr[this.tetrisType[0]][this.tetrisType[1]],_ele,self=this; 
 this.turning = true; 
 this.thisTetris = []; 
 for(var i=_tt.length-1;i>=0;--i){ 
 _ele = this.cellArr[_tt[i]+this.offsetCol+this.offsetRow*this.cellCol]; 
 //规定左右移动不能超出边框 
 if(this.offsetCol<7&&(_tt[i]+this.offsetCol+1)%this.cellCol==0){ 
 this.offsetCol++; 
 return; 
 }else if(this.offsetCol>7&&(_tt[i]+this.offsetCol)%this.cellCol==0){ 
 this.offsetCol--; 
 return; 
 } 
 //判断是否下落是与方块碰撞了,排除向左移动时碰到左边的方块而停止下落 
 if(_ele&&_ele.hasClass("active")&&dir=="left"&&($.inArray(_ele,this.preTetris)<0)){ 
 if(($.inArray(_ele,this.cellArr)-$.inArray(this.preTetris[i],this.cellArr))%this.cellCol!=0){ 
 this.offsetCol++; 
 return; 
 } 
 } 
 if(_ele&&_ele.hasClass("active")&&dir=="right"&&($.inArray(_ele,this.preTetris)<0)){ 
 if(($.inArray(_ele,this.cellArr)-$.inArray(this.preTetris[i],this.cellArr))%this.cellCol!=0){ 
 this.offsetCol--; 
 return; 
 } 
 } 
 //找到某个div进行下落的过程 
 //否则找不到直接结束下落的过程 
 if(_ele){ 
 //找到一个div有class=active,而且不是上一次自身的位置,那么就停止 
 //向下走了,因为遇到障碍物了 
 //否则这个div符合,存起来 
 if(_ele.hasClass("active")&&($.inArray(_ele,this.preTetris)<0)){ 
 this.tetrisDown(); 
 return; 
 } else { 
 this.thisTetris.push(_ele); 
 } 
 } else if(this.offsetRow>0){ 
 this.tetrisDown(); 
 return; 
 } 
 } 
 //将上一次的位置的标记全部去除 
 for(var j=0,jlen=this.preTetris.length;j<jlen;++j){ 
 this.preTetris[j].removeClass("active"); 
 } 
 //标记这一次的位置 
 for(var k=0,klen=this.thisTetris.length;k<klen;k++){ 
 this.thisTetris[k].addClass("active"); 
 } 
 //储存起现在的位置,会成为下一次的前一次位置 
 this.preTetris = this.thisTetris.slice(0); 
 }, 
 //无法下落时进行的函数 
 tetrisDown : function(){ 
 clearInterval(this.timer); 
 var _index; 
 this.turning = false; 
 //是否填充满一行的检测 
 forOuter:for(var j=0,jlen=this.preTetris.length;j<jlen;++j){ 
 _index = $.inArray(this.preTetris[j],this.cellArr); 
 for(var k=_index-_index%this.cellCol,klen=_index-_index%this.cellCol+this.cellCol;k<klen;++k){ 
 if(!this.cellArr[k].hasClass("active")){ 
 continue forOuter; 
 } 
 } 
 if($.inArray(_index-_index%this.cellCol,this.fullArr)<0) 
 this.fullArr.push(_index-_index%this.cellCol); 
 } 
 if(this.fullArr.length){ 
 this.getScore(); 
 return; 
 } 
 //如果图形在6-9的div内被标记,那么游戏结束 
 for(var i=6;i<9;++i){ 
 if(this.cellArr[i].hasClass("active")){ 
 this.gameOver(); 
 alert("you lost!"); 
 return; 
 } 
 } 
 this.nextTetris(); 
 }, 
 //下一个图形 
 nextTetris : function(){ 
 var self = this; 
 clearInterval(this.timer); 
 this.preTetris = []; 
 this.offsetRow = -2; 
 this.offsetCol = 7; 
 this.tetrisType = this.nextType; 
 this.nextType = this.tetrisTypeArr[Math.floor(this.tetrisTypeArr.length*Math.random())]; 
 this.showNextType(); 
 this.timer = setInterval(function(){ 
 self.offsetRow++; 
 self.showTetris(); 
 },this.interval[this.level]); 
 }, 
 showNextType : function(){ 
 //_nt为找到在this.nextType[0]行,this.nextType[1]列的一行数据 
 var _nt = this.tetrisArr[this.nextType[0]][this.nextType[1]],_ele,_index; 
 //找到class=active的元素,之后全部删除class元素 
 this.e_nextType.find(".active").removeClass("active"); 
 for(var i=0,ilen=_nt.length;i<ilen;++i){ 
 //因为offsetCol的最小值只能为2,所以在tetrisArr数组中赋的值都减了2 
 //这里要加回2来处理,才能在小的视图里安放图形 
 if(_nt[i]>this.cellCol-2){ 
 _index = (_nt[i]+2)%this.cellCol-1+4*parseInt((_nt[i]+2)/this.cellCol); 
 }else{ 
 _index = _nt[i] + 1; 
 } 
 _ele = this.miniCellArr[_index]; 
 _ele.addClass("active"); 
 } 
 }, 
 //获取分数 
 getScore : function(){ 
 var self = this; 
 //对完整的行消除,对元素进行向下移动 
 for(var i=this.fullArr.length-1;i>=0;--i){ 
 for(var j=0;j<this.cellCol;++j){ 
 this.cellArr[j+this.fullArr[i]].removeClass("active"); 
 if(j==this.cellCol-1){ 
 for(var k=this.fullArr[i];k>=0;--k){ 
 if(this.cellArr[k].hasClass("active")){ 
  this.cellArr[k].removeClass("active"); 
  this.cellArr[k+this.cellCol].addClass("active"); 
 } 
 } 
 } 
 } 
 } 
 this.score += this.levelScore[this.level]*this.doubleScore[this.fullArr.length-1]; 
 this.e_playScore.html(this.score); 
 this.fullArr = []; 
 this.nextTetris(); 
 }, 
 //游戏结束 
 gameOver : function(){ 
 this.death = true; 
 this.pause(); 
 return; 
 } 
 }; 
 $(document).ready(function(e){ 
 var t = new Tetris(); 
 }); 
 </script> 

源码下载:http://xiazai.jb51.net/201610/yuanma/js-html5els(jb51.net).rar

您可能感兴趣的文章:

相关文章