首页 > 编程 > JavaScript > 正文

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

2019-11-20 08:44:02
字体:
来源:转载
供稿:网友

这个游戏主要分为三部份,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.VeVB.COm/201610/yuanma/js-html5els(VeVB.COm).rar

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持武林网。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表