欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JS和canvas實(shí)現(xiàn)俄羅斯方塊

 更新時間:2017年03月14日 10:58:39   作者:yuandaishi  
本文主要介紹了JS和canvas實(shí)現(xiàn)俄羅斯方塊的實(shí)例。具有很好的參考價值。下面跟著小編一起來看下吧

效果圖:

代碼如下:

<!DOCTYPE html>
<html>
 <head>
 <meta charset="UTF-8">
 <title></title>
 </head>
 <body>
 <p style="font-size: 20px;">鍵盤箭頭A,D控制左右移動,S控制快速下滑。W控制變形,空格控制暫停,enter開始游戲</p>
 <div id="box" style="width: 1000px;height: 800px;border: 1px solid pink;margin: 0 auto;position: relative;">
 </div>
 </body>
<script type="text/javascript">
shape_collection = {//圖形順時針旋轉(zhuǎn)變形,感覺有點(diǎn)麻煩,這里還應(yīng)該加一個參數(shù)--距離左右多少格的時候不能變形,有利于后續(xù)圖形的拓展,但是這里就先不寫了
 s1: [
 {
  mo: [
  [0, 0, 0, 0],
  [0, 0, 0, 0],
  [0, 0, 0, 0],
  [1, 1, 1, 1]
  ],
  l:true,//通過這兩個參數(shù),判斷左右碰撞能否變形
  r:true
 },
 {//與左邊,右邊碰撞,都不能變形(距離右邊一格的時候,也不能變形)
  mo: [
  [0, 1, 0, 0],
  [0, 1, 0, 0],
  [0, 1, 0, 0],
  [0, 1, 0, 0]
  ] ,
  l:false,
  r:false
 }
 ],
 s2: [
 {
  mo: [//始終不變形
  [1, 1, 0, 0],
  [1, 1, 0, 0],
  [0, 0, 0, 0],
  [0, 0, 0, 0]
  ],
  l:false,
  r:false
 }
 ],
 s3: [
 {
  mo: [//右邊不能變形
  [1, 0, 0, 0],
  [1, 1, 0, 0],
  [0, 1, 0, 0],
  [0, 0, 0, 0]
  ],
  l:true,
  r:false
 },
 {
  mo: [
  [0, 0, 0, 0],
  [0, 1, 1, 0],
  [1, 1, 0, 0],
  [0, 0, 0, 0]
  ],
  l:true,
  r:true
 }
 ],
 s4: [
 {
  mo: [//右邊不能變形
  [0, 1, 0, 0],
  [1, 1, 0, 0],
  [1, 0, 0, 0],
  [0, 0, 0, 0]
  ],
  l:true,
  r:false
 },
 {
  mo: [
  [0, 0, 0, 0],
  [1, 1, 0, 0],
  [0, 1, 1, 0],
  [0, 0, 0, 0]
  ],
  l:true,
  r:true
 }
 ],
 s5: [
 {
  mo: [//右邊不能變形,左邊可以變形
  [1, 0, 0, 0],
  [1, 0, 0, 0],
  [1, 1, 0, 0],
  [0, 0, 0, 0]
  ],
  l:true,
  r:false
 },
 {
  mo: [//
  [0, 0, 0, 0],
  [1, 1, 1, 0],
  [1, 0, 0, 0],
  [0, 0, 0, 0]
  ],
  l:true,
  r:true
 },
 {
  mo: [//右邊不能變形
  [1, 1, 0, 0],
  [0, 1, 0, 0],
  [0, 1, 0, 0],
  [0, 0, 0, 0]
  ],
  l:true,
  r:false
 },
 {
  mo: [
  [0, 0, 0, 0],
  [0, 0, 1, 0],
  [1, 1, 1, 0],
  [0, 0, 0, 0]
  ],
  l:true,
  r:true
  }
 ],
 s6: [
 {
  mo: [//右邊不能變形,左邊可以變形
  [0, 1, 0, 0],
    [0, 1, 0, 0],
    [1, 1, 0, 0],
    [0, 0, 0, 0]
  ],
  l:true,
  r:false
  },
 {
  mo: [//
  [0, 0, 0, 0],
  [1, 0, 0, 0],
  [1, 1, 1, 0],
  [0, 0, 0, 0]
  ],
  l:true,
  r:true
 },
 {
  mo: [//右邊不能變形
  [1, 1, 0, 0],
  [1, 0, 0, 0],
  [1, 0, 0, 0],
  [0, 0, 0, 0]
  ],
  l:true,
  r:false
 },
 {
  mo: [
  [0, 0, 0, 0],
  [1, 1, 1, 0],
  [0, 0, 1, 0],
  [0, 0, 0, 0]
  ],
  l:true,
  r:true
 }
 ],
 s7: [
 {
  mo: [//
  [0, 0, 0, 0],
    [0, 1, 0, 0],
    [1, 1, 1, 0],
    [0, 0, 0, 0]
  ],
  l:true,
  r:true
 },
 {
  mo: [//右邊不能變形
  [1, 0, 0, 0],
  [1, 1, 0, 0],
  [1, 0, 0, 0],
  [0, 0, 0, 0]
  ],
  l:true,
  r:false
 },
 {
  mo: [//
  [0, 0, 0, 0],
  [1, 1, 1, 0],
  [0, 1, 0, 0],
  [0, 0, 0, 0]
  ],
  l:true,
  r:true
 },
 {
  mo: [//右邊不能變形
  [0, 1, 0, 0],
  [1, 1, 0, 0],
  [0, 1, 0, 0],
  [0, 0, 0, 0]
  ],
  l:true,
  r:false
 }
 ],
}
</script>
<script type="text/javascript">
;(function(){
 var tetris=function(a){
 var _this=this;
 this.settings={
  dom:"",
  side_length:25,//方塊邊長
  row:20,//行數(shù)
  col:15,//列數(shù)
  v_dowm:10,
  side_width:1//分隔線條寬度默認(rèn)為1
 };
 var k=this.extend(a,this.settings);
 var dom=document.getElementById(this.settings.dom);
 var fall_2=undefined;//用于判斷快速下落
 var score=0;//分?jǐn)?shù)
 this.p_dom(dom,"初始級別:");
 this.p_dom(dom,"分?jǐn)?shù):","score");
 var score_dom=dom.getElementsByClassName("score")[0];
 score_dom.style.cssText="position:absolute;left: 0;right: 0;top: 30px;margin: auto auto;text-align: center;";
 var score_num=document.createElement("span");
 score_num.className="score_num";
 score_num.style.cssText="color:gold;font-size: 30px;";
 score_num.innerText=score;
 score_dom.appendChild(score_num);
 this.input_dom(dom,4);
 var start_con=false;//是否開始游戲
 var shape =shape_collection;//各種形狀,這是一種思路,也很利于以后形狀的添加
 var shape_key=_this.obj_list(shape);//[s1,s2,s3,s4,s5,s6,s7]
 var color=["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"];//顏色
 var cube_arr=[];//用來裝建造區(qū)域小方塊
 var cube_arr_s=[];//用來裝提示圖形區(qū)域小方塊
 var shape_arr={//用來表示下落的滑塊
  shape_solo:undefined,//s1——s7中某一個的某一個圖形
  solo_key:undefined,//shape_solo的key值
  mo_list:undefined,//繪制的圖形在數(shù)組shape_solo的下標(biāo),變換圖形的時候用到
  serial:[],//小方塊坐標(biāo)集合,默認(rèn)為空,不繪制小塊。繪制小方塊的參考,重要參數(shù)
  re_point_x:(_this.settings.col/2)|0,//以第幾個為初始參考X坐標(biāo)(用于左右移動)
  re_point_y:0,//y坐標(biāo)參考。(不要在serial里面修改值,serial總在4X4里面,容易做參考)
  width:_this.settings.side_length,//小方塊的寬度
v:_this.settings.side_length+_this.settings.side_width,//每次移動的距離等于方塊邊長+grid線寬
  collision_l:false,//與左邊是否碰撞
  collision_r:false,//與右邊是否碰撞
  collision_d:false,//與下邊是否碰撞
  draw:function(a){//繪制小方塊函數(shù),寫在這里,才是這個對象的私有方法,而_proto_的寫法是所有對象都擁有
   var se=this.serial;
   //console.log(se)
   for(var i=0;i<se.length;i++){
   a.beginPath();
   a.fillStyle=se[0][2];//this指向這個對象.第三個參數(shù)是顏色
   a.fillRect(this.v*(this.re_point_x+se[i][0]),this.v*(this.re_point_y+se[i][1]),this.width,this.width);
   }
  }
 };
 //創(chuàng)建提示圖形
 var ts="ts";//提示圖形ID;
 this.canvas_dom(dom,this.settings.side_length,4,4,this.settings.side_width);
 var canvas_s=dom.getElementsByTagName("canvas")[0];
 canvas_s.setAttribute("style","position: absolute;right: 130px;border:3px solid goldenrod;top: 82px;")
 var ctx_s=canvas_s.getContext("2d");
 var cube_obj_s=_this.cube_obj_arr(ctx_s,this.settings.side_length,4,4,this.settings.side_width,cube_arr_s);
 var shape_arr_s=this.clone_obj(this.draw_shape(ts,shape,shape_arr,shape_key,_this.make_color(color)));//因?yàn)榉祷氐氖莝hape_arr,所以這里導(dǎo)致了shape_arr_s和shape_arr有關(guān)聯(lián),也就是說以后的代碼中,其中一個改變的話,另一個也會跟著改變,用clone方法去掉關(guān)聯(lián)
 cube_obj_s.forEach(function(e){
  e.draw(ctx_s);
 });
 shape_arr_s.draw(ctx_s);
 //創(chuàng)建堆砌圖形
 var dq="dq";//堆砌圖形ID;
 this.canvas_dom(dom,this.settings.side_length,this.settings.row,this.settings.col,this.settings.side_width);
 var canvas=dom.getElementsByTagName("canvas")[1];
 var ctx=canvas.getContext("2d");
 var cube_obj=_this.cube_obj_arr(ctx,this.settings.side_length,this.settings.row,this.settings.col,this.settings.side_width,cube_arr);
 //this.grid(ctx,this.settings.side_length,this.settings.row,this.settings.col,this.settings.side_width);//網(wǎng)格
 //console.log(cube_obj);
 cube_obj.forEach(function(e){
  e.draw(ctx);
 });
 var shape_arr_t=this.clone_obj(this.draw_shape(ctx,shape,shape_arr,shape_key,_this.make_color(color)));
 //console.log(shape_arr);
 shape_arr_t.draw(ctx);
 //鼠標(biāo)事件
 window.onkeydown=function(e){
  switch (e.keyCode){
  case 87://up
   up();
   break;
  case 83://down
   //down();
   break;
  case 65://left
   left();
   break; 
  case 68://right
   right()
   break;
  case 32://workspace
   //up();
   break; 
  case 13://enter
   enter();
   break; 
  default:
   break;
  }
 };
 window.onkeypress=function(e){//onkeypress和onkeydown,即使按下的是同一個按鍵,e.keyCode也不一樣
  if(start_con){ 
  switch (e.keyCode){
   case 115:
   if(fall_2==undefined){//做這個判斷是為了防止快速的點(diǎn)擊S鍵時,出現(xiàn)的多次fall_2事件,因?yàn)?0ms之后,fall_2的值才變成undefined
    fall_2=setInterval(fall,10);//clearInterval返回的值是undefined,而setInterval返回的值是一個整數(shù)
    setTimeout(function(){
    fall_2=clearInterval(fall_2);//重置fall_2的值為undefined
    },50);
   }
   break;
   default:
   break;
  }
  }
 }
 function up(){//shape和shape_arr的關(guān)系要弄清楚,這里判斷有點(diǎn)復(fù)雜
  if(start_con){
  ctx.clearRect(0,0,canvas.width,canvas.height);//清屏
  cube_obj.forEach(function(e){//重新繪制虛擬小方塊
   e.draw(ctx);
  })
  var l=shape[shape_arr_t["solo_key"]].length-1;//數(shù)組長度減1
  var i_list=shape_arr_t["mo_list"];//對應(yīng)數(shù)組的key
  var re_point_x=shape_arr_t["re_point_x"];
  var con_l=shape_arr_t["shape_solo"].l;
  var con_r=shape_arr_t["shape_solo"].r;
  var con_l_l=false;//用于判斷左右是否有con為1的虛擬滑塊,不僅僅要判斷是否碰到邊上,還要判斷這個
  var con_r_r=false;
  var con_suxian=false;//豎線
  var arr_se=[];
  var k_uni=shape_arr_t["serial"].length;
  for(var i_uni=0;i_uni<k_uni;i_uni++){//取出圖形所有小塊的橫坐標(biāo),這里有兩個for循環(huán),相同的變量會互相影響,所有設(shè)置成i_uni
   arr_se.push(shape_arr_t["serial"][i_uni][0]);
  }
  var min_coor=Math.min.apply(null,arr_se);
  var max_coor=Math.max.apply(null,arr_se);
  for(var i_y_a=0;i_y_a<k_uni;i_y_a++){
   var c_x_1=shape_arr_t["re_point_x"]+shape_arr_t["serial"][i_y_a][0];
   var c_y_1=shape_arr_t["re_point_y"]+shape_arr_t["serial"][i_y_a][1];
   if(cube_obj[c_y_1*_this.settings.col+c_x_1+1]!==undefined&&cube_obj[c_y_1*_this.settings.col+c_x_1+1].con==1){//任意滑塊con==1的時候
   con_r_r=true;
   break;
   }
  }
  for(var i_y_b=0;i_y_b<k_uni;i_y_b++){//其實(shí)左右可以合并成一個判斷,省掉一些代碼
   var c_x_2=shape_arr_t["re_point_x"]+shape_arr_t["serial"][i_y_b][0];
   var c_y_2=shape_arr_t["re_point_y"]+shape_arr_t["serial"][i_y_b][1];
   if(cube_obj[c_y_2*_this.settings.col+c_x_2-1].con==1){//任意滑塊con==1的時候
   con_l_l=true;
   break;
   }
  }
  if(shape_arr_t["solo_key"]==="s1"){//豎線情況特殊,單獨(dú)處理,其實(shí)應(yīng)該寫一個函數(shù)來統(tǒng)一判斷,不應(yīng)該出現(xiàn)特殊圖形,不然特殊圖形增加的話,要增加很多判讀  
   if(i_list==1){//如果是豎線的話
   for(var i_y_c=0;i_y_c<k_uni;i_y_c++){//如果是豎線的話,則右邊2格處虛擬方塊的con是1,也不能變形,這里到下一行的情況也能適應(yīng)
    var c_x_3=shape_arr_t["re_point_x"]+shape_arr_t["serial"][i_y_c][0];
    var c_y_3=shape_arr_t["re_point_y"]+shape_arr_t["serial"][i_y_c][1];
    if(cube_obj[c_y_3*_this.settings.col+c_x_3+2]!==undefined&&cube_obj[c_y_3*_this.settings.col+c_x_3+2].con==1||cube_obj[c_y_3*_this.settings.col+c_x_3-1].con==1){//任意滑塊con==1的時候
    con_suxian=true;
    break;
    }
   }
   if(re_point_x+max_coor<_this.settings.col-2&&re_point_x>(0- min_coor)&&!con_suxian){
    shape_arr_t["shape_solo"]=shape[shape_arr_t["solo_key"]][0];
    shape_arr_t["mo_list"]=0;//序號為0
   }
   }else{
   shape_arr_t["shape_solo"]=shape[shape_arr_t["solo_key"]][i_list+1];
   shape_arr_t["mo_list"]+=1;//序號加1
   }
  }else{
   if(re_point_x+max_coor>=(_this.settings.col-1)||con_r_r){//靠近右邊或者右邊有con為1的方快(實(shí)體方塊)
   if(con_r){
    if(i_list<l){
    shape_arr_t["shape_solo"]=shape[shape_arr_t["solo_key"]][i_list+1];
    shape_arr_t["mo_list"]+=1;//序號加1
    }else{
    shape_arr_t["shape_solo"]=shape[shape_arr_t["solo_key"]][0];
    shape_arr_t["mo_list"]=0;//序號為0
    }
   }
   }else if(re_point_x<=(0-min_coor)||con_l_l){//靠近左邊或者左邊有con=1的方塊
   if(con_l){
    if(i_list<l){
    shape_arr_t["shape_solo"]=shape[shape_arr_t["solo_key"]][i_list+1];
    shape_arr_t["mo_list"]+=1;//序號加1
    }else{
    shape_arr_t["shape_solo"]=shape[shape_arr_t["solo_key"]][0];
    shape_arr_t["mo_list"]=0;//序號為0
    }
   }
   }else{
   if(i_list<l){
    shape_arr_t["shape_solo"]=shape[shape_arr_t["solo_key"]][i_list+1];
    shape_arr_t["mo_list"]+=1;//序號加1
   }else{
    shape_arr_t["shape_solo"]=shape[shape_arr_t["solo_key"]][0];
    shape_arr_t["mo_list"]=0;//序號為0
   }
   }
  }
  var s_cube=shape_arr_t["shape_solo"];//圖形變換,根據(jù)shape
  var s_mo=s_cube["mo"];//圖形元素
  var k=s_mo.length;
  var color=shape_arr_t["serial"][0][2];//取出顏色
  //console.log(color)
  shape_arr_t["serial"].length=0;//數(shù)組置空
  //console.log(shape_arr["serial"])
  for(var i=0;i<k;i++){//這里的長度是4
   for(var j=0;j<k;j++){//這里的長度是4
   if(s_mo[i][j]){//如果等于1的話
    shape_arr_t["serial"].push([j,i,color])//需要繪制小塊的坐標(biāo),所有小方塊顏色一樣,如果想變成不一樣,則在for循環(huán)內(nèi)部執(zhí)行生成顏色函數(shù),j,i才能對應(yīng)圖形
   }
   }
  }
  //console.log(shape_arr)
  shape_arr_t.draw(ctx);//重新繪制
  };
 }
 function left(){
  if(start_con){
  ctx.clearRect(0,0,canvas.width,canvas.height);//清屏
  cube_obj.forEach(function(e){//重新繪制虛擬小方塊
   e.draw(ctx);
  })
  var arr_se=[];
  var con=true;
  var k=shape_arr_t["serial"].length;
  for(var i_uni=0;i_uni<k;i_uni++){//取出圖形所有小塊的橫坐標(biāo)
   arr_se.push(shape_arr_t["serial"][i_uni][0]);
  }
  var min_coor=Math.min.apply(null,arr_se);//取出最小的,其實(shí)這里除了豎線那個圖形之外,最小的值都是0,但是這里這樣寫,有利于拓展以后可能出現(xiàn)的其他情況
  if(shape_arr_t["re_point_x"]<=(0- min_coor)){//碰到邊界的時候
   con=false;
  }
  for(var i=0;i<k;i++){//判斷所有小塊左邊的虛擬方塊的con是否都是0
   var c_x=shape_arr_t["re_point_x"]+shape_arr_t["serial"][i][0];
   var c_y=shape_arr_t["re_point_y"]+shape_arr_t["serial"][i][1];
   if(cube_obj[c_y*_this.settings.col+c_x-1].con==1){//任意滑塊con==1的時候。?。杭?減一的時候,有可能到上一行下一行,但是這種情況就靠邊了,所以這樣判斷還是對的
   con=false;
   break;
   }
  }
  if(con){
   shape_arr_t["re_point_x"]-=1; 
  }
  shape_arr_t.draw(ctx);//重新繪制
  }
 };
 function right(){
  if(start_con){
  ctx.clearRect(0,0,canvas.width,canvas.height);//清屏
  cube_obj.forEach(function(e){//重新繪制虛擬小方塊
   e.draw(ctx);
  })
  var con=true;
  var arr_se=[];
  var k=shape_arr_t["serial"].length;
  for(var i_uni=0;i_uni<k;i_uni++){//取出圖形所有小塊的橫坐標(biāo)
   arr_se.push(shape_arr_t["serial"][i_uni][0]);
  }
  var max_coor=Math.max.apply(null,arr_se);//取出最大的
  if(shape_arr_t["re_point_x"]+max_coor>=(_this.settings.col-1)){//靠邊的話
   con=false;
  }
  for(var i=0;i<k;i++){//判斷所有小塊右邊的虛擬方塊的con是否都是0
   var c_x=shape_arr_t["re_point_x"]+shape_arr_t["serial"][i][0];
   var c_y=shape_arr_t["re_point_y"]+shape_arr_t["serial"][i][1];
   if(cube_obj[c_y*_this.settings.col+c_x+1]!==undefined&&cube_obj[c_y*_this.settings.col+c_x+1].con==1){//任意滑塊con==1的時候
   con=false;
   break;
   }
  }
  if(con){
   shape_arr_t["re_point_x"]+=1; 
  }
  shape_arr_t.draw(ctx);//重新繪制
  }
 };
 function down(){
 };
 function enter(){
  var radio_arr=document.getElementsByClassName("level");
  if(!start_con){//如果還沒開始的話,則開始(//設(shè)置條件判斷。不停的點(diǎn)擊enter的時候,只執(zhí)行一次)
  Array.prototype.forEach.call(radio_arr,function(e){
   if(e.checked==true){
   k_t=e.value;//用于級別增加
   level_t=e.value;
   }
   e.setAttribute("disabled",true);
  })
  fall_1=setInterval(fall,_this.settings.v_dowm/level_t)//全局變量,用于domn函數(shù)的清除,但是這樣就不能避免外部的污染了
  start_con=true;
  }
 };
 function get_score(){//得分機(jī)制,寫了很多for循環(huán),感覺應(yīng)該有更好的判斷
  var lose_row=[];//消失的行數(shù)
  var clear_con=false;//是否當(dāng)前需要重繪
  for(var i=0;i<_this.settings.row;i++){
  var all_con=true;//默認(rèn)當(dāng)前行所有滑塊的con都是1
  for(var j=0;j<_this.settings.col;j++){
   if(cube_obj[i*_this.settings.col+j]["con"]!==1){
   all_con=false;
   break;
   }
  }
  if(all_con){
   lose_row.push(i)
  } 
  }//以下代碼在沒有消除的行的時候,都不執(zhí)行
  if(lose_row.length>0){//計(jì)算分?jǐn)?shù)
  switch (lose_row.length){
   case 1:
   score+=10;
   break;
   case 2:
   score+=30;
   break;
   case 3:
   score+=60
   break;
   case 4:
   score+=100;
   break; 
   default:
   break;
  }
  }
  for(var i_sc=0;i_sc<lose_row.length;i_sc++){//把需要消除行的con變?yōu)?,用于消除,length為0的時候,表示沒有需要消除的行
  for(var j_sc=0;j_sc<_this.settings.col;j_sc++){
   cube_obj[lose_row[i_sc]*_this.settings.col+j_sc]["con"]=0;//重置為虛擬
   cube_obj[lose_row[i_sc]*_this.settings.col+j_sc]["fillStyle"]="pink"http://顏色重新變成粉紅,這是0的標(biāo)示
  }
  clear_con=true;//只要有需要消除的行,就要重繪
  }
  if(clear_con){
  ctx.clearRect(0,0,canvas.width,canvas.height);//清屏
  cube_obj.forEach(function(e){//重新繪制虛擬小方塊,移除消除的行
   e.draw(ctx);
  })
  score_num.innerText=score;//重新計(jì)算分?jǐn)?shù)
  }
  for(var i_sc=0;i_sc<lose_row.length;i_sc++){//con為1的滑塊往下移動
  var con_one=[];//用來存儲所有con為1的虛擬滑塊
  for(var i_v=0;i_v<_this.settings.row*_this.settings.col;i_v++){
   if(cube_obj[i_v]["con"]==1){
   con_one.push(cube_obj[i_v]);
   }
  }
  for(var i_l=con_one.length-1;i_l>=0;i_l--){//
   if(con_one[i_l]["row"]<lose_row[i_sc]){//如果位置在消失的滑塊上方
   var fillStyle=con_one[i_l]["fillStyle"];//取出渲染顏色
   var row=con_one[i_l]["row"];//取出當(dāng)前行數(shù)
   var col=con_one[i_l]["col"];//取出當(dāng)前列數(shù)
   con_one[i_l]["con"]=0;//重置為虛擬
   con_one[i_l]["fillStyle"]="pink";
   var k=lose_row.length-i_sc;//往下移動多少行;
   cube_obj[(row+k)*_this.settings.col+col]["fillStyle"]=fillStyle;//移動之后變色 
   cube_obj[(row+k)*_this.settings.col+col]["con"]=1;
   }
  }
  }
  if(clear_con){//繪制
  clearInterval(fall_1);//fall函數(shù)停止執(zhí)行
  setTimeout(function(){//xxms之后重繪,給人消失的效果,為了做成這種效果,造成了fall函數(shù)和get_score函數(shù)的嵌套,應(yīng)該有更好的思路
   ctx_s.clearRect(0,0,canvas_s.width,canvas_s.height);//提示屏清除
   cube_obj_s.forEach(function(e){//提示屏虛擬方塊重新繪制
   e.draw(ctx_s);
   });
   ctx.clearRect(0,0,canvas.width,canvas.height);//清屏
   cube_obj.forEach(function(e){//重新繪制虛擬小方塊
   e.draw(ctx);
   })
   shape_arr_t=_this.clone_obj(shape_arr_s);;//注“這里不能用var 聲明變量,否則函數(shù)內(nèi)部shape_arr的值會是undefined。
   shape_arr_t.re_point_x=(_this.settings.col/2)|0;//初始坐標(biāo)做變化
   shape_arr_t.re_point_y=0;
   shape_arr_s=_this.draw_shape(ts,shape,shape_arr,shape_key,_this.make_color(color));
   shape_arr_s.draw(ctx_s);//重繪提示滑塊
   if(score>=10&&score<20){//分?jǐn)?shù)變化的話,則加速
   level_t=parseInt(k_t)+1;
   }else if(score>=20&&score<30){
   level_t=parseInt(k_t)+2;
   }else if(score>=30&&score<40){
   level_t=parseInt(k_t)+3;
   }else if(score>=40){
   level_t=parseInt(k_t)+4;
   }
   fall_1=setInterval(fall,_this.settings.v_dowm/level_t)//重新啟動fall函數(shù)
  },250)
  }
  return clear_con;//用于判斷后續(xù)作圖
 };
 function fall(){//下落函數(shù)
  var arr_se=[];
  var con=true;
  var k=shape_arr_t["serial"].length;
//  for(var i=0;i<k;i++){//取出圖形所有小塊的縱坐標(biāo)坐標(biāo)
//  arr_se.push(shape_arr["serial"][i][1]);
//  }
//  var max_coor=Math.max.apply(null,arr_se);//取出最大的
  for(var i_que=0;i_que<k;i_que++){//判斷所有小塊下方的虛擬方塊的con是否都是0
  var c_x_1=shape_arr_t["re_point_x"]+shape_arr_t["serial"][i_que][0];
  var c_y_1=shape_arr_t["re_point_y"]+shape_arr_t["serial"][i_que][1];
  //cube_obj[(c_y_1+1)*_this.settings.col+c_x_1]==undefined這種方法判斷是否靠近底邊
  if(cube_obj[(c_y_1+1)*_this.settings.col+c_x_1]==undefined||cube_obj[(c_y_1+1)*_this.settings.col+c_x_1].con==1){//到達(dá)底部或者下方任意滑塊con==1的時候
   con=false;
   break;
  }
  }
  if(con){//不靠低邊并且所有小塊下方的虛擬方塊的con都是0
  ctx.clearRect(0,0,canvas.width,canvas.height);//清屏
  shape_arr_t["re_point_y"]+=1; 
  cube_obj.forEach(function(e){//重新繪制虛擬小方塊
   e.draw(ctx);
  })
  shape_arr_t.draw(ctx);//重繪滑塊
  }else{
  end();
  for(var i_uni=0;i_uni<k;i_uni++){
   var c_x_2=shape_arr_t["re_point_x"]+shape_arr_t["serial"][i_uni][0];
   var c_y_2=shape_arr_t["re_point_y"]+shape_arr_t["serial"][i_uni][1];
   var c_color=shape_arr_t["serial"][i_uni][2];
   cube_obj[c_y_2*_this.settings.col+c_x_2].fillStyle=c_color;//修改對應(yīng)虛擬方塊顏色
   cube_obj[c_y_2*_this.settings.col+c_x_2].con=1;//修改對應(yīng)虛擬方塊con
  } 
  con_s=get_score();
  if(!con_s){//沒有消除行的話
   ctx.clearRect(0,0,canvas.width,canvas.height);//清屏
   ctx_s.clearRect(0,0,canvas_s.width,canvas_s.height);//提示屏清除
   cube_obj_s.forEach(function(e){//提示屏虛擬方塊重新繪制
   e.draw(ctx_s);
   });
   cube_obj.forEach(function(e){//重新繪制虛擬小方塊
   e.draw(ctx);
   })
//   shape_arr=shape_arr_s;//注“這里不能用var 聲明變量,否則函數(shù)內(nèi)部shape_arr的值會是undefined。
//   shape_arr_s=_this.draw_shape(ts,shape,shape_arr,shape_key,_this.make_color(color));
//   shape_arr一個對象,因而是引用類型值,所以執(zhí)行shape_arr=shape_arr_s的時候,只是做了指針的重新指向,shape_arr會隨著shape_arr_s的改變而改變
   shape_arr_t=_this.clone_obj(shape_arr_s);
   shape_arr_t.re_point_x=(_this.settings.col/2)|0;//初始坐標(biāo)做變化
   shape_arr_t.re_point_y=0;
   shape_arr_s=_this.draw_shape(ts,shape,shape_arr,shape_key,_this.make_color(color));
   shape_arr_s.draw(ctx_s);//重繪提示滑塊
   shape_arr_t.draw(ctx);//重繪滑塊
  }
  }
 };
 function end(){//判斷游戲結(jié)束
  var con_end=false;
  for(var i=0;i<_this.settings.col;i++){
  if(cube_obj[i]["con"]==1){
   alert("到頂了,你好菜");
   con_end=true;
   break;
  }
  }
  if(con_end){
  location.reload();
  }
 }
 }
 tetris.prototype={//constructor將不在指向原函數(shù),指向這個對象,如果需要,則寫明
 extend:function(a,b){
  for(var key in a){
  if(a[key]!==undefined){
   b[key]=a[key];
  }
  }
  return b;
 },
 clone_obj:function(myObj){//克隆對象
   if(typeof(myObj) != 'object') return myObj; 
   if(myObj == null) return myObj; 
   if(myObj instanceof Array){//如果是數(shù)組的話,則創(chuàng)建新數(shù)組
    var myNewObj=new Array();
    for(var i=0;i<myObj.length;i++){
    myNewObj[i]=arguments.callee(myObj[i]);
    }
   }else{
    var myNewObj = new Object(); 
    for(var i in myObj) 
    myNewObj[i] = arguments.callee(myObj[i]);//遞歸。把所有的子對象都clone
   }
   return myNewObj; 
 },
 p_dom:function(a,b,c){//創(chuàng)建p標(biāo)簽
  var p=document.createElement("p");
  p.style.cssText="font-size: 20px;";
  p.className=c;
  p.innerText=b;
  a.appendChild(p);
 },
 input_dom:function(a,b){//創(chuàng)建input標(biāo)簽
  for(var i=1;i<=b;i++){
  if(i==1){
   var ch="checked";
  }else{
   ch="";
  }
  var label_d=document.createElement("label");
  var str='<input type="radio" name="level" value="'+i+'" '+ch+' class="level">級別'+i;
  label_d.innerHTML=str;
  a.appendChild(label_d);
  }
 },
 canvas_dom:function(a,b,c,d,e){//創(chuàng)建canvas標(biāo)簽
  var canvas=document.createElement("canvas");
  canvas.style.cssText="border:3px solid #333333;display: block;margin: 0 auto;";
  canvas.setAttribute("width",d*(b+e)-e);
  canvas.setAttribute("height",c*(b+e)-e);
  a.appendChild(canvas);
 },
 cube_obj_arr:function(a,b,c,d,e,f){//創(chuàng)建小方塊集合,從左往右,從上往下,虛擬的,這里可以不畫出來
  for(var i=0;i<c;i++){
  for(var j=0;j<d;j++){
   var cube_obj={
   x_start:(b+e)*j,
   y_start:(b+e)*i,
   col:j,//第幾烈
   row:i,//第幾行
   fillStyle:"pink",//默認(rèn)顏色
   side_width:b,
   con:0,
   draw:function(a){
    a.beginPath();
    a.fillStyle=this.fillStyle;//this指向這個對象
    a.fillRect(this.x_start,this.y_start,this.side_width,this.side_width)
   }
   };//條件以后按需添加
   f.push(cube_obj);
  }
  }
  return f;
 },
 grid:function(a,b,c,d,e){//畫網(wǎng)格
  for(var i=1;i<c;i++){//行數(shù)
  a.beginPath();
  a.moveTo(0,i*(b+e)-e);
  a.lineTo(d*(b+e)-e,i*(b+e)-e);
  a.lineWidth=e;
  a.stroke();
  }
  for(var i=1;i<d;i++){
  a.beginPath();
  a.moveTo(i*(b+e)-e,0);
  a.lineTo(i*(b+e)-e,c*(b+e)-e);
  a.lineWidth=e;
  a.stroke();
  }
 },
 make_color:function(a){//生成隨機(jī)顏色
  var color_true="#";
  for(var i=0;i<6;i++){
  color_true+=a[Math.round(Math.random()*15)];
  }
  return color_true;
 },
 obj_list:function(a){//for...in 循環(huán)只遍歷可枚舉屬性。像 Array 和 Object 使用內(nèi)置構(gòu)造函數(shù)所創(chuàng)建的對象都會繼承自 Object.prototype 和 String.prototype 的不可枚舉屬性
  var key_arr=[];
  for(var key in a){
  key_arr.push(key);
  }
  return key_arr;
 },
 draw_shape:function(a,b,c,d,e){//生成下落滑塊//ctx,shape,shape_arr,shape_key,_this.make_color(color)
  if(a=="ts"){
  c["re_point_x"]=0;
  c["re_point_y"]=0;
  }else{
  c["re_point_x"]=(this.settings.col/2)|0;//重置
  c["re_point_y"]=0;//重置
  }
  c["serial"].length=0;//重置
  var shape_list=d[Math.round(Math.random()*(d.length-1))];//對象中的任意值
  c["solo_key"]=shape_list;
  var b_length=b[shape_list].length;
  var mo_list=Math.round(Math.random()*(b_length-1));
  c["mo_list"]=mo_list;
  var s_cube=b[shape_list][mo_list];//任一一個圖形集合,包裹l,r
  c["shape_solo"]=s_cube//s1-s7中的某一個中的某一個圖形
  var s_mo=s_cube["mo"];//圖形元素
  var k=s_mo.length;
  for(var i=0;i<k;i++){//這里的長度是4
  for(var j=0;j<k;j++){//這里的長度是4
   if(s_mo[i][j]){//如果等于1的話
   c["serial"].push([j,i,e])//需要繪制小塊的坐標(biāo),所有小方塊顏色一樣,如果想變成不一樣,則在for循環(huán)內(nèi)部執(zhí)行生成顏色函數(shù),j,i才能對應(yīng)圖形
   }
  }
  }
  return c;
 }
 }
 window.tetris=tetris;
})()
</script>
 <script type="text/javascript">
 new tetris({
  dom:"box",
  side_length:25,
  row:20,
  col:12,
  v_dowm:500//設(shè)置級別1時的下落速度
 });
 </script>
</html>

以上就是本文的全部內(nèi)容,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,同時也希望多多支持腳本之家!

相關(guān)文章

  • 微信小程序購物商城系統(tǒng)開發(fā)系列-工具篇的介紹

    微信小程序購物商城系統(tǒng)開發(fā)系列-工具篇的介紹

    這篇文章主要介紹了微信小程序購物商城系統(tǒng)開發(fā)系列-工具篇的介紹,具有一定的參考價值,感興趣的小伙伴們可以參考一下。
    2016-11-11
  • 教你如何解密js/vbs/vbscript加密的編碼異處理小結(jié)

    教你如何解密js/vbs/vbscript加密的編碼異處理小結(jié)

    教你如何解密js/vbs/vbscript加密的編碼異處理加密代碼 是一篇非常不錯的加密解密原理,希望大家仔細(xì)研究
    2008-06-06
  • javascript 精粹筆記

    javascript 精粹筆記

    javascript 精粹筆記,都是一些js下應(yīng)用技巧之類,學(xué)習(xí)js的朋友可以簡單的參考瀏覽下。
    2010-05-05
  • JS常見問題之為什么點(diǎn)擊彈出的i總是最后一個

    JS常見問題之為什么點(diǎn)擊彈出的i總是最后一個

    最近有很多朋友問我,為什么點(diǎn)擊彈出的i總是最后一個,于是抽時間寫了這篇文章,特此分享到腳本之家平臺,供大家參考
    2016-01-01
  • JavaScript中前后端交互Ajax示例詳解

    JavaScript中前后端交互Ajax示例詳解

    Ajax不是一種新的編程語言,而是使用現(xiàn)有標(biāo)準(zhǔn)的新方法,下面這篇文章主要給大家介紹了關(guān)于JavaScript中前后端交互Ajax的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-03-03
  • 微信小程序嵌入騰訊視頻源過程詳解

    微信小程序嵌入騰訊視頻源過程詳解

    這篇文章主要介紹了微信小程序嵌入騰訊視頻源過程詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-08-08
  • js登錄彈出層特效

    js登錄彈出層特效

    點(diǎn)擊彈出層,點(diǎn)擊后彈出一個登錄層,在這個層內(nèi)的內(nèi)容調(diào)用了一個示例頁面
    2014-03-03
  • DIV菜單層實(shí)現(xiàn)代碼

    DIV菜單層實(shí)現(xiàn)代碼

    昨天我問一美工jQuery怎么樣了,他說簡單的還可以,復(fù)雜的就不行了,我又問是哪種程度的復(fù)雜?
    2010-11-11
  • PixiJS學(xué)習(xí)之Sprite類的使用詳解

    PixiJS學(xué)習(xí)之Sprite類的使用詳解

    Sprite 直譯為 “精靈”,是游戲開發(fā)中常見的術(shù)語,就是將一個角色的多個動作放到一個圖片里,通過裁剪局部區(qū)域得到當(dāng)前的角色狀態(tài)圖。本文主要介紹了PixiJS中Sprite類的使用,需要的可以參考一下
    2023-02-02
  • webpack自動打包功能實(shí)現(xiàn)

    webpack自動打包功能實(shí)現(xiàn)

    webpack是前端項(xiàng)目構(gòu)建工具打包工具,本文通過實(shí)例代碼給大家介紹webpack自動打包功能實(shí)現(xiàn),感興趣的朋友跟隨小編一起看看吧
    2023-02-02

最新評論