JavaScript制作俄罗斯方块游戏

时间:2016-11-0951举报小编:youjiejie

    JavaScript制作俄罗斯方块游戏,用JavaScript制作俄罗斯方块游戏。

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

    完成后的效果如下:

    JavaScript制作俄罗斯方块游戏

    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

    以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持未来软件园。