推箱子,拼圖,迷宮,太禿然了,一夜完成這款迷宮遊戲

先看效果圖,在線電腦嘗試地址
http://blog.icchen.com/game/migong.html

推箱子,拼圖,迷宮,太禿然了,一夜完成這款迷宮遊戲

起因

又到深夜了,我按照以往在CSDN以及各大論壇查看著大佬的問題分享!這佔用了我大量的時間!偶然間發現發現了幾十行代碼就可以完成的小遊戲。然後我尋思我自己可不可以完成這樣的小遊戲創作呢?

推箱子,拼圖,迷宮,太禿然了,一夜完成這款迷宮遊戲

我在想:天天看這玩意,有啥作用,必須跟著寫個小遊戲啥的!當天立志:不寫完不睡覺!

推箱子,拼圖,迷宮,太禿然了,一夜完成這款迷宮遊戲

分析

如果用數據結構與算法造出東西來呢?

· 什麼東西簡單容易呢?我百度一下,我靠,這個鳥遊戲原來不好搞啊,得接觸一堆不熟悉的東西,搞不來搞不來。

有了(靈光一閃),寫個猜數字遊戲,問他加減乘除等於幾。

· 5姐妹又不是小孩子,糊弄不過去。

經過一番折騰,終於在半夜12點確定寫迷宮小遊戲了。大概弄清楚其中的幾個步驟。

大概是:

· 畫線—>畫迷宮(擦線)—>方塊移動、移動約束(不出界不穿牆)—>完成遊戲。

畫線(棋盤)

對於html+js(canvas)畫的東西,之前學過javaswing應該有點映像。在html中有個canvas 的畫布,可以在上面畫一些東西和聲明一些監聽(鍵盤監聽)。

對於迷宮來說,那些線條是沒有屬性的,只有位置x,y,你操作這個畫布時候,可能和我們習慣的面相對象思維不一樣。所以,在你設計的線或者點的時候,記得那個點、線在什麼位置,在後續劃線還是擦線還是移動的時候根據這個位置進行操作。

MyHtml.html


var aa=14;

var chess = document.getElementById("mycanvas");

var context = chess.getContext('2d');


// var context2 = chess.getContext('2d');

// context.strokeStyle = 'yellow';

var tree = [];//存放是否聯通

var isling=[];//判斷是否相連

for(var i=0;i

tree[i]=[];

for(var j=0;j

tree[i][j]=-1;//初始值為0

}

} for(var i=0;i

isling[i]=[];

for(var j=0;j

isling[i][j]=-1;//初始值為0

}

}


function drawChessBoard(){//繪畫

for(var i=0;i

context.strokeStyle='gray';//可選區域

context.moveTo(15+i*30,15);//垂直方向畫15根線,相距30px;

context.lineTo(15+i*30,15+30*aa);

context.stroke();

context.moveTo(15,15+i*30);//水平方向畫15根線,相距30px;棋盤為14*14;

context.lineTo(15+30*aa,15+i*30);

context.stroke();

}

}

drawChessBoard();//繪製棋盤


// var mymap=new Array(36);

// for(var i=0;i<36;i++)

// {mymap[i]=-1;}


實現效果

推箱子,拼圖,迷宮,太禿然了,一夜完成這款迷宮遊戲

畫迷宮

隨機迷宮怎麼生成?怎麼搞?一臉懵逼。

· 因為我們想要迷宮,那麼就需要這個迷宮出口和入口有連通路徑,你可能壓根不知道迷宮改怎麼生成,用的什麼算法。小聲BB:並查集(不相交集合)。

迷宮和不相交集合有什麼聯繫呢?(規則)

· 之前筆者在前面數據結構與算法系列中曾經介紹過並查集(不相交集合),它的主要功能是森林的合併,不聯通的通過並查集能夠快速將兩個森林合併,並且能夠快速查詢兩個節點是否在同一個森林中!

而我們的隨機迷宮:在每個方格都不聯通的情況下,是一個棋盤方格,這也是它的初始狀態。而這個節點可以跟鄰居可能相連,也可能不相連。我們可以通過並查集實現。

具體思路為:(主要理解並查集)

1:定義好不想交集合的基本類和方法(search,union等)
2:數組初始化,每一個數組元素都是一個集合,值為-1
3:隨機查找一個格子(一維數據要轉換成二維,有點麻煩),在隨機找一面牆(也就是找這個格子的上下左右),還要判斷找的格子出沒出界。
具體在格子中找個隨機數m——>隨機數m在二維中的位置[m/長,m%長]——>這個二維的上下左右隨機找一個位置p[m/長+1,m%長]或[m/長-1,m%長]或[m/長,m%長+1]或[m/長,m%長-1]——>判斷是否越界
4:判斷兩個格子(一維數組編號)是否在一個集合(並查集查找)。如果在,則重新找,如果不在,那麼把牆挖去
5:把牆挖去有點繁瑣,需要考慮奇偶判斷它那種牆(上下還是左右,還要考慮位置),然後擦掉。(根據數組轉換成真實距離)。具體為找一個節點,根據位置關係找到一維數組的號位用並查集判斷是否在一個集合中。

6:最終得到一個完整的迷宮。直到第一個(1,1)和(n,n)聯通停止。雖然採用隨機數找牆,但是效果並不是特別差。其中要搞清一維二維數組的關係。一維是真實數據,並查集操作。二維是位置。要搞懂轉化!

注意:避免混淆,搞清數組的地址和邏輯矩陣位置。數組從0開始的,邏輯上你自己判斷。別搞混淆!


推箱子,拼圖,迷宮,太禿然了,一夜完成這款迷宮遊戲


主要邏輯為:

while(search(0)!=search(aa*aa-1))//主要思路

{

var num = parseInt(Math.random() * aa*aa );//產生一個小於196的隨機數

var neihbour=getnei(num);

if(search(num)==search(neihbour)){continue;}

else//不在一個上

{

isling[num][neihbour]=1;isling[neihbour][num]=1;

drawline(num,neihbour);//劃線

union(num,neihbour);


}

}

那麼在前面的代碼為

MyHtml.html


實現效果:

推箱子,拼圖,迷宮,太禿然了,一夜完成這款迷宮遊戲


方塊移動

這部分我採用的方法不是動態真的移動,而是一格一格的跳躍。也就是當走到下一個格子將當前格子的方塊擦掉,在移動的那個格子中再畫一個方塊。選擇方塊是因為方塊更方便擦除,可以根據像素大小精準擦除。

另外,再移動中要注意不能穿牆、越界。那麼怎麼判斷呢?很好辦,我們再前面會判斷兩個格子是否聯通,如果不連通我們將把這個牆拆開。再拆的時候把這個牆的時候記錄這兩點拆牆可走即可(數組)

另外,事件的監聽上下左右查一查就可以得到,添加按鈕對一些事件監聽,這些不是最主要的。

為了豐富遊戲可玩性,將方法封裝,可以設置關卡(只需改變迷宮大小)。這樣就可以實現通關了。另外,如果寫成動態存庫那就更好了。

推箱子,拼圖,迷宮,太禿然了,一夜完成這款迷宮遊戲


結語

隔行如隔山,短短几十行,碼了大半天,然後終於搞完成了,然後大家需要自己體驗的話點擊上方的鏈接,先行體驗,如果有什麼不懂的不明白的可以留言討論。


分享到:


相關文章: