首页 > 编程 > JavaScript > 正文

使用JS代码实现俄罗斯方块游戏

2019-11-19 13:20:54
字体:
来源:转载
供稿:网友

简单的JS俄罗斯方块游戏源码,先给大家展示下效果图,如果大家感觉不错,请参考实现代码,

  效果图:

 代码如下,复制即可使用:

<!DOCTYPE html><html><head><meta charset="utf-8"><title>使用JS实现俄罗斯方块游戏</title><style type="text/css">  .MainFrame  {    border: 1px solid burlywood;    margin: 10px auto;    position: relative;    background-color: silver;  }  .MainFramediv  {    float: left;    margin: 1px;    position: absolute;    /*z-index: -1;*/  }  .smallDiv  {    margin: 1px;    position: absolute;  }  .smallDivblack  {    /*float: left;*/    margin: 1px;    /*margin: 1px;*/    position: absolute;    /*z-index: 2;*/  }  #tetris{    width: 50%;    margin: 0 auto;    padding: 0;    /*border: 1px solid silver;*/  }  #tetris:after{    content: "";    Display: block;    Clear: both;  }  #control{    float: left;    border: 1px solid silver;    width: 150px;    height: 578px;    margin-top: 10px;    margin-left: 20px;    padding-top: 30px;    font-size: 24px;    font-weight: 400;    color: blue;    text-align: center;  }  #level,#regame{    width: 100px;    height: 30px;    border: 1px solid blue;    font-size: 16px;    color: red;    font-weight: 300;  }  #control p{    margin-top: 200px;  }  #regame{    margin-top: 100px;    font-weight: 600;    background-color: azure;  }  #TFrime{    float: left;  }  #info{    float: left;    border: 1px solid silver;    width: 150px;    height: 578px;    margin: 10px auto;    padding-top: 30px;    text-align: center;    color: blue;    font-size: 24px;    font-weight: 400;  }  #nextfigure{    width: 100px;    height: 100px;    background-color: silver;    margin: 0 auto;    margin-bottom: 100px;    position: relative;  }  .drawdiv{    background-color: red;    margin: 1px;    border: 1px solid silver;    position: absolute;  }</style><!-- 此处需要自己修改JS路径 --><script src="js/GameFrame.js" type="text/javascript" charset="utf-8"></script><script src="js/graph.js" type="text/javascript" charset="utf-8"></script><script src="js/index.js" type="text/javascript" charset="utf-8"></script></head><body onload="initGame()"><div id="tetris">  <div id="control">    难度:    <div><select id="level" onchange="changespeed()">      <option value="1000">简单      <option value="500">一般      <option value="200">困难    </select></div>    <input type="button" id="regame" value="重 新 开 始" onclick="regame()">    <p>      ↑:变换<br>      ←:左移<br>      →:右移<br>      ↓:加速<br>    </p>  </div>  <div id="TFrime"></div>  <div id="info">    下一个图形:    <div id="nextfigure">    </div>    <div>分数:<span id="score">0</span></div>  </div></div><div style="text-align:center;margin:10px 0; font:normal 14px/24px 'MicroSoft YaHei';"><p>适用浏览器:360、FireFox、Chrome、Safari、Opera、傲游、搜狗、世界之窗. 不支持IE8及以下浏览器。</p></div></body></html>

 GameFrame.js

function GameFrame(unit,row,col){  //单位的像素  this.unit = unit;  //横向单位个数(列),,(一行的个数)  this.row = row;  //纵向单位个数(行),,(一列的个数)  this.col =col;  //保存页面创建div容器的属性  this.Content;  //小图形  this.samlldiv;  //定时器id  this.intervalid;  //速度  this.speed =document.getElementById("level").value;  //速度是否改变  this.ChangeSped=0;  //记录每个位置是否有div  this.datas=[];  //记录消除行数相应的分数  this.score=[0,100,300,600,1000]  //记录当前的图形的下标  this.now;  //记录下一个图形的下标  this.next;  //记录当前的图形的颜色  this.nowcolor;  //记录下一个图形的颜色  this.nextcolor;  //保存7种图形相对坐标的数组  this.arr = "0,1,0,2,1,2,2,2;0,1,1,1,1,2,2,2;0,1,0,2,1,1,2,1;0,2,1,1,1,2,2,1;1,0,1,1,1,2,1,3;1,1,1,2,2,1,2,2;1,1,2,0,2,1,2,2".split(";");  //保存小方块的颜色  this.color=["red","blue","green","yellow","#00FFFF","#930093","#F80000","#984B4B"];  //初始化容器div  this.init = function()  {    //创建div    var div = document.createElement("div");    //设置div的宽度    div.style.width = (this.unit*this.row)+"px";    //设置div的高度    div.style.height=(this.unit*this.col)+"px";    //设置div的样式    div.className="MainFrame";    div.id="MainFrame";    //加入到body中    document.getElementById("TFrime").appendChild(div);    this.Content =div; //保存div的引用    //初始化数组    for(var i=0;i<this.col;i++)  //i为行    {      for(var j=0;j<this.row;j++){        //j为列      var sdiv = document.createElement("div");      sdiv.className="MainFramediv";      sdiv.style.width = (this.unit - 2) + "px";      sdiv.style.height = (this.unit - 2) + "px";      sdiv.style.left=(j*this.unit)+"px";      sdiv.style.top=(i*this.unit)+"px";      this.Content.appendChild(sdiv);      this.datas.push(0);      }    }    this.next=Math.floor(Math.random() * this.arr.length);    this.nextcolor=this.color[Math.floor(Math.random() * this.color.length)];    Start();  }  this.MoveLeft = function()  {    this.samlldiv.moveleft();  }  this.MoveRight = function(){    this.samlldiv.moveright();  }  this.Change = function(){    this.samlldiv.change();  }  this.MoveDown = function(){    if(this.samlldiv.movedown())    {//      for(var i=0;i<this.samlldiv.divs.length;i++)//      {//        this.Content.removeChild(this.samlldiv.divs[i]);//      }      this.samlldiv.rescore();      Start();    }  }  function Start()  {    //将next值传给now    this.frame.now=this.frame.next;    this.frame.nowcolor=this.frame.nextcolor;    //创建小div    this.frame.samlldiv=new Graph(this.frame);    this.frame.samlldiv.init(this.frame.now,this.frame.nowcolor);    //绘出下一个图形    this.frame.next=Math.floor(Math.random() * this.frame.arr.length);    this.frame.nextcolor=this.frame.color[Math.floor(Math.random() * this.frame.color.length)];    draw();    //调用定时器下落    this.frame.intervalid = setInterval(autoMoveDown,this.frame.speed);    //判断游戏是否结束    if (this.frame.samlldiv.movedown()){        clearInterval(this.frame.intervalid);        alert("游戏结束!");      }  }  function autoMoveDown()  {    if(this.frame.samlldiv.movedown())    {      this.frame.samlldiv.rescore();      Start();    }    //改变速度    if(this.frame.ChangeSped){      clearInterval(this.frame.intervalid);      this.frame.intervalid = setInterval(autoMoveDown,this.frame.speed);      this.frame.ChangeSped=0;    }  }  //速度改变,令ChangeSped值为1  this.changespeed=function(){    this.speed=document.getElementById("level").value;    this.ChangeSped=1;//    alert(this.ChangeSped);  }  //绘制下一个图形  function draw(){    //清楚原有的图形    var cleardiv=document.getElementsByClassName("drawdiv");    for(;;){      if(cleardiv.length){        document.getElementById("nextfigure").removeChild(cleardiv[0]);      }else{        break;      }    }    //绘制图形    var smallarr = this.frame.arr[this.frame.next].split(",");    for (var i = 0; i < 8; i += 2) {    var drawdiv = document.createElement("div");    drawdiv.className = "drawdiv";    drawdiv.style.backgroundColor=this.frame.nextcolor;    drawdiv.style.width = (this.frame.unit - 2) + "px";    drawdiv.style.height = (this.frame.unit - 2) + "px";    drawdiv.style.top = (((smallarr[i] - 0) * this.frame.unit)+18) + "px";    drawdiv.style.left = (((smallarr[i + 1] - 0) * this.frame.unit)+18) + "px";    document.getElementById("nextfigure").appendChild(drawdiv);    }  }}

 graph.js

function Graph(frame) {  //保存7种图形相对坐标的数组//  var arr = "0,1,0,2,1,2,2,2;0,1,1,1,1,2,2,2;0,1,0,2,1,1,2,1;0,2,1,1,1,2,2,1;1,0,1,1,1,2,1,3;1,1,1,2,2,1,2,2;1,1,2,0,2,1,2,2".split(";");  //保存4个小图形的数组  this.divs = [];  //外部容器div的数组  this.parentFrame = frame;  //图形横纵偏移  this.x = 0;  this.y = 0;  //记录图形的坐标数组  this.zb = [];  //记录消除的行数  this.line=0;  //初始化小图形的方法  this.init = function(rand,color) {      //计算图形其实坐标的单位      var startleft = (this.parentFrame.row - 4) / 2;      this.x = startleft;      //随机生成图形数组下标//      var rand = Math.floor(Math.random() * arr.length);      //分解图形的坐标      var smallarr = this.parentFrame.arr[rand].split(",");      this.zb = smallarr;      //循环设置小div的 left和top      for (var i = 0; i < 8; i += 2) {        //创建小div        var smalldiv = document.createElement("div");        //设置样式        smalldiv.className = "smallDiv";        //设置颜色        smalldiv.style.backgroundColor=color;        //定义高宽        smalldiv.style.width = (this.parentFrame.unit - 2) + "px";        smalldiv.style.height = (this.parentFrame.unit - 2) + "px";        //设置小div的top        smalldiv.style.top = ((smallarr[i] - 0) * this.parentFrame.unit) + "px";        //设置小div的left        smalldiv.style.left = (((smallarr[i + 1] - 0) + startleft) * this.parentFrame.unit) + "px";        //保存小div的引用        this.divs.push(smalldiv);                //加入到外部容器        document.getElementById("MainFrame").appendChild(smalldiv);      }      //执行自动向下移动      //this.parentFrame.intervalid = setInterval(autoMoveDown, this.parentFrame.speed);    }    //左移动  this.moveleft = function() {      //    var canmove = true;      //    //判断能否左移动      //          //    for(var i=0;i<this.divs.length;i++)      //    {      //        var left=parseInt(this.divs[i].style.left); //div目前的left      //        if(left - this.parentFrame.unit <0) //减去一个单位的像素是否小于0      //        {      //          canmove = false; //不能向左移动了      //          break;      //        }      //    }      if (canMove(this.zb, this.x, this.y, this.parentFrame, 2)) //可以移动      {        this.x -= 1;        for (var i = 0; i < this.divs.length; i++) //循环小div,把每个div的left减去一个单位的像素        {          var left = parseInt(this.divs[i].style.left);          this.divs[i].style.left = (left - this.parentFrame.unit) + "px";        }      }    }    //右移动  this.moveright = function() {    //    var canmove = true;    //      //判断能否右移动    //    for(var i=0;i<this.divs.length;i++)    //    {    //      var left=parseInt(this.divs[i].style.left);    //      if(left + this.parentFrame.unit >=parseInt(this.parentFrame.Content.style.width))    //      {    //        canmove = false;    //        break;    //      }    //    }    var temp = canMove(this.zb, this.x, this.y, this.parentFrame, 1);//    alert(temp);    console.log(temp);    if (canMove(this.zb, this.x, this.y, this.parentFrame, 1)) {      this.x += 1;      for (var i = 0; i < this.divs.length; i++) {        var left = parseInt(this.divs[i].style.left);        this.divs[i].style.left = (left + this.parentFrame.unit) + "px";      }    }  }  //变形  this.change = function() {    //变形的公式    //小div的2个相对坐标点改变  x = y ; y= 3-x; 比如 (0,1) 变化之后 就是  x=1,y=3-0 -> (1,3)    //循环4个小div    if (!canMove(this.zb, this.x, this.y, this.parentFrame, 4)) {      if (this.x < 0) {        this.x += 1;      } else {        this.x -= 1;      }    }    for (var i = 0; i < this.divs.length; i++) {      //根据公式改变每个div的相对偏移量,2个一改      var temp = this.zb[i * 2]      this.zb[i * 2] = this.zb[i * 2 + 1];      this.zb[i * 2 + 1] = 3 - temp;      //根据改变后的偏移量计算图形的当前left和top      this.divs[i].style.top = ((this.y + parseInt(this.zb[i * 2])) * this.parentFrame.unit) + "px";      this.divs[i].style.left = ((this.x + parseInt(this.zb[i * 2 + 1])) * this.parentFrame.unit) + "px";    }  }  this.movedown = function() {    var $this = this =="window" ? this.frame.samlldiv : this;    if (canMove($this.zb, $this.x, $this.y, $this.parentFrame, 3)) {      $this.y += 1;      for (var i = 0; i < $this.divs.length; i++) {        var top = parseInt($this.divs[i].style.top);        $this.divs[i].style.top = (top + $this.parentFrame.unit) + "px";      }      return false;    } else {      clearInterval($this.parentFrame.intervalid);//      var temp = $this.parentFrame.Content.getElementsByTagName("div");      for (var i=0;i<$this.divs.length;i++) {        //div变灰        //$this.divs[i].className ="smallDivblack";        var $y = $this.y + parseInt($this.zb[i*2]);        var $x = $this.x+parseInt($this.zb[i*2+1]);//        debugger;        $this.parentFrame.datas[$y*$this.parentFrame.row+ $x] =1;        $this.divs[i].dataset.row=$y;  //记录div所在的行        $this.divs[i].dataset.col=$x;  //记录div所在的列        $this.divs[i].className="smallDivblack";        $this.divs[i].style.backgroundColor="black";        //$this.parentFrame.datas[]      }        //消行并计分        for (var i= 0;i<$this.parentFrame.col;i++) {    //i为行          //判断是否满足消行条件          for (var j=0;j<$this.parentFrame.row;j++) {    //j为列            if($this.parentFrame.datas[i*$this.parentFrame.row+ j] !=1){              break;            }          }          //消行,将该行上面的所有div下移一行          if(j==$this.parentFrame.row){            var x;    //记录div在哪一列            var y;    //记录div在哪一行            var getsmalldiv=document.getElementById("TFrime").getElementsByClassName("smallDivblack");//得到小div            for (var a=0;a<getsmalldiv.length;a++){              y=parseInt(getsmalldiv[a].dataset.row);              x=parseInt(getsmalldiv[a].dataset.col);              if(y==i){    //消除该行                debugger;                $this.parentFrame.datas[y*$this.parentFrame.row+ x]=0;                getsmalldiv[a].remove();                a--;              }            }            for (var a=i-1;a>0;a--) {              for (var b=0;b<getsmalldiv.length;b++) {                y=parseInt(getsmalldiv[b].dataset.row);                x=parseInt(getsmalldiv[b].dataset.col);                if(y==a){    //将上面的div下移一行//                debugger;                var divtop=parseInt(getsmalldiv[b].style.top);                getsmalldiv[b].style.top=(divtop+$this.parentFrame.unit)+"px";                getsmalldiv[b].dataset.row++;                $this.parentFrame.datas[y*$this.parentFrame.row+ x]=0;                $this.parentFrame.datas[(y+1)*$this.parentFrame.row+ x]=1;                }              }            }            $this.line++;//            for (var a=0;a<getsmalldiv.length;a++) {//              y=parseInt(getsmalldiv[a].dataset.row);//              x=parseInt(getsmalldiv[a].dataset.col);////              alert(getsmalldiv[a].dataset.row);//              if(y<i){    //将上面的div下移一行////                debugger;//                var divtop=parseInt(getsmalldiv[a].style.top);////                alert(getsmalldiv[a].style.top);//                getsmalldiv[a].style.top=(divtop+$this.parentFrame.unit)+"px";//                getsmalldiv[a].dataset.row++;//                debugger;//                $this.parentFrame.datas[y*$this.parentFrame.row+ x]=0;//                $this.parentFrame.datas[(y+1)*$this.parentFrame.row+ x]=1;//              }////              }else if(y==i){    //消除该行////                debugger;////                $this.parentFrame.datas[y*$this.parentFrame.row+ x]=0;////                getsmalldiv[a].className="MainFramediv";////              }//            }          }        }      return true;    }  }//  function autoMoveDown() {//    //    var small = this.frame.samlldiv;//    var f = this.frame;//    //    if (canMove(small.zb, small.x, small.y, 0, f.col, 3)) {//      small.y += 1;//      for (var i = 0; i < small.divs.length; i++) {//        var top = parseInt(small.divs[i].style.top);//        small.divs[i].style.top = (top + f.unit) + "px";//      }//    } else {//      clearInterval(f.intervalid);//    }////  }  //预判能否移动或变化,action:1.右移,2.左移,3.下移,4.变化  //zb是4个小图形的相对偏移,x是图形左偏移,y是top偏移,f是外部frame  function canMove(zb, x, y, f, action) {    //datas[parseInt(zb[i + 1]) + x + 1)+(this.y-1)*row] !=0    switch (action) {      case 1://        debugger;        for (var i = 0; i < zb.length; i += 2) {          if (parseInt(zb[i + 1]) + x + 1 >= f.row)          {            return false;          }else if(f.datas[(parseInt(zb[i + 1]) + x + 1)+(y+parseInt(zb[i]))*f.row] !=0)          {            return false;          }        }        break;      case 2:        for (var i = 0; i < zb.length; i += 2) {          if (parseInt(zb[i + 1]) + x - 1 < 0 ) {            return false;          }else if(f.datas[(parseInt(zb[i + 1]) + x - 1)+(y+parseInt(zb[i]))*f.row] !=0)          {            return false;          }        }        break;      case 3:        for (var i = 0; i < zb.length; i += 2) {          if (parseInt(zb[i]) + y + 1 >= f.col ||          f.datas[(parseInt(zb[i + 1]) + x)+(parseInt(zb[i]) + y+1)*f.row] !=0) {            return false;          }        }        break;      case 4:        for (var i = 0; i < zb.length; i += 2) {          var temp = 3 - zb[i];          if (temp + x < 0 || temp + x >= f.row) {            return false;          }        }        break;    }    return true;  }  this.rescore=function(){    var gamescore=document.getElementById("score");    gamescore.innerHTML=parseInt(gamescore.innerHTML)+this.parentFrame.score[this.line];  }}

 index.js

var frame;function initGame(){  frame = new GameFrame(16,20,38);  frame.init();  document.body.addEventListener("keydown",MoveOrChange)}function changespeed(){  frame.changespeed();}function regame(){  location.reload();}function MoveOrChange(){  switch(event.keyCode)  {    case 38: //变形(上方向键)      frame.Change();      break;    case 37: //左移动      frame.MoveLeft();      break;    case 39://右移动      frame.MoveRight();      break;    case 40: //向下      frame.MoveDown();      break;  }}

总结

以上所述是小编给大家介绍的使用JS代码实现俄罗斯方块游戏,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对武林网网站的支持!

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