原生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 相关文章推荐
鼠标放在图片上显示大图的JS代码
Mar 26 Javascript
jQuery实现的导航条切换可显示隐藏
Oct 22 Javascript
如何让你的Lightbox支持滚轮缩放及Base64图片
Dec 04 Javascript
jQuery实现带滚动线条导航效果的方法
Jan 30 Javascript
js实现网页右上角滑出会自动消失大幅广告的方法
Feb 27 Javascript
JS处理数据四舍五入(tofixed与round的区别详解)
Oct 26 Javascript
新手必须知的Node.js 4个JavaScript基本概念
Sep 16 Javascript
记一次vue-webpack项目优化实践详解
Feb 17 Javascript
vuex根据不同的用户权限展示不同的路由列表功能
Sep 20 Javascript
vue使用nprogress实现进度条
Dec 09 Javascript
vue 实现锚点功能操作
Aug 10 Javascript
JS创建或填充任意长度数组的小技巧汇总
Oct 24 Javascript
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页面间传递参数实例代码
2008/06/05 PHP
Thinkphp实现MySQL读写分离操作示例
2014/06/25 PHP
PHP生成压缩文件实例
2015/02/07 PHP
php计算一个文件大小的方法
2015/03/30 PHP
PHP用反撇号执行外部命令
2015/04/14 PHP
php之可变函数的实例详解
2017/09/13 PHP
PHP基于递归算法解决兔子生兔子问题
2018/05/11 PHP
javascript中方便增删改cookie的一个类
2012/10/11 Javascript
jQuery $.data()方法使用注意细节
2012/12/31 Javascript
Javascript中对象继承的实现小例
2014/05/12 Javascript
javascript实现分栏显示小技巧附图
2014/10/13 Javascript
node.js中的fs.futimesSync方法使用说明
2014/12/17 Javascript
html的DOM中document对象anchors集合用法实例
2015/01/21 Javascript
javascript操作select元素实例分析
2015/03/27 Javascript
JavaScript实现算术平方根算法-代码超简单
2015/09/11 Javascript
微信小程序 教程之模块化
2016/10/17 Javascript
详解如何在微信小程序中愉快地使用sass
2018/07/30 Javascript
解决vue单页路由跳转后scrollTop的问题
2018/09/03 Javascript
jQuery与原生JavaScript选择HTML元素集合用法对比分析
2019/11/26 jQuery
JavaScript实现多层颜色选项卡嵌套
2020/09/21 Javascript
JavaScript使用setTimeout实现倒计时效果
2021/02/19 Javascript
[08:02]DOTA2牵红线 zhou神抱得美人归
2014/03/22 DOTA
[34:41]夜魇凡尔赛茶话会 第二期02:你画我猜
2021/03/11 DOTA
全面了解Python环境配置及项目建立
2016/06/30 Python
Python设计模式之工厂模式简单示例
2018/01/09 Python
python判断输入日期为第几天的实例
2018/11/13 Python
CSS3 Flexbox中flex-shrink属性的用法示例介绍
2013/12/30 HTML / CSS
利用 CSS3 实现的无缝轮播功能代码
2017/09/25 HTML / CSS
HTML5实现页面切换激活的PageVisibility API使用初探
2016/05/13 HTML / CSS
皇家道尔顿官网:Royal Doulton
2017/12/06 全球购物
俄罗斯品牌服装和鞋子在线商店:BRIONITY
2020/03/26 全球购物
struct和class的区别
2015/11/20 面试题
校园摄影活动策划方案
2014/02/05 职场文书
助学金感谢信
2015/01/20 职场文书
行政申诉状范文
2015/05/20 职场文书
Python图片处理之图片裁剪教程
2021/05/27 Python