日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Unity 2D随机地图

發(fā)布時(shí)間:2024/3/24 编程问答 49 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Unity 2D随机地图 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

最近翻起以前下載的一些老的教學(xué)視頻,于是決定重新看一遍,且每周所學(xué)做個(gè)記錄,下面就直接開始。

這篇文章就講講教程里面的隨機(jī)2D地圖的實(shí)現(xiàn)原理,以及代碼展示。

首先效果如下:

右邊是使用UntiyEditor所編輯的一個(gè)生成面板。左邊是實(shí)際所生成的地圖。

下面是實(shí)際源碼展示


public void CreateTiles(){var total = tiles.Length;for (int i = 0; i < total; i++){var tile = new Tile_();tile.id = i;tiles[i] = tile;}FindNeighbors();}private void FindNeighbors(){for (int r = 0; r < rows; r++){for (int c = 0; c < columns; c++){var tile = tiles[columns*r+c];if (r<rows-1){tile.AddNeighbor(Sides.Bottom,tiles[columns*(r+1)+c]);}if (c<columns-1){ tile.AddNeighbor(Sides.Right,tiles[columns*r+c+1]);}if (c>0){tile.AddNeighbor(Sides.Left,tiles[columns*r+c-1]);}if (r>0){tile.AddNeighbor(Sides.Top,tiles[columns*(r-1)+c]);}}}}

首先要想實(shí)現(xiàn)2D地圖,最簡單的就是先能按照自己所設(shè)定的尺寸生成一個(gè)矩形的地圖,且每一個(gè)單位是由一張sprite組成,這個(gè)應(yīng)該不難。然后,按照面向?qū)ο蟮乃季S,每一個(gè)sprite身上都有一個(gè)tile的腳本,用來記錄自身的信息,以及他周圍的鄰居,以上代碼就是簡單的生成了tile,然后下面對他上下左右的tile都進(jìn)行了儲(chǔ)存。

?

接下來就是如何把這個(gè)地圖包圍起來,始現(xiàn)效果如下

?

首先大家的疑問都是這個(gè)地圖是如何知道,他的邊緣應(yīng)該是如何進(jìn)行填充的。這個(gè)時(shí)候就是用到了一個(gè)很簡單的知識(shí)點(diǎn),二進(jìn)制。

private void CalculateAutotileID(){var sideValues = new StringBuilder();foreach (Tile_ tile in neighbors){sideValues.Append(tile == null ? "0":"1");}autotileID = Convert.ToInt32(sideValues.ToString(),2);}

在生成完地圖的每個(gè)Tile以及記錄了他們的鄰居時(shí)候,根據(jù)他們鄰居有或者沒,用0和1來表示。那么就可以遍歷出所有的情況,比如這個(gè)tile如果他周圍都是空的只有他自己,那么他上下左右都是0,換成二進(jìn)制就是 0,0,0,0,如果他周圍都有方塊,那么換成二進(jìn)制就是1,1,1,1。這就是兩種極端的情況。以此類推,我們根據(jù)每個(gè)tile儲(chǔ)存的他自己周圍的鄰居,就可以得到每個(gè)tile當(dāng)前處于什么狀態(tài),然后轉(zhuǎn)換為10進(jìn)制的數(shù)字,這就是上文的autotileID,并儲(chǔ)存在他們每個(gè)tile自身的類身上,然后只要在合適的時(shí)機(jī)。根據(jù)這個(gè)ID加載對應(yīng)的sprite,就能實(shí)現(xiàn)一個(gè)最簡單的四四方方的地圖。


接下來我們講講,當(dāng)我們生成了一個(gè)矩型的地圖之后我們?nèi)绾巫屗車桓g掉,從而實(shí)現(xiàn)如下圖的效果

public void CreateIsland(float erodePrecent,int erodeIterations,float treePercent,float hillPercent,float mountainPercent,float townsPercent,float monsterPercent,float lakePercent){ DecorateTiles(landTiles,lakePercent,TileType.Empty);for (int i = 0; i < erodeIterations; i++){DecorateTiles(coastTiles,erodePrecent,TileType.Empty);}var openTiles = landTiles;RandomizeTileArray(openTiles);if (openTiles!= null && openTiles[0] != null){openTiles[0].autotileID = (int)TileType.Castle;}DecorateTiles(landTiles,treePercent,TileType.Tree);DecorateTiles(landTiles,hillPercent,TileType.Hills);DecorateTiles(landTiles,mountainPercent,TileType.Mountain);DecorateTiles(landTiles,townsPercent,TileType.Towns);DecorateTiles(landTiles,monsterPercent,TileType.Monster);}public void DecorateTiles(Tile_[] tiles,float percent,TileType type){ var total = Mathf.FloorToInt(tiles.Length*percent);RandomizeTileArray(tiles);for (int i = 0; i < total; i++){ var tile = tiles[i];if(type == TileType.Empty){tile.ClearNeighbors();}tile.autotileID = (int)type;}}

上面的代碼,創(chuàng)建了一個(gè)簡單的方法,DecorateTiles,傳入指定的tile數(shù)組,然后根據(jù)百分比,把他們換成制定的tile類型。

腐蝕的方法很簡單,就在第一個(gè)方法的for循環(huán)里面,他是找到了所有autotileID小于15的方塊,小于15就代表了他們都是邊緣tile,然后對他們隨機(jī)進(jìn)行置空,然后根據(jù)unityEditor所填下的值。決定執(zhí)行幾次置空循環(huán)。

里面的其他代碼也很容易理解,就是獲取了數(shù)值為15的autotileID的方塊,數(shù)值為15就是都為里面填充的方塊,只要根據(jù)百分比轉(zhuǎn)換成你需要的樹,山,之類的,就能實(shí)現(xiàn)上圖最簡單的效果。

?

總結(jié)一下,這個(gè)簡單的2D隨機(jī)地圖,就是通過二進(jìn)制獲得了所有地圖的關(guān)系信息,用這個(gè)關(guān)系信息進(jìn)行數(shù)據(jù)的處理,填充,置空。來實(shí)現(xiàn)出如上圖的效果。

總結(jié)

以上是生活随笔為你收集整理的Unity 2D随机地图的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。