Js貪吃蛇開發過程詳細

開發需求:

需求大家玩過貪吃蛇應該都瞭解,用上下左右控制蛇的方向移動,吃到閃動的小蟲就增長一段並加分。直到撞到四壁或吃到自己遊戲結束。

設計思路:

首先要有一個地圖供蛇爬行。由於蛇的形狀長度均會改變,如果用圖片表示的話肯定不行,其實蛇的移動可以看做是背景色的黑白變化,蛇頭的前一個html元素變黑,蛇爲變白,則可看成是向前移動了一步。你整個地圖的移動則需將整個地圖分爲多個小的html元素,這裏我們選擇table做地圖框架,裏面包含的td做蛇的位移就可以了。我們可以做一個30*30的表格做地圖。然後通過改變900個td的背景色的變化來控制蛇的位移。

開發詳細:

初始構思是這樣畫出方格陣做地圖,然後3個方格是黑色背景表示的蛇。第四個變黑,第一個變白則可看做是向前移動了一步。怎樣控制前後變色呢?開始我想到的是用js獲取當前元素的前後兄弟元素的方法控制首尾的td背景顏色改變,但這種方法後來失敗,只能適用於直線前行的移動,如果向下掉頭的戶js獲取下方的td就難了。其實等把整個地圖畫出來就想到了,應該用二維數組。二維數組的一維表示tr行,二維表示每行的td,這樣把地圖的每個元素都存入二維數組,可以按a[x][y]的x,y算法很快的調用到要移動的位置。

其它的蛇怎麼動怎麼吃蟲子先不考慮,先做出這個table和數組。

css

#she{border-collapse:collapse;}
#she td{
width:15px;
height:15px;
border:1px solid grey;
}
.hei{ background:#000;}/黑色背景/
.bai{ background:#ffff;}/白色背景/
body頁面爲

js

var allTds = new Array();//用於保存所有的td的二維數組
var ck = 30;//地圖長寬
window.function(){//網頁加載時執行
for(var i = 0;i<ck;i++){//控制ck個行即tr
var tr = document.createElement(“tr”);
var trs = new Array();//聲明一個數組用於保存此行的ck個td.
for(var j=0;j<ck;j++){//控制每個行裏的元素即tr裏的ck個td,如果不想畫正方形ck可分開寫兩個參數,一個高一個寬
var td=document.createElement(“td”);
trs[j] = td;
tr.appendChild(td);
}
document.getElementById(“she”).appendChild(tr);
allTds[i] = trs;//保存到二維數組
}
這樣就畫出了一個ckck的表格,此處用的30,即3030;生成表格的同時生成了數組。

然後我們初始化蛇的位置在前k個,k爲蛇的初始長度可自行設定。這個沒啥難的,循環allTds[0][0]到allTds[0][k-1]將其className設爲css的“hei”即可。

然後的要點是我們要考慮這條蛇應該怎麼移動,實質是蛇頭的相鄰td和蛇尾的td的背景變化。蛇頭好說如果當前蛇頭是allTds[x][y],則移動一步後向前則變爲allTds[x][y+1],向下舌頭變爲allTds[x+1][y]。但如何知道當前哪個是蛇頭?經過很多次走動拐彎後如何確定,還有蛇尾,蛇尾的td變白色後,哪個td是下一個蛇尾,是左側還是右側還是上下都有可能。

這時我想到一個辦法是用一個一維數組var she = new Array();表示蛇身,將表示蛇神的td元素依次從尾到頭存入she[0]…she[n].這樣移動一步後新蛇頭可以根據移動方向確定下一個蛇頭是誰,將she[n]替換爲新的蛇頭,前面的she[n-]的值替換爲she[n]…一次替換到she[0]是蛇尾變爲了she[1].she[0]原有值被擠掉。這樣就移動了一步!每移動一步前先這個數組中所有元素變白,即蛇消除掉,變化數組後此數組的所有元素再變黑,蛇再顯示出來,就移動了,這樣蛇頭蛇尾的變化都解決 ,不用考慮蛇身。

思路有了接下來就做。

首先蛇頭是根據方向來移動的,需要一個控制方向的函數,蛇的消除和顯示可以單獨做兩個個帶參函數供調用如下

var dir = 1;//方向,1前,2後,3上,4下
function keyDown(event){//接受鍵盤改變方向

if(event.keyCode==39){//左箭頭
	dir =1;
}
if(event.keyCode==37){//右箭頭
	dir =2;
}
if(event.keyCode==38){//上箭頭
	dir =3;
}
if(event.keyCode==40){//下箭頭
	dir =4;
}

}
function sheYin(obj){//蛇隱 其實不用全部消除,只消除蛇身數組的第一個,因爲我們是按蛇尾到蛇頭排的數組
obj[0].className = “bai”;
}
function sheXian(obj){//蛇現同理
obj[obj.length-1].className = “hei”;
}
開始的初始化改爲:

var allTds = new Array();//用於保存所有的td的二維數組
var ck = 30;//地圖長寬
var k=3;//初始長度
var she = new Array();//初始化蛇
var x = 0;y = k-1;//蛇頭座標
var dir = 1;//方向,1前,2後,3上,4下
window.function(){//網頁加載時執行
for(var i = 0;i<ck;i++){//控制ck個行即tr
var tr = document.getElementById(“she”).insertRow(-1);
var trs = new Array();//聲明一個數組用於保存此行的ck個td.
for(var j=0;j<ck;j++){//控制每個行裏的元素即tr裏的ck個td,如果不想畫正方形ck可分開寫兩個參數,一個高一個寬
var td=document.createElement(“td”);
trs[j] = td;
tr.appendChild(td);
}
allTds[i] = trs;//保存到二維數組
}

for(var g = 0;g< k;g++){//初始化蛇身數組
	she[g] = allTds[0][g];
	allTds[0][g].className = "hei";
}

}

function weStart(){
sheYin(she);//先消除蛇尾

for(var o=0;o<she.length-1;o++){//將蛇身數組依次前移,擠掉蛇尾
	she[o] = she[o+1];
}

if(dir==1){//如果是橫向前行
	she[k-1] = allTds[x][y+1];//任命新蛇頭
	y+=1;//改變蛇頭座標
}
if(dir==2){//同理
	she[k-1] = allTds[x][y-1];
	y-=1;//改變蛇頭座標
}
if(dir==3){//同理
	she[k-1] = allTds[x-1][y];
	x-=1;//改變蛇頭座標
}
if(dir==4){//同理
	she[k-1] = allTds[x+1][y];
	x+=1;//改變蛇頭座標
}

sheXian(she);//將新蛇頭點黑
setTimeout("weStart()",500);//隔半秒後再執行一次,就是半秒走一步的意思

}
原來的地圖table下再畫個table放開始結束等按鈕:

得分:
這時已經是一個粗糙的可以通過控制4向箭頭控制蛇走動的遊戲了。然後要解決的就是撞牆,還有吃蟲,還有變長,還有吃到自己

撞牆這個必須控制,否則移動到table邊緣時取不到下一個元素js本身就會報錯。控制撞牆前提示也很簡單,其實就是先看新舌頭的座標是否超出了0-ck的範圍,再決定是結束遊戲還是走一步,此例是0-30;

然後是吃蟲,這個也很簡單,用js取隨機數的方法隨機取0-ck的兩個數做爲蟲子的座標,如果新蛇頭的座標剛好等於蟲子的座標則表明吃到了蟲子,則將蟲子座標做爲新蛇頭,爲了增長蛇長度,後面不再擠掉蛇尾,數組不變,只是在數組尾部再加一個td,注意此處我們是依照蛇尾到蛇頭順序存入的數組,所以是數組尾部加一個新蛇頭。吃掉後同時做加分操作。重新拋出一個蟲子座標。

然後是吃到自己,同樣簡單了,只有判斷新蛇頭是否包含在蛇身數組中就知道是否要吃到自己了。

然後是game over後如何結束遊戲,其實就是關閉setTimeout事件,用var ji指向每一次的setTimeout結束遊戲調用clearTimeout(ji)即可。

所以此時再執行移動就需要判斷了,是否撞牆了,是否吃蟲了,所以sheyin,shexian需要判斷後再執行需要拿到if裏面來:

方向我們可以隨意控制,但蛇是不能逆行反方向走的,所有控制方向這要改。開始想到的是改變方向前先判斷是否逆行再去改變,後來實施後有問題,因爲比如向左走時,按向下箭頭,並不是蛇頭立刻向下移動,而是等到這個setTimeout的0.5秒到時間後纔去走,就算你設的不是0.5秒,這也是有時間間隔的,這段時間間隔內我們按了向下,非逆行改變了dir的值爲下,立刻再按向右箭頭,判斷與原來的值下非逆行,也可改變dir爲向右,但真正移動時。。。逆行了。。

解決辦法是我們設一個臨時的方向dirLin,無論怎麼改變方向都是改變這個dirLin,真正執行移動這個操作時再去判斷dirLin和正在走的方向dir是否逆行,如果不逆行,則dir=drLin,否則dir保持原方向。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章