原生js实现俄罗斯方块


Posted in Javascript onOctober 20, 2020

本文实例为大家分享了js实现俄罗斯方块的具体代码,供大家参考,具体内容如下

效果如下

原生js实现俄罗斯方块

html

<!DOCTYPE html>
<html lang="en">
 
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <meta http-equiv="X-UA-Compatible" content="ie=edge">
 <link rel="stylesheet" href="../css/Demo.css" >
 <title>俄罗斯方块</title>
</head>
 
<body>
 <div class="square" id="local">
 <div class="title"><h2>我方游戏区域</h2></div>
 <div class="game" id="local_game">
 
 </div>
 <div class="tip" id="local_tip">
 </div>
 <div class="next" id="local_next">
 
 </div>
 <div class="info">
  <div>用时<span id="local_time">  0</span></div>
  <div>得分<span id="local_score" class="score">  0</span></div>
 </div>
 </div>
 <div class="square" id="remote">
 <div class="title"><h2>对方游戏区域</h2></div>
 <div class="game" id="remote_game">
 
 </div>
 <div class="tip" id="remote_tip">
 </div>
 <div class="next" id="remote_next">
 
 </div>
 <div class="info">
  <div>用时<span id="remote_time">  0</span></div>
  <div>得分<span id="remote_score" class="score">  0</span></div>
  <div class="btn">
  <button id="down">down</button>
  <button id="left">left</button>
  <button id="right">right</button>
  <button id="rotate">rotate</button>
  <button id="fall">fall</button><!-- 下坠 -->
  <button id="fixed">fixed</button><!-- 固定 -->
  <button id="performNext">performNext</button><!-- 产生下一个 -->
  <button id="checkClear">checkClear</button><!-- 是否消行 -->
  <button id="gameover">gameover</button><!-- 游戏是否结束 -->
  <button id="settime">settime</button>
  <button id="addscore">addscore</button>
  <button id="gamestate">gamestate</button><!-- 游戏状态赢或输 -->
  <button id="addTaiLines">addTaiLines</button><!-- 底部增加一行 -->
  </div>
 </div>
 </div>
</body>
<script src="../js/square.js"></script>
<script src="../js/squareFactory.js"></script>
<script src="../js/game.js"></script>
<script src="../js/local.js"></script>
<script src="../js/remote.js"></script>
<script type="text/javascript" src="../js/Demo.js"></script>
 
</html>

css

.square{
 width: 400px;
 height: 500px;
 position: absolute;
 border: solid 1px red;
}
.title{
 width: 400px;
 text-align: center;
 margin: 0 auto;
}
.game{
 width: 200px;height: 400px;
 border-bottom: 1px solid blue; 
 border-right: 1px solid blue; 
 border-left: 1px solid blue; 
 position: absolute;
 background-color: #f2faff;
 top: 70px;
 left: 10px;
}
.next{
 width: 80px;height: 80px;
 position: absolute;top: 70px;left: 250px;
 border: solid 0px red;
}
.info{
 position: absolute;top: 170px;left: 250px;
 border: solid 0px red
}
 
.none,.current,.done{
 width: 20px;height: 20px;
 position: absolute;
 box-sizing: border-box;
}
 
 
.tip{
 width: 100px;
 position: absolute;
 top: 270px;
 left: 250px;
 font-size: 20px;
 color:red;
 border: solid 0px red;
}
 
 
.score{
 color:green;
}
/* 消失的方块 */
.none{
 background-color: #414141;
 border: solid 1px white
}
 
/* 正在操作的方块 */
.current{
 background-color: pink;
 border:solid 1px red;
}
 
/* 落下的方块 */
.done{
 background:#d2f028;
 border:solid 1px black
}
 
#remote{
 left: 500px;
}
 
.btn{
 width: 70px;
 border: solid 0px red
}

Demo.js

var local = new local();
local.start();
 
var remote = new Remote();
remote.start(2,2);
remote.bindEvents();

game.js

//核心逻辑 2
var Game = function(){
 //这两个div为游戏中的两个最大的容器盒子 dom元素
 var gameDiv;
 var nextDiv;
 var timeDiv;
 var scoreDiv;
 var local_tipDiv;
 //游戏界面框中的方块坐标
 var gameData=[
  [0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0],
 ]
 
 //装载所有的div的容器 数组
 //next中的div 
 var nextDivs = [];
 //游戏框中的div
 var gameDivs = [];
 
 //定义两个方块
 //当前方块
 var cur;
 //下一个方块
 var next;
 
 //渲染游戏框中的div
 /**
  * 
  * @param {*} container 最大容器 也就是这个div要被添加到容器
  * @param {*} data div的矩阵数据 
  * @param {*} divs 用于装载所有的div
  */
 var initDiv = function(container,data,divs){
  for(var i=0;i<data.length;i++){
   var DIV = [];
   for(var j=0;j<data[i].length;j++){
    var div = document.createElement("div");
    div.classList.add('none');
    div.style.top=i*20+"px";
    div.style.left=j*20+"px";
    container.appendChild(div);
    DIV.push(div);
   }
   divs.push(DIV)
  }
 };
 
 //刷新游戏界面的div 和提示下一个的div
 /**
  * 
  * @param {*} data div的矩阵数据
  * @param {*} divs 装载div的容器
  */
 var refresh = function(data,divs){
  for(var i = 0;i<data.length;i++){
   for(var j=0;j<data[i].length;j++){
    if(data[i][j]==0){
     divs[i][j].className = "none"
    }
    else if(data[i][j]==1){
     divs[i][j].className = "done"
    }
    else if(data[i][j]==2){
     divs[i][j].className = "current"
    }
   }
  }
 } ;
 
 
//初始化方法
 var init = function(doms,type,dir){
  gameDiv = doms.gameDiv;//游戏区域的大div
  nextDiv = doms.nextDiv;//提示区域的大div
  timeDiv = doms.timeDiv;//显示时间的div
  scoreDiv = doms.scoreDiv;//显示分数的dom
  local_tipDiv = doms.local_tip;//显示游戏状态
 
  //这里返回的是七种方块的其中一种 这些方块都继承square对象的成员
  next = squareFactory.prototype.make(type,dir);
 
  initDiv(gameDiv,gameData,gameDivs);
  initDiv(nextDiv,next.data,nextDivs);
  refresh(next.data,nextDivs);
  //console.log(gameData)
 };
 
 //下移
 this.down = function(){
  //这里是将isValue方法传入到canDown中 里canDown中判断下落的点是否合法
  if(cur.canDown(isValue)){ 
   //移动组合方块之前先清除数据 在重新添加
   clearGameData();
   //这里x加一 那么组合方块的初始下标位置变化加一 如从第十行开始 那么变化变成
   //第十一行
   cur.onDown(); //这里x轴控制的上下 y控制的是左右
   setData();
   refresh(gameData,gameDivs);
   //console.log(gameData);
   return true;
  }else{
   return false;
  } 
  //这里我们需要注意 若next提示框中的组合方块四周都有空位时 我们就算不清除
  //它也能正常移动 这是因为后来方块会替换现有的空位 而现有的空位便会
  //向下移动 
  //0 1 1 0
  //0 0 0 0
  //例如 我们若向右加一的话 那么它便会变成这样
  //0 0 1 1 这是因为它本来前面有个空位 所以加1后 后来的空位便会替换
  //原本1的位置 而原本1的位置由于加1了 所以也会整体向右移动
 };
 
 //左
 this.left = function(){
  if(cur.canLeft(isValue)){ 
   clearGameData();
   cur.onLeft(); 
   setData();
   refresh(gameData,gameDivs)
   //console.log(gameData)
  }
 };
 
 //右
 this.right = function(){
  if(cur.canRight(isValue)){ 
   clearGameData();
   cur.onRight(); 
   setData();
   refresh(gameData,gameDivs)
   //console.log(gameData)
  }
 };
 
 //上
 this.up = function(){
  if(cur.canRotate(isValue)){
   cur.onrotate();
   setData();
   refresh(gameData,gameDivs)
  }
 };
 
 //直接坠落
 //在内部调用自己用this引用的方法时 也要加上this
 this.fall = function(){ while( this.down() ); };
 
 
 //清除方块
 var clearGameData = function(){
  for(var i=0;i<cur.data.length;i++){
   for(var j=0;j<cur.data[i].length;j++){
    if(check(cur.origin,i,j))
    gameData[cur.origin.x+i][cur.origin.y+j] = 0
   }
  }
 };
 //用于设置当前组合方块的位置变化
 var setData = function(){ 
  //外循环四次 
  for(var i=0;i<cur.data.length;i++){
   //内循环四次
   for(var j=0;j<cur.data[i].length;j++){
    //将 square中的data矩阵的值赋给插入到gameData矩阵中的指定位置
    //例如 这里x为10 那么一级数组的开始位置下标就是 10+0
    //二级数组中的开始下标就是5+0 
    //也就是data[10+0][5+0]
    //第二次就是 data[10+1][5+1] 以此类推
    //这里注意一级数组控制的是上下 二级数组控制的是左右
    //也就是说 x轴是上下 y轴是左右
    if(check(cur.origin,i,j))
    gameData[cur.origin.x+i][cur.origin.y+j] = cur.data[i][j]
   }
  }
 };
 
 
//底部增加行
this.addTaiLines = function(lines){
 //lines为底部增加的行 例如line为2
 //将所有的方块往上移动两行
 // i=0;i<20 - 2;i++
 // gamedata[0] = gamedata[0+2] 例如从0开始 第一行就变成了第三行
 // gamedata[1] = gamedata[1+2] 第二行就变成了第四行
 // gamedata[2] = gamedata[2+2] 第三行就变成了第五行
 /**
  * 0 0 0 0 0 0 0 0 0 0 
  * 2 2 2 2 2 2 2 2 2 2
  * 2 2 2 2 2 2 2 2 2 2
  * 2 2 2 2 2 2 2 2 2 2
  */
 for(var i=0;i<gameData.length-lines.length;i++){
  gameData[i] = gameData[i+lines.length];
 }
 //再把所有底部增加的内容显示出来
 //i=0 i<2 i++
 //gamedata[20-2+0](18) = lines[0]
 //gamedata[20-2+1](19) = lines[1]
 for(var i=0;i<lines.length;i++){
  gameData[gameData.length-lines.length+i] = lines[i];
 }
 cur.origin.x-=lines.length;
 if(cur.origin.x<0){
  cur.origin.x = 0;
 }
 refresh(gameData,gameDivs);
}
 
//设置时间显示
this.setTime = function(times){
 timeDiv.innerText = "--"+times+"s";
}
 
 
this.gameState = function(win){
 if(win){
  local_tipDiv.innerText = "你赢了"
 }else{
  local_tipDiv.innerText = "你输了"
 }
}
 
 
//产生下一个方块
this.performNext = function(type,dir){
 //首先先将下一个方块赋值给当前操作的方块
 cur = next;
 //然后重新设置当前游戏区域的方块
 setData();
 //在显示提示下一个方块
 next = squareFactory.prototype.make(type,dir);
 //然后刷新游戏区和提示区
 refresh(gameData,gameDivs)
 refresh(next.data,nextDivs);
}
 
 
//消行
var Fraction = 0;
this.checkclear = function(){
 Fraction = 0;
 //从最后一行开始 判断是否全部为1 若为1 则表示那一行以及全部铺满
 //否则clear为false 并跳出当前循环 例如第一次 若19行没有铺满 则跳出循环
 for(var i=gameData.length-1;i>=0;i-=1){
  var clear = true;
  for(var j=0;j<gameData[0].length;j+=1){
   //gamedata[19][0]!=1
   //or
   //gamedata[19][1]!=1 ....
   if(gameData[i][j]!=1){
    clear = false;
    break;
   }
  }
  //若clear为true 说明这一行全部铺满
  if(clear){
   Fraction += 1;
   //例如 m=19;m>0;m--
   for(var m = i;m>0;m--){
    //n=0;n<10;n++ 注 gamedata为20 其中每一个数组的长度为10
    for(var n=0;n<gameData[0].length;n++){
     //例如 外循环第一次 
     //gamendata[19][0] = gamedata[19-1][0];
     //gamendata[19][1] = gamedata[19-1][1]; ....
     // 外循环第二次
     //gamendata[18][0] = gamedata[18-1][0];
     //gamendata[18][1] = gamedata[18-1][1]; ....
     gameData[m][n] = gameData[m-1][n];
     //将上一行的内容移动到下一行
    }
   }
   //n=0;n<10;n++
   for(var n=0;n<gameData[0].length;n++){
    //gamedata[0][0] = 0
    //gamedata[0][1] = 0
    //gamedata[0][2] = 0 ....
    gameData[0][n] = 0;
   }
   //i++的作用是让最下面一行被清除后 比如 19行铺满 我们便将18行往下移动一个行
   //然后在重新判断当前移动后的18行(也就是19行)是否铺满
   //因为每次循环完成后 i都会-1 如果底层没有铺满我们便正常循环 如果底层铺满
   //我们便重头开始检测
   console.log("当前i",i)
   i++;
  }
 }
 addscore(Fraction)
}
 
var score = 0;
var addscore = function(scoreCount){
 switch(scoreCount){
  case 1:
   score +=10;
   break;
  case 2:
   score +=30;
   break;
  case 3:
   score +=50;
   break;
  case 4:
   score +=100;
   break;
 }
 scoreDiv.innerText = "--"+score;
}
 
 
 
//游戏结束
this.gameover = function(){
 var over = false;
 for(var i=0;i<gameData[0].length;i++){
  if(gameData[1][i]==1){//若第二行以及有落下的方块 那么游戏便结束
   over = true;
  }
 }
 return over;
}
 
 /**
  * 
  * @param {*} pos 等于当前方块的x 和 y的原点
  * @param {*} x 等于当前方块的上下位置的变化值
  * @param {*} y 左右位置的变化值
  */
 //判断当前是否可以移动
 var check = function(pos,x,y){
  if(pos.x+x < 0){return false}
  else if(pos.x+x >= gameData.length){return false}
  else if(pos.y+y < 0){return false}
  else if(pos.y+y >= gameData[0].length){return false}
  //这里是判断如果我们落下的这个位置已经有一个方块的话 那也不合法
  //若这个方块已经落下 我们便判定它的矩阵数据为1
  else if(gameData[pos.x+x][pos.y+y]==1){return false}
  else{return true}
 };
 /*
  10 + 0 > length ?
  10 + 1 > length ?
 0 0 1 0 0 5 + 1 > length ? 
 1 0 1 0 0 
 2 0 1 1 0
 3 0 0 0 0
  0 1 2 3 
 */
 
 
//让当前方块变得不可移动
this.fixed = function(){
 for(var i=0;i<cur.data.length;i++){//0 1 2 3
  for(var j=0;j<cur.data[0].length;j++){//0 1 2 3
   if(check(cur.origin,i,j)){
    //若当前方块的值是 2 也就是说还处于操作状态的话
    //我们便将它赋值为 1 因为2等于操作中的方块 1等于以及落下的方块
    //而以及落下的方块是不可以移动 这个判断是写在check方法中的
    if(gameData[cur.origin.x+i][cur.origin.y+j]==2){
     gameData[cur.origin.x+i][cur.origin.y+j] = 1;
    }
   }
  }
 }
 refresh(gameData,gameDivs);
}
 
 //检测当前next中的矩阵数据是否合法
 /**
  * 
  * @param {*} pos 当前方块的原点
  * @param {*} nextdata next中方块矩阵
  */
 var isValue = function(pos,nextdata){
  for(var i = 0;i<nextdata.length;i++){
   for(var j=0;j<nextdata[0].length;j++){
    //判断当前next的矩阵数据中的每一个位置是否等于0
    //若不等于0则判断当前的点是否还能继续下降
    if(nextdata[i][j]!==0){
     //若不能 则直接返回false
     if(!check(pos,i,j))return false;
    }
   }
  }
  //若都没有问题则返回true
  return true;
 }
 
 
 //将这个init导出 因为这里这个init是一个私有的方法
 this.init = init;
 this.addscore = addscore;
};

local.js

//我的游戏区域 1
var local = function(){
 // 先声明游戏对象
 var game;
 
 //定义定时器时间间隔
 var INTERVAL = 500;
 
 //定义定时器
 var time = null;
 
 //计算时间
 var timeCount = 0;
 var times = 0;
 
 //定义一个start开始方法
 this.start = function(){
  //获取游戏中两个界面的dom元素
  var dom = {
   gameDiv:document.querySelector("#local_game"),
   nextDiv:document.querySelector("#local_next"),
   timeDiv:document.querySelector("#local_time"),
   scoreDiv:document.querySelector("#local_score"),
   local_tip:document.querySelector("#local_tip")
  };
  //实例化Game;
  game = new Game();
  //并将dom传入到Game的初始化方法中
  game.init(dom,generateType(),generateDir());
  //产生初始方块
  game.performNext(generateType(),generateDir());
  bindKeyEvent();
  //游戏开始时定义一个定时器 让方块自动下移
  time = setInterval(move,INTERVAL);
 };
 
 function move(){
  //时间计数
  timeFunc();
 
  if(!game.down()){
   game.fixed();
   //判断是否消行
   game.checkclear();
 
   //判断是否结束游戏
   if(game.gameover()){
    stop();
    game.gameState(false);
   }else{
    //当当前方块已经落到底部后 我们便产生下一个方块
    game.performNext(generateType(),generateDir())
   }
  }
 }

 var timeFunc = function(){
  //计算秒数 因为每过500毫秒会调用一次
  timeCount+=1;
  if(timeCount==2){
   timeCount = 0;
   times += 1;
   //设置显示时间
   game.setTime(times);
  }
 
  if(times%5==0){
   // game.addTaiLines(generrateBottomLine(1));
  }
 }

 //随机生成干扰行
 /**
  * 
  * @param {*} linenum 生成干扰行的行数
  */
 var generrateBottomLine = function(linenum){
  //定义一个二维数组
  var lines = [];
  for(var i=0;i<linenum;i++){
   //二维数组中的一维数组
   var line = [];
   for(var j=0;j<10;j++){
    //随机生成0-2的数
    line.push(Math.ceil(Math.random()*2)-1);
   }
   lines.push(line);
  }
  return lines;
 }
 
 //产生一个随机数 代表着方块的种类
 function generateType(){
  //产生0-6的整数
  return Math.ceil(Math.random()*7)-1
 }
 
 //产生一个随机数 代表方块旋转的方向
 function generateDir(){
  //产生0-6的整数
  return Math.ceil(Math.random()*4)-1
 }
 
 //游戏结束
 function stop(){
  if(time){
   clearInterval(time)
   time = null;
  }
  document.onkeydown = null;
 }
 
 //声明键盘事件
 var bindKeyEvent = function(){
  document.onkeydown = function(e){
   switch(e.keyCode){
    case 38: //up
     game.up();
    break;
    case 39: //right
     game.right();
    break;
    case 40: //down 
     game.down();
    break;
    case 37: //left
     game.left();
    break;
    case 32: //space
     game.fall();
    break;
   }
  }
 }
 
}

remote.js

//对方游戏区域
//这个js主要为对方的操作意识
var Remote = function(){
 //游戏对象
 var game;
 //开始 决定方块类型 和旋转方向
 var start = function(type,dir){
  //获取游戏中两个界面的dom元素
  var dom = {
   gameDiv:document.querySelector("#remote_game"),
   nextDiv:document.querySelector("#remote_next"),
   timeDiv:document.querySelector("#remote_time"),
   scoreDiv:document.querySelector("#remote_score"),
   local_tip:document.querySelector("#remote_tip")
  };
  //实例化Game;
  game = new Game();
  //并将dom传入到Game的初始化方法中
  game.init(dom,type,dir);
 };
 
 //绑定事件
 var bindEvents = function(){
  document.querySelector("#left").onclick = function(){
   game.left();
  }
  document.querySelector("#right").onclick = function(){
   game.right();
  }
  document.querySelector("#down").onclick = function(){
   game.down();
  }
  document.querySelector("#rotate").onclick = function(){
   game.up();
  }
  document.querySelector("#fall").onclick = function(){
   game.fall();
  }
  document.querySelector("#fixed").onclick = function(){
   game.fixed();
  }
  document.querySelector("#performNext").onclick = function(){
   game.performNext(2,2);
  }
  document.querySelector("#checkClear").onclick = function(){
   game.checkclear();
  }
  document.querySelector("#gameover").onclick = function(){
   game.gameover();
  }
  document.querySelector("#settime").onclick = function(){
   game.setTime(20);
  }
  document.querySelector("#addscore").onclick = function(){
   game.addscore(3);
  }
  document.querySelector("#gamestate").onclick = function(){
   game.gameState(true);
  }
  document.querySelector("#addTaiLines").onclick = function(){
   game.addTaiLines([[1,0,0,1,0,1,0,1,1,1]]);
  }
 }
 
 //导出方法
 this.start = start;
 this.bindEvents = bindEvents;
}

square.js

//所有的方块的公共逻辑 3
var square = function(){
 //方块提示框中的方块数据
 this.data = [
  [0,0,0,0],
  [0,0,0,0],
  [0,0,0,0],
  [0,0,0,0]
 ];
 this.dir = 0;
 
 //方块坐标原点
 this.origin={
  x:0,
  y:0
 }
};
 
//检测当前矩阵数据中的方块位置能否下降
square.prototype.canDown=function(isvalue){
 var test = {};
 //console.log(this.origin.x,this.origin.x + 1);
  //这里要加1的原因是因为 这个方法是在我们还没有执行到加1程序之前调用的
  //所以我们需要手动给它去加1
 test.x = this.origin.x + 1;
 test.y = this.origin.y;
 return isvalue(test,this.data);
};
 
square.prototype.canLeft=function(isvalue){
 var test = {};
 test.x = this.origin.x;
 test.y = this.origin.y - 1;
 return isvalue(test,this.data);
};
 
square.prototype.canRight=function(isvalue){
 var test = {};
 test.x = this.origin.x;
 test.y = this.origin.y + 1;
 return isvalue(test,this.data);
};
 
//下落方法 这个方法我们放到原型对象上 因为下落方法是主要的方法
square.prototype.onDown = function(){
 this.origin.x += 1;
};
 
square.prototype.onLeft = function(){
 this.origin.y -= 1;
};
 
square.prototype.onRight = function(){
 this.origin.y += 1;
};
 
 
//下面是旋转的功能
square.prototype.canRotate = function(isvalue){
 var testdir = (this.dir + 1)%4;//因为是在旋转指向前进行的判断 所以我们先加1
 var testrotate = [
  [0,0,0,0],
  [0,0,0,0],
  [0,0,0,0],
  [0,0,0,0]
 ];
 for(var i=0;i<this.data.length;i++){
  for(var j=0;j<this.data[i].length;j++){
   testrotate[i][j] = this.rotate[testdir][i][j]
  }
 }
 return isvalue(this.origin,testrotate);
};
 
square.prototype.onrotate = function(num){
 num = num|1;
 this.dir = (this.dir+num)%4;//因为是在旋转指向前进行的判断 所以我们先加1
 for(var i=0;i<this.data.length;i++){
  for(var j=0;j<this.data[i].length;j++){
   this.data[i][j] = this.rotate[this.dir][i][j]
  }
 }
};

squareFactory.js

//工厂 用于生成不同的方块
//所有的方块的公共逻辑 3
var square1 = function(){
 //这样写 当我们实例化square1的时候 square中this引用的成员将会添加到square1上
 square.call(this);
 //四个不同的旋转方向 默认是0 也就是第一个
 this.rotate = [
  [
   [0,2,0,0],
   [0,2,0,0],
   [0,2,2,0],
   [0,0,0,0]
  ],
  [
   [0,0,0,0],
   [2,2,2,0],
   [2,0,0,0],
   [0,0,0,0]
  ],
  [
   [2,2,0,0],
   [0,2,0,0],
   [0,2,0,0],
   [0,0,0,0]
  ],
  [
   [0,0,2,0],
   [2,2,2,0],
   [0,0,0,0],
   [0,0,0,0]
  ]
 ];
};
square1.prototype = square.prototype;//打通原型链
 
 
var square2 = function(){
 //这样写 当我们实例化square1的时候 square中this引用的成员将会添加到square1上
 square.call(this);
 //四个不同的旋转方向 默认是0 也就是第一个
 this.rotate = [
  [
   [0,2,0,0],
   [0,2,0,0],
   [0,2,0,0],
   [0,2,0,0]
  ],
  [
   [0,0,0,0],
   [2,2,2,2],
   [0,0,0,0],
   [0,0,0,0]
  ],
  [
   [0,2,0,0],
   [0,2,0,0],
   [0,2,0,0],
   [0,2,0,0]
  ],
  [
   [0,0,0,0],
   [2,2,2,2],
   [0,0,0,0],
   [0,0,0,0]
  ]
 ];
};
square2.prototype = square.prototype;
 
var square3 = function(){
 //这样写 当我们实例化square1的时候 square中this引用的成员将会添加到square1上
 square.call(this);
 //四个不同的旋转方向 默认是0 也就是第一个
 this.rotate = [
  [
   [0,2,0,0],
   [2,2,2,0],
   [0,0,0,0],
   [0,0,0,0]
  ],
  [
   [2,2,2,0],
   [0,2,0,0],
   [0,0,0,0],
   [0,0,0,0]
  ],
  [
   [0,2,0,0],
   [2,2,0,0],
   [0,2,0,0],
   [0,0,0,0]
  ],
  [
   [2,0,0,0],
   [2,2,0,0],
   [2,0,0,0],
   [0,0,0,0]
  ]
 ];
};
square3.prototype = square.prototype;
 
var square4 = function(){
 //这样写 当我们实例化square1的时候 square中this引用的成员将会添加到square1上
 square.call(this);
 //四个不同的旋转方向 默认是0 也就是第一个
 this.rotate = [
  [
   [2,2,0,0],
   [2,2,0,0],
   [0,0,0,0],
   [0,0,0,0]
  ],
  [
   [2,2,0,0],
   [2,2,0,0],
   [0,0,0,0],
   [0,0,0,0]
  ],
  [
   [2,2,0,0],
   [2,2,0,0],
   [0,0,0,0],
   [0,0,0,0]
  ],
  [
   [2,2,0,0],
   [2,2,0,0],
   [0,0,0,0],
   [0,0,0,0]
  ]
 ];
};
square4.prototype = square.prototype;
 
var square5 = function(){
 //这样写 当我们实例化square1的时候 square中this引用的成员将会添加到square1上
 square.call(this);
 //四个不同的旋转方向 默认是0 也就是第一个
 this.rotate = [
  [
   [0,0,0,0],
   [2,2,0,0],
   [0,2,2,0],
   [0,0,0,0]
  ],
  [
   [0,0,2,0],
   [0,2,2,0],
   [0,2,0,0],
   [0,0,0,0]
  ],
  [
   [0,0,0,0],
   [0,2,2,0],
   [2,2,0,0],
   [0,0,0,0]
  ],
  [
   [2,0,0,0],
   [2,2,0,0],
   [0,2,0,0],
   [0,0,0,0]
  ]
 ];
};
square5.prototype = square.prototype;
 
var square6 = function(){
 //这样写 当我们实例化square1的时候 square中this引用的成员将会添加到square1上
 square.call(this);
 //四个不同的旋转方向 默认是0 也就是第一个
 this.rotate = [
  [
   [0,2,0,0],
   [0,2,2,2],
   [0,0,0,0],
   [0,0,0,0]
  ],
  [
   [0,0,2,0],
   [0,0,2,0],
   [0,2,2,0],
   [0,0,0,0]
  ],
  [
   [2,2,2,0],
   [0,0,2,0],
   [0,0,0,0],
   [0,0,0,0]
  ],
  [
   [0,2,2,0],
   [0,2,0,0],
   [0,2,0,0],
   [0,0,0,0]
  ]
 ];
};
square6.prototype = square.prototype;
 
var square7 = function(){
 //这样写 当我们实例化square1的时候 square中this引用的成员将会添加到square1上
 square.call(this);
 //四个不同的旋转方向 默认是0 也就是第一个
 this.rotate = [
  [
   [2,2,0,0],
   [2,2,0,0],
   [2,2,0,0],
   [2,2,0,0]
  ],
  [
   [0,0,0,0],
   [2,2,2,2],
   [2,2,2,2],
   [0,0,0,0]
  ],
  [
   [2,2,0,0],
   [2,2,0,0],
   [2,2,0,0],
   [2,2,0,0]
  ],
  [
   [0,0,0,0],
   [2,2,2,2],
   [2,2,2,2],
   [0,0,0,0]
  ]
 ];
};
square7.prototype = square.prototype;
 
var squareFactory = function(){};
squareFactory.prototype.make=function(index,dir){
 var s;
 index+=1;
 switch (index) {
  case 1:
   s = new square1();
   break;
  case 2:
   s = new square2();
   break;
  case 3:
   s = new square3();
   break;
  case 4:
   s = new square4();
   break;
  case 5:
   s = new square5();
   break;
  case 6:
   s = new square6();
   break;
  case 7:
   s = new square7();
   break;
  default:
   break;
 }
 //因为一来square中的data矩阵默认全是0 所以我们需要给它一个旋转方向
 //让它有一个形状
 console.log(index,s);
 s.origin.x = 0;
 s.origin.y = 3;
 s.onrotate(dir);
 return s;
};

更多有趣的经典小游戏实现专题,分享给大家:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
理解Javascript_12_执行模型浅析
Oct 18 Javascript
jquery下异步提交表单 异步跨域提交表单
Nov 17 Javascript
jQuery弹出层始终垂直居中相对于屏幕或当前窗口
Apr 01 Javascript
javascript在myeclipse中报错的解决方法
Oct 29 Javascript
JavaScript实现自动变换表格边框颜色
May 08 Javascript
jQuery仅用3行代码实现的显示与隐藏功能完整实例
Oct 08 Javascript
VUEJS实战之构建基础并渲染出列表(1)
Jun 13 Javascript
JavaScript实现刷新不重记的倒计时
Aug 10 Javascript
Angularjs实现搜索关键字高亮显示效果
Jan 17 Javascript
jQuery实现的简单悬浮层功能完整实例
Jan 23 Javascript
从零开始做一个pagination分页组件
Mar 15 Javascript
Jquery Fade用法详解
Nov 06 jQuery
React实现评论的添加和删除
Oct 20 #Javascript
基于JavaScript实现简单抽奖功能代码实例
Oct 20 #Javascript
微信小程序使用前置摄像头拍照
Oct 22 #Javascript
jQuery实现可以计算进制转换的计算器
Oct 19 #jQuery
jQuery实现计算器功能
Oct 19 #jQuery
vue3为什么要用proxy替代defineProperty
Oct 19 #Javascript
jQuery实现推拉门效果
Oct 19 #jQuery
You might like
一步一步学习PHP(4) php 函数 补充2
2010/02/15 PHP
PHP 反向排序和随机排序代码
2010/06/30 PHP
php全排列递归算法代码
2012/10/09 PHP
thinkphp特殊标签用法概述
2014/11/24 PHP
腾讯微博提示missing parameter errorcode 102 错误的解决方法
2014/12/22 PHP
PHP使用Memcache时模拟命名空间及缓存失效问题的解决
2016/02/27 PHP
JQuery $.each遍历JavaScript数组对象实例
2014/09/01 Javascript
Javascript this 关键字 详解
2014/10/22 Javascript
嵌入式iframe子页面与父页面js通信的方法
2015/01/20 Javascript
JavaScript实现文本框中默认显示背景图片在获得焦点后消失的方法
2015/07/01 Javascript
jq源码解析之绑在$,jQuery上面的方法(实例讲解)
2017/10/13 jQuery
解决vue-cli3 使用子目录部署问题
2018/07/19 Javascript
angularJs select绑定的model取不到值的解决方法
2018/10/08 Javascript
微信小程序如何修改radio和checkbox的默认样式和图标
2019/07/24 Javascript
jquery将信息遍历到界面上实例代码
2020/01/21 jQuery
javascript实现简易数码时钟
2020/03/30 Javascript
JQuery Ajax如何实现注册检测用户名
2020/09/25 jQuery
[01:09:20]NB vs NAVI Supermajor小组赛A组 BO3 第二场 6.2
2018/06/03 DOTA
Python 常用string函数详解
2016/05/30 Python
python enumerate函数的使用方法总结
2017/11/15 Python
Windows下anaconda安装第三方包的方法小结(tensorflow、gensim为例)
2018/04/05 Python
python实现键盘控制鼠标移动
2020/11/27 Python
Python控制Firefox方法总结
2019/06/03 Python
CSS3弹性盒模型开发笔记(三)
2016/04/26 HTML / CSS
HTML5如何实现元素拖拽
2016/03/11 HTML / CSS
美国著名的团购网站:Woot
2016/08/02 全球购物
goodhealth官方海外旗舰店:新西兰国民营养师
2017/12/15 全球购物
美国排名第一的葡萄酒俱乐部:Firstleaf Wine Club
2020/01/02 全球购物
一套英文Java笔试题面试题
2016/04/21 面试题
大学新生军训个人的自我评价
2013/10/03 职场文书
开票员岗位职责
2015/02/12 职场文书
体育委员竞选稿
2015/11/21 职场文书
JavaScript如何优化逻辑判断代码详解
2021/06/08 Javascript
mysql如何配置白名单访问
2021/06/30 MySQL
MySQL多表查询机制
2022/03/17 MySQL
Python简易开发之制作计算器
2022/04/28 Python