国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

JS和canvas實現俄羅斯方塊

2019-11-19 17:09:32
字體:
來源:轉載
供稿:網友

效果圖:

代碼如下:

<!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 = {//圖形順時針旋轉變形,感覺有點麻煩,這里還應該加一個參數--距離左右多少格的時候不能變形,有利于后續圖形的拓展,但是這里就先不寫了 s1: [ {  mo: [  [0, 0, 0, 0],  [0, 0, 0, 0],  [0, 0, 0, 0],  [1, 1, 1, 1]  ],  l:true,//通過這兩個參數,判斷左右碰撞能否變形  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,//行數  col:15,//列數  v_dowm:10,  side_width:1//分隔線條寬度默認為1 }; var k=this.extend(a,this.settings); var dom=document.getElementById(this.settings.dom); var fall_2=undefined;//用于判斷快速下落 var score=0;//分數 this.p_dom(dom,"初始級別:"); this.p_dom(dom,"分數:","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=[];//用來裝建造區域小方塊 var cube_arr_s=[];//用來裝提示圖形區域小方塊 var shape_arr={//用來表示下落的滑塊  shape_solo:undefined,//s1――s7中某一個的某一個圖形  solo_key:undefined,//shape_solo的key值  mo_list:undefined,//繪制的圖形在數組shape_solo的下標,變換圖形的時候用到  serial:[],//小方塊坐標集合,默認為空,不繪制小塊。繪制小方塊的參考,重要參數  re_point_x:(_this.settings.col/2)|0,//以第幾個為初始參考X坐標(用于左右移動)  re_point_y:0,//y坐標參考。(不要在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){//繪制小方塊函數,寫在這里,才是這個對象的私有方法,而_proto_的寫法是所有對象都擁有   var se=this.serial;   //console.log(se)   for(var i=0;i<se.length;i++){   a.beginPath();   a.fillStyle=se[0][2];//this指向這個對象.第三個參數是顏色   a.fillRect(this.v*(this.re_point_x+se[i][0]),this.v*(this.re_point_y+se[i][1]),this.width,this.width);   }  } }; //創建提示圖形 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)));//因為返回的是shape_arr,所以這里導致了shape_arr_s和shape_arr有關聯,也就是說以后的代碼中,其中一個改變的話,另一個也會跟著改變,用clone方法去掉關聯 cube_obj_s.forEach(function(e){  e.draw(ctx_s); }); shape_arr_s.draw(ctx_s); //創建堆砌圖形 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);//網格 //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); //鼠標事件 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){//做這個判斷是為了防止快速的點擊S鍵時,出現的多次fall_2事件,因為50ms之后,fall_2的值才變成undefined    fall_2=setInterval(fall,10);//clearInterval返回的值是undefined,而setInterval返回的值是一個整數    setTimeout(function(){    fall_2=clearInterval(fall_2);//重置fall_2的值為undefined    },50);   }   break;   default:   break;  }  } } function up(){//shape和shape_arr的關系要弄清楚,這里判斷有點復雜  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;//數組長度減1  var i_list=shape_arr_t["mo_list"];//對應數組的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++){//取出圖形所有小塊的橫坐標,這里有兩個for循環,相同的變量會互相影響,所有設置成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++){//其實左右可以合并成一個判斷,省掉一些代碼   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"){//豎線情況特殊,單獨處理,其實應該寫一個函數來統一判斷,不應該出現特殊圖形,不然特殊圖形增加的話,要增加很多判讀     if(i_list==1){//如果是豎線的話   for(var i_y_c=0;i_y_c<k_uni;i_y_c++){//如果是豎線的話,則右邊2格處虛擬方塊的con是1,也不能變形,這里到下一行的情況也能適應    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的方快(實體方塊)   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"];//圖形變換,根據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;//數組置空  //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])//需要繪制小塊的坐標,所有小方塊顏色一樣,如果想變成不一樣,則在for循環內部執行生成顏色函數,j,i才能對應圖形   }   }  }  //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++){//取出圖形所有小塊的橫坐標   arr_se.push(shape_arr_t["serial"][i_uni][0]);  }  var min_coor=Math.min.apply(null,arr_se);//取出最小的,其實這里除了豎線那個圖形之外,最小的值都是0,但是這里這樣寫,有利于拓展以后可能出現的其他情況  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的時候。住:加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++){//取出圖形所有小塊的橫坐標   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){//如果還沒開始的話,則開始(//設置條件判斷。不停的點擊enter的時候,只執行一次)  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函數的清除,但是這樣就不能避免外部的污染了  start_con=true;  } }; function get_score(){//得分機制,寫了很多for循環,感覺應該有更好的判斷  var lose_row=[];//消失的行數  var clear_con=false;//是否當前需要重繪  for(var i=0;i<_this.settings.row;i++){  var all_con=true;//默認當前行所有滑塊的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)  }   }//以下代碼在沒有消除的行的時候,都不執行  if(lose_row.length>0){//計算分數  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變為0,用于消除,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的標示  }  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;//重新計算分數  }  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"];//取出當前行數   var col=con_one[i_l]["col"];//取出當前列數   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函數停止執行  setTimeout(function(){//xxms之后重繪,給人消失的效果,為了做成這種效果,造成了fall函數和get_score函數的嵌套,應該有更好的思路   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 聲明變量,否則函數內部shape_arr的值會是undefined。   shape_arr_t.re_point_x=(_this.settings.col/2)|0;//初始坐標做變化   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){//分數變化的話,則加速   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函數  },250)  }  return clear_con;//用于判斷后續作圖 }; function fall(){//下落函數  var arr_se=[];  var con=true;  var k=shape_arr_t["serial"].length;//  for(var i=0;i<k;i++){//取出圖形所有小塊的縱坐標坐標//  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){//到達底部或者下方任意滑塊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;//修改對應虛擬方塊顏色   cube_obj[c_y_2*_this.settings.col+c_x_2].con=1;//修改對應虛擬方塊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 聲明變量,否則函數內部shape_arr的值會是undefined。//   shape_arr_s=_this.draw_shape(ts,shape,shape_arr,shape_key,_this.make_color(color));//   shape_arr一個對象,因而是引用類型值,所以執行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;//初始坐標做變化   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(){//判斷游戲結束  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將不在指向原函數,指向這個對象,如果需要,則寫明 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){//如果是數組的話,則創建新數組    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){//創建p標簽  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){//創建input標簽  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){//創建canvas標簽  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){//創建小方塊集合,從左往右,從上往下,虛擬的,這里可以不畫出來  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",//默認顏色   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){//畫網格  for(var i=1;i<c;i++){//行數  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){//生成隨機顏色  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 循環只遍歷可枚舉屬性。像 Array 和 Object 使用內置構造函數所創建的對象都會繼承自 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])//需要繪制小塊的坐標,所有小方塊顏色一樣,如果想變成不一樣,則在for循環內部執行生成顏色函數,j,i才能對應圖形   }  }  }  return c; } } window.tetris=tetris;})()</script> <script type="text/javascript"> new tetris({  dom:"box",  side_length:25,  row:20,  col:12,  v_dowm:500//設置級別1時的下落速度 }); </script></html>

以上就是本文的全部內容,希望本文的內容對大家的學習或者工作能帶來一定的幫助,同時也希望多多支持武林網!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 嘉荫县| 平度市| 咸阳市| 莒南县| 海林市| 巴塘县| 南陵县| 西乡县| 中西区| 昆山市| 武强县| 龙口市| 叶城县| 梓潼县| 惠来县| 焦作市| 原平市| 彝良县| 唐山市| 江西省| 大荔县| 廊坊市| 新野县| 连平县| 永和县| 宜州市| 封丘县| 丹巴县| 西吉县| 恭城| 祁连县| 城固县| 四川省| 沈丘县| 普兰店市| 司法| 三门县| 舒兰市| 滨海县| 张家港市| 翁牛特旗|