怎么用Javascript实现俄罗斯方块游戏
這篇文章主要介紹“怎么用Javascript實現俄羅斯方塊游戲”,在日常操作中,相信很多人在怎么用Javascript實現俄羅斯方塊游戲問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”怎么用Javascript實現俄羅斯方塊游戲”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
本俄羅斯方塊代碼采用 JavaScript 腳本代碼寫成,簡單易懂;
全代碼采用靜態類及靜態變量成員組成;
全腳本通過實現代碼全局配置 OLSFK.Options = {...}
定義方塊起始坐標及定義各自的旋轉點;
從初始化俄羅斯方塊界面開始,再監聽鍵盤事件;以及左右,向下及旋轉動作判斷,重新渲染方塊位置;
判斷是否消行,以及相應的加級判斷,執行速度,加分操作來執行;
***以判斷是否當前級別大于所定義的***級別來判斷是否結束;
代碼說明講解
OLSFK.Options={//相關參數width:12,//界面橫向方塊數height:20,//界面縱向方塊數boxWidth:'16px',curLevel:1,speed:1000,//setInterval,setTimeoutdirect:{//可以設定是ASDW,還是←↓→Down:40,/*runspeed*/Left:37,Right:39,Rotate:38},Move:true,//是否正在移動Eventing:false,Levels:{1:1000,2:900,3:800,4:700,5:600,6:500,7:400,8:300,9:200,10:100},curBlock:4,//當前移動的圖形名稱nextBlock:0,GampMap:newObject(),Timer:null,deline:0,Score:0,Deling:false,Start:false,lineNum:10,//刪除幾行了,加級ScoreNum:40//消一行加分}
direct 表示 使用鍵盤方位鍵來操作方塊的移動方向;
使用哪種方向鍵按自由喜歡配置,比如字母鍵的A, S, D, W; 或右邊小數字鍵盤的數字鍵各自的鍵盤編碼;
比如 上(旋轉)、下、左、右 方向鍵的編碼分別為:38、40、37、39;
Levels:表示級別配置,本配置共分為10級,每個級別所對應的下落速度,即定時執行間隔;
curBlock:表示當前活動的方塊;
nextBlock:表示接下來執行的方塊索引,并顯示界面右上角的預覽框中;
GampMap:用于保存在根據定義行列數形成的游戲表格中保存每個格的數據信息;
OLSFK.Options.GampMap[x+'_'+y]=0;
對象表格為: id: "box_"+x+"_"+y;
初始化數據為 ‘0’; 表示該表格還未占用;當有占用時,設置值為 ‘1’;
Timer:為定時執行器;setTimeout 定時執行方塊下落的的頻率;定時時間越小,速度越快;
Deling:當正在執行消行操作時,下次暫不顯示并下落;
lineNum:表示消超過 10 行,加一級;
ScoreNum:表示每消一行所加的分數;
OLSFK.ReItems=function(cur){//key旋轉點switch(cur){case1:OLSFK.Items[1]={//長塊LongBlock1:{x:4,y:0},2:{x:5,y:0},3:{x:6,y:0},4:{x:7,y:0},5:{x:5,y:0}//旋轉點};break;//....}}
該方法用于恢復方塊的初始設置;
OLSFK.Next={//key旋轉點//長塊LongBlock1:{1:{x:0,y:1},2:{x:1,y:1},3:{x:2,y:1},4:{x:3,y:1}},//...}
為不了不與游戲方塊的設置沖突,獨立出來下次隨機方塊的對象配置;
OLSFK.Items={//key旋轉點//長塊LongBlock1:{1:{x:4,y:0},2:{x:5,y:0},3:{x:6,y:0},4:{x:7,y:0},5:{x:5,y:0}},//方塊Box2:{1:{x:4,y:0},2:{x:5,y:0},3:{x:4,y:1},4:{x:5,y:1},5:{x:0,y:0}},//凸塊TuBlock3:{1:{x:4,y:1},2:{x:5,y:0},3:{x:5,y:1},4:{x:6,y:1},5:{x:5,y:1}},//L塊LBlock4:{1:{x:5,y:0},2:{x:5,y:1},3:{x:5,y:2},4:{x:6,y:2},5:{x:5,y:2}},5:{//反向L塊FLBlock1:{x:5,y:2},2:{x:6,y:2},3:{x:6,y:1},4:{x:6,y:0},5:{x:6,y:2}},//Z塊ZBlock6:{1:{x:4,y:0},2:{x:5,y:0},3:{x:5,y:1},4:{x:6,y:1},5:{x:5,y:0}},7:{//反向Z塊FZBlock1:{x:4,y:1},2:{x:5,y:1},3:{x:5,y:0},4:{x:6,y:0},5:{x:5,y:1}}}
方塊共分為:長條塊,方塊,凸塊(T塊),L塊,反L塊,Z塊,反Z塊幾種;
共7種方塊,以1,2,3,4,5,6,7 索引鍵表示,方塊是四個小塊組成,每塊都有各自的坐標,1-4表示組成該塊的初始坐標位置,5表示旋轉點;
OLSFK.Init=function(){//初始化界面//...}
俄羅斯方塊的界面初始化方法;將在 window.onload 中調用執行;
varw=OLSFK.Options.width;varh=OLSFK.Options.height;vartotal=w*h;varx=0,y=0;for(vari=0;i<total;i++){OLSFK.Options.GampMap[x+'_'+y]=0;Lib.Tag('SPAN',{id:"box_"+x+"_"+y,name:"cbox",style:{width:OLSFK.Options.boxWidth,height:OLSFK.Options.boxWidth,border:"2pxoutset#669",background:"#ddd",float:"left",overflow:"hidden"},innerHTML:" ",className:"cssbox"},back);varend=i+1;x++;if(end>=w&&end%w==0){x=0;y++;Lib.Tag('DIV',{style:{clear:"both"}},back);}}
通過設置的 Options.width, Options.height 列數與行數,以及設置的小方格寬度,初始化了一個寬:Options.width列,高為 Options.height 的表格界面出來;
Lib.Tag 用于創建標簽對象;
Lib.Tag=function(TAG,json,pnode){//...}
TAG為標簽名,比如: div, span 等;
json為設置標簽樣式 style;
pnode 是該創建所在的父容器;
OLSFK.Init = function() {} 還創建主游戲區域旁邊的下次隨機方塊預覽區,當前級別,及分數,以及操作“開始”,“暫停”按鈕等;
游戲初始入口點
window.onload=function(){if(window.isIE){document.attachEvent("onkeydown",function(e){if(OLSFK.Options.Start){varE=OLSFK.KeyCode();OLSFK.EventFunc(E);}});document.attachEvent("onkeyup",function(e){if(!OLSFK.Options.Move&&OLSFK.Options.Start){OLSFK.Options.Move=true;OLSFK.Options.Eventing=false;OLSFK.Options.Timer=setTimeout(function(){OLSFK.play();},OLSFK.Options.Levels[OLSFK.Options.curLevel]);}});}else{document.addEventListener("keydown",function(e){if(OLSFK.Options.Start){varE=OLSFK.KeyCode();OLSFK.EventFunc(E);}},false);document.addEventListener("keyup",function(e){if(!OLSFK.Options.Move&&OLSFK.Options.Start){OLSFK.Options.Move=true;OLSFK.Options.Eventing=false;OLSFK.Options.Timer=setTimeout(function(){OLSFK.play();},OLSFK.Options.Levels[OLSFK.Options.curLevel]);}},false);}OLSFK.Init();}
主要是監聽鍵盤事件,根據 鍵盤事件 返回的按鈕編碼與 OLSFK.Options.direct 設置方向鍵匹配來操作方塊的移動,旋轉等;
keydown 用于操作下落方塊的移動方向,旋轉等;并重新繪制方塊位置;
keyup 后繼續按本級速度向下落;
OLSFK.Options.Levels[OLSFK.Options.curLevel]
表示當前級別對應的速度,即定時器間隔執行時間(毫秒);
OLSFK.EventFunc=function(code){switch(code){caseOLSFK.Options.direct.Left://LEFTif(!OLSFK.Options.Deling){clearTimeout(OLSFK.Options.Timer);OLSFK.Options.Eventing=true;OLSFK.Options.Move=false;OLSFK.Left();}break;//...}}
該方法是 監聽 keydown 事件執行的動作;code 為按鍵 編碼;
當判斷未在消行動作時,清除定時器,OLSFK.Options.Eventing 設置為事件中 true,OLSFK.Options.Move 為 false 表示停止移動;
進入 向左移動方法 OLSFK.Left();
OLSFK.Left=function(){varblock=OLSFK.Items[OLSFK.Options.curBlock];if(block){varflag=true;for(vari=1;i<=4;i++){varx=block[i].x;vary=block[i].y;if(x-1<0){flag=false;break;}if(OLSFK.Options.GampMap[(x-1)+'_'+y]==1&&!OLSFK.isMe(x-1,y)){flag=false;break;}}if(flag){for(vari=1;i<=4;i++)//清除圖形{varitm=block[i];varbox=Lib.Getid('box_'+itm.x+'_'+itm.y);box.style.background='#ddd';OLSFK.Options.GampMap[itm.x+'_'+itm.y]=0;}for(vari=1;i<=5;i++){varx=block[i].x;vary=block[i].y;OLSFK.Items[OLSFK.Options.curBlock][i]={x:(x-1),y:y};}OLSFK.draw();}}}
var block = OLSFK.Items[OLSFK.Options.curBlock]; 表示獲取當前移動方塊;
if(OLSFK.Options.GampMap[(x-1)+'_'+y]==1&&!OLSFK.isMe(x-1,y)){flag=false;break;}
判斷該方塊四個小方塊左邊是否有被占用的方塊,也即:OLSFK.Options.GampMap[(x-1)+'_'+y] 為 1; 并且該位置塊不屬于方塊自己的;
當左邊方向無占用格時,清除當前方塊四個小方塊位置,重新繪制方塊新坐標位置;并重置 相應的 OLSFK.Options.GameMap [x+y] 相應格的值;
當按鈕 keyup 時,繼承正常向下落;
OLSFK.isMe 代碼:
OLSFK.isMe=function(x,y){varblock=OLSFK.Items[OLSFK.Options.curBlock];if(block){for(vari=1;i<=4;i++){if(block[i].x==x&&block[i].y==y){returntrue;}}}returnfalse;}
即指定的 x,y (參數值) 是否還在當前方塊四個坐標內;
OLSFK.Right () 與 Left() 一樣;
旋轉方塊代碼;
OLSFK.Rotate=function(){varblock=OLSFK.Items[OLSFK.Options.curBlock];if(block){varflag=true;varR=block[5];for(vari=1;i<=4;i++){varx=block[i].x;vary=block[i].y;if(R.x==x&&R.y==y){}else{varnson=newObject();nson.x=R.x+R.y-y;nson.y=R.y-R.x+x;if(nson.x<0||nson.y<0||nson.x>=OLSFK.Options.width||nson.y>=OLSFK.Options.height){flag=false;break;}if(OLSFK.Options.GampMap[nson.x+'_'+nson.y]==1&&!OLSFK.isMe(nson.x,nson.y)){flag=false;break;}}}if(flag){for(vari=1;i<=4;i++)//清除圖形{varitm=block[i];varbox=Lib.Getid('box_'+itm.x+'_'+itm.y);box.style.background='#ddd';OLSFK.Options.GampMap[itm.x+'_'+itm.y]=0;}varPnt=1;for(vari=1;i<=4;i++){varx=block[i].x;vary=block[i].y;if(R.x==x&&R.y==y){Pnt=i;}else{varnson=newObject();nson.x=R.x+R.y-y;nson.y=R.y-R.x+x;OLSFK.Items[OLSFK.Options.curBlock][i]={x:nson.x,y:nson.y};}}OLSFK.Items[OLSFK.Options.curBlock][5]=OLSFK.Items[OLSFK.Options.curBlock][Pnt];OLSFK.draw();}}}
var R = block[5]; 就是獲取旋轉點;
就開始對方塊四個小塊以旋轉點為中心,逆時針旋轉(并不全是 90 度);當當前塊不為旋轉點時,旋轉公式;
varnson=newObject(); nson.x=R.x+R.y-y; nson.y=R.y-R.x+x;
這個公式要這樣看;
ResultX=RotateX+(RotateY-CurrentY); ResultY=RotateY-(RotateX-CurrentX);//Y的偏移量,就是X的增加值;//反之同
當旋轉四周都無占用物時;清除當前圖形,重繪旋轉后的圖形位置;
重置OLSFK.Options.GampMap[itm.x+'_'+itm.y] 各個方塊的占用值;
OLSFK.Random=function(){if(OLSFK.Options.nextBlock!=0){OLSFK.Options.curBlock=OLSFK.Options.nextBlock;varblock=OLSFK.Next[OLSFK.Options.nextBlock];if(block){for(vari=1;i<=4;i++){varitm=block[i];varbox=Lib.Getid('cur_'+itm.x+'_'+itm.y);box.style.background='#ddd';//OLSFK.Options.GampMap[itm.x+'_'+itm.y]=0;}}}else{OLSFK.Options.curBlock=Math.floor(Math.random()*7+1);}OLSFK.Options.nextBlock=Math.floor(Math.random()*7+1);OLSFK.drawNext();}
隨機生成下次預下落的方塊;并顯示到右上角的預覽表格里;
OLSFK.play=function(speed){varblock=OLSFK.Items[OLSFK.Options.curBlock];if(block&&OLSFK.Options.Move){varflag=true;for(vari=1;i<=4;i++){varx=block[i].x;vary=block[i].y;if(y+1>=OLSFK.Options.height){flag=false;break;}if(OLSFK.Options.GampMap[x+'_'+(y+1)]==1&&!OLSFK.isMe(x,y+1)){flag=false;break;}}if(flag){for(vari=1;i<=4;i++)//清除圖形{varitm=block[i];varbox=Lib.Getid('box_'+itm.x+'_'+itm.y);box.style.background='#ddd';OLSFK.Options.GampMap[itm.x+'_'+itm.y]=0;}for(vari=1;i<=5;i++){varx=block[i].x;vary=block[i].y;OLSFK.Items[OLSFK.Options.curBlock][i]={x:x,y:(y+1)};}OLSFK.draw();varS=OLSFK.Options.Levels[OLSFK.Options.curLevel];if(speed){S=50;}OLSFK.Options.Timer=setTimeout(function(){OLSFK.play();},S);}else{OLSFK.ReItems(OLSFK.Options.curBlock);OLSFK.newRun();}}}
OLSFK.play 正常下落的方法,也得判斷下落一格是否有被占用的格,如果沒有,清除當前方塊,繪制方塊新位置;
當方塊不能再下落時(flag = false),重置當前方塊坐標配置; OLSFK.ReItems(OLSFK.Options.curBlock);
進入 OLSFK.newRun(); 新下落方塊下落過程準備;
OLSFK.newRun=function(){clearTimeout(OLSFK.Options.Timer);OLSFK.DelFunc();if(OLSFK.Options.deline>=10){OLSFK.Options.deline=0;OLSFK.Options.curLevel++;OLSFK.Element.CurLevel.setHTML("級:"+OLSFK.Options.curLevel);}OLSFK.Element.Score.setHTML("分:"+OLSFK.Options.Score);if(OLSFK.Options.curLevel<=OLSFK.Options.lineNum){OLSFK.Random();//判斷是否結束OLSFK.ChkEnd();}else{OLSFK.Options.Move=false;OLSFK.Options.Start=false;OLSFK.Options.Eventing=false;OLSFK.Options.Deling=false;Lib.Getid('spn').innerHTML='GameIsOver!YouWintheGame!';Lib.Getid('dobtn').innerHTML='開始';}}
當下落結束時,清除定時器,暫停新方塊下落,檢測是否有可消除的行;減了多少行;
每減去一行 加分OLSFK.Options.Score += OLSFK.Options.ScoreNum;
這個方法在 :
OLSFK.DelFunc=function(){OLSFK.Options.Deling=true;OLSFK.Options.Move=false;OLSFK.Options.Eventing=false;varFn=0;for(vari=OLSFK.Options.height-1;i>=0;i--){Fn=0;for(varj=0;j<OLSFK.Options.width;j++){if(OLSFK.Options.GampMap[j+'_'+i]==1){Fn++;}}if(Fn==OLSFK.Options.width){OLSFK.Options.deline++;OLSFK.Options.Score+=OLSFK.Options.ScoreNum;OLSFK.DelLine(i);i++;}}OLSFK.Options.Deling=false;OLSFK.Options.Move=true;OLSFK.Options.Eventing=true;}
中執行;
減完一行,就重置該行以上所有行往下降一行;并重置 :
OLSFK.Options.GampMap[x+'_'+y] = OLSFK.Options.GampMap[x+'_'+(y-1)];
該減行為上行的數據;
if(Fn==OLSFK.Options.width){OLSFK.Options.deline++;OLSFK.Options.Score+=OLSFK.Options.ScoreNum;OLSFK.DelLine(i);i++;}
該判斷表示該行上所有格都被占用到;
回到 newRun 上,當判斷消行超過幾行時,即加級;
if(OLSFK.Options.curLevel<=OLSFK.Options.lineNum)
{
OLSFK.Random();//判斷是否結束OLSFK.ChkEnd();
}
如果級數小于配置的總級數,則進入 OLSFK.random();
設置當前下落方塊,并隨機生成下次下落方塊并預覽右上角表格上;
OLSFK.ChkEnd=function(){varblock=OLSFK.Items[OLSFK.Options.curBlock];if(block&&OLSFK.Options.Move){varflag=true;for(vari=1;i<=4;i++){varx=block[i].x;vary=block[i].y;if(OLSFK.Options.GampMap[x+'_'+y]==1){flag=false;break;}}}if(flag){OLSFK.draw();//定時往下掉OLSFK.Options.Timer=setTimeout(function(){OLSFK.play();},OLSFK.Options.Levels[OLSFK.Options.curLevel]);}else{OLSFK.Options.Move=false;OLSFK.Options.Start=false;OLSFK.Options.Eventing=false;OLSFK.Options.Deling=false;Lib.Getid('spn').innerHTML='GameIsOver';Lib.Getid('dobtn').innerHTML='開始';}}
當當前下落的方塊進入表格上有被占用的格子,即被卡住,游戲結束;
反之 則 setTimeout 開始新方塊的下落動作;
其他方法說明
OLSFK.Event=function(){if(window.isIE)returnwindow.event;func=OLSFK.Event.caller;while(func!=null){vararg0=func.arguments[0];if(arg0){returnarg0;}func=func.caller;}returnnull;}OLSFK.KeyCode=function(){returnOLSFK.Event().keyCode||OLSFK.Event().which;}
OLSFK.Event = function();
這是一種獲取當前事件的方法,可以比較兼容獲取當前的事件;
俄羅斯方塊 JavaScript 代碼
http://files.cnblogs.com/editor/OLSFK.rar
總結
以上是生活随笔為你收集整理的怎么用Javascript实现俄罗斯方块游戏的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 修改Mysql默认 编码
- 下一篇: 版图设计