3D扫雷
掃雷的規則
? ?? ?掃雷,顧名思義,就是在一塊區域內把所有非地雷的格子揭開即勝利;踩到地雷格子就算失敗。區域的大小隨難度的大小決定,有9X9(簡單)到16X30(困難)之分,另外還有自定義的。
? ?? ?通過點擊格子來打開它,如果里面有雷,你就輸了;沒有雷,出現一個數字n,表示在與其相鄰的8個格子內存在著n個雷。如果相鄰的格子沒有雷,那么這個格子也會被發現。
我們的需求
從上面的規則中,我們可以推斷出掃雷簡單版需要的幾個要素: · 布滿格子的網格 · 格子能夠填充一個雷的大小 · 格子能夠隨著鼠標的點擊響應事件 · 當某個各自響應鼠標點擊事件時,它能夠計算出周圍的雷的數量。
創建一個基本的格子
? ?? ? 新建一個Unity項目,再創建一個cube命名為Tile。將它拖到項目文件中作為一個預制物體。我們會用這個沒有腳本的格子作為玩的范圍,而后我們會添加腳本給他。
創建網格生成器 新建一個空的物體命名為Grid,同樣把它作為預制物體。它將作為游戲區域和所有格子的生成器。再新建一個Js腳本,命名為Grid,將其添加到Grid物體上面。Grid腳本主要創建了一個域,如下: [C#]?純文本查看?復制代碼
? ?? ?然后,指定Grid物體上面的Tile Prefab公有變量,將預制物體Tile賦值給它。numberOfTiles變量表示允許你創建的格子數,DistanceBetweenTiles聲明了調整格子間距的大小。
現在,網格生成器還沒有具體功能,在CreateTile()函數中添加以下代碼: [C#]?純文本查看?復制代碼
如果你執行當前的場景,就會創建一行格子,就像這樣:
?
這個函數復制了我們指定數量的格子,然后我們將他們放置一行,通過distanceBetweenTiles控制他們之間的距離。調整距離以達到適當的距離。 對于掃雷游戲,我們需要的是讓格子擺成一個網格,而不是一條線。為了實現這種效果,我們還需要在Grid代碼的開始添加以下代碼:
[C#]?純文本查看?復制代碼
調整CreateTile()函數,就像這樣:
[C#]?純文本查看?復制代碼
如果運行程序,應該就像這樣:
如果你設置的tilesPerRow變量合適,生成器便會創建一個很棒的規則區域。如果你編程能力很強的話,你還可以嘗試更好的優化方案。
將炸彈放入格子中
既然我們已經創建了基座掃雷格子,那么我們就可以給它添加“炸彈”了。新建一個Js腳本,命名為Tile,并將它添到Tile預制物體上,然后聲明一個bool變量。 [C#]?純文本查看?復制代碼
這個變量表示在格子中是否存在炸彈。接著我們得將“炸彈”放進網格中。為了實現這樣的效果,我們需要改變Tile預制物體的游戲物體類型,使其轉變為我們剛剛創建的Tile類,如下: [C#]?純文本查看?復制代碼
然后把Tile物體再次賦值給這個變量。現在我們就可以開始訪問這些變量了。賦值炸彈還是有些技巧的,我們應該在網格生成器中賦值。 首先,在Grid代碼中用三個數組來表示一個格子的數據: [C#]?純文本查看?復制代碼
這里,我們需要初始化數組。初始化操作放在CreateTiles函數中進行,如下: [C#]?純文本查看?復制代碼
然后,還是在CreateTiles函數中改變實例化操作的參數,如下: [C#]?純文本查看?復制代碼
在CreateTiles函數最后添加AssighMines函數: [C#]?純文本查看?復制代碼
CreateTiles函數整體如下:
[C#]?純文本查看?復制代碼
然后,實現AssighMines函數: [C#]?純文本查看?復制代碼
代碼梳理:當一個格子Tile在CreateTiles函數中被創建的時候,這個格子便會被添加到tileAll數組中,所有的格子還會被復制到tileUnmined數組中。在這個數組中,我們隨機選擇格子給其添加炸彈。添加炸彈的操作就是設置變量isMined為true,即表示本格子內存在炸彈。
?
讓格子看起來更有趣
現在,格子就矗立在Unity立方體上,讓我們把他們變成真的“格子”。在原文件中,你能夠找到一個叫做“puzzleObjects.fbx”的3D文件。把復制到的資源文件中,我們就能用它了。我們還要確保導入的文件它的比例為1,因為我們之前使用的設置就是這個比例。 文件導入設置如下:
?
然后設置一下預制物體格子,用tileImproved替換掉立方體原有的mesh。
?
當我們進行到這一步,重置格子的BoxCollider組件。這么做會讓碰撞體更加契合格子。
?
最后給格子重新賦值一個新的材質,不然格子純白色的,不好看。
?
注意:改變預制物體后記得要apply一下,這樣我們改動的東西才能應用到之后創建的預制物體上。之后創建的格子都會照著新的格子去復制。
添加一個數字展示在格子上 我們需要一個數字來顯示本格子周圍有多少地雷。實現這個功能的一個簡單方法就是使用Unity的3D文字。通過點擊GameObject ->CreateOther ->3DText創建,然后把它添加到格子上,就像這樣:
?
讓我們再改進一下:旋轉text讓它面朝上。先給它賦個0值,這樣好讓我們能夠知道字體大小是否合適。還要調整字體和文本的大小,讓字體顯得清晰就行。
?
?
好了,現在我們還要在代碼中能夠訪問3D文本,添加以下代碼: [C#]?純文本查看?復制代碼
把3D文本拖到對應的變量上面:
?
再次提醒,改變預制物體需要應用一下!
總結 我們已經實現了掃雷游戲的基礎函數,目前來說還不能運行,在下一個部分會添加更多的內容,敬請期待。
我們的需求
從上面的規則中,我們可以推斷出掃雷簡單版需要的幾個要素: · 布滿格子的網格 · 格子能夠填充一個雷的大小 · 格子能夠隨著鼠標的點擊響應事件 · 當某個各自響應鼠標點擊事件時,它能夠計算出周圍的雷的數量。
創建一個基本的格子
? ?? ? 新建一個Unity項目,再創建一個cube命名為Tile。將它拖到項目文件中作為一個預制物體。我們會用這個沒有腳本的格子作為玩的范圍,而后我們會添加腳本給他。
創建網格生成器 新建一個空的物體命名為Grid,同樣把它作為預制物體。它將作為游戲區域和所有格子的生成器。再新建一個Js腳本,命名為Grid,將其添加到Grid物體上面。Grid腳本主要創建了一個域,如下: [C#]?純文本查看?復制代碼
| 01 02 03 04 05 06 07 08 09 10 11 12 | public var tilePrefab: GameObject; public var numberOfTiles: int = 10; public var distanceBetweenTiles: float = 1.0; function Start() { CreateTiles(); } function CreateTiles() { } |
現在,網格生成器還沒有具體功能,在CreateTile()函數中添加以下代碼: [C#]?純文本查看?復制代碼
| 1 2 3 4 5 6 | var xOffset: float = 0.0; ?? for(var tilesCreated: int = 0; tilesCreated < numberOfTiles; tilesCreated += 1) { ????xOffset += distanceBetweenTiles; ????Instantiate(tilePrefab, Vector3(transform.position.x + xOffset, transform.position.y, transform.position.z), transform.rotation); } |
?
這個函數復制了我們指定數量的格子,然后我們將他們放置一行,通過distanceBetweenTiles控制他們之間的距離。調整距離以達到適當的距離。 對于掃雷游戲,我們需要的是讓格子擺成一個網格,而不是一條線。為了實現這種效果,我們還需要在Grid代碼的開始添加以下代碼:
[C#]?純文本查看?復制代碼
| public var tilesPerRow: int = 4; |
[C#]?純文本查看?復制代碼
| 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 | function CreateTiles() { ????var xOffset: float = 0.0; ????var zOffset: float = 0.0; ?? ????for(var tilesCreated: int = 0; tilesCreated < numberOfTiles; tilesCreated += 1) ????{ ????????xOffset += distanceBetweenTiles; ?????????? ????????if(tilesCreated % tilesPerRow == 0) ????????{ ????????????zOffset += distanceBetweenTiles; ????????????xOffset = 0; ????????} ?????? ????????Instantiate(tilePrefab, Vector3(transform.position.x + xOffset, transform.position.y, transform.position.z + zOffset), transform.rotation); ????} } |
如果你設置的tilesPerRow變量合適,生成器便會創建一個很棒的規則區域。如果你編程能力很強的話,你還可以嘗試更好的優化方案。
將炸彈放入格子中
既然我們已經創建了基座掃雷格子,那么我們就可以給它添加“炸彈”了。新建一個Js腳本,命名為Tile,并將它添到Tile預制物體上,然后聲明一個bool變量。 [C#]?純文本查看?復制代碼
| public var isMined: boolean = false; |
| public var tilePrefab: Tile; |
| 1 2 | static var tilesAll: Tile[]; static var tilesMined: Array; static var tilesUnmined: Array; |
| 1 2 | tilesAll = new Tile[numberOfTiles]; tilesMined = new Array(); tilesUnmined = new Array(); |
| 1 | var newTile = Instantiate(tilePrefab, Vector3(transform.position.x + xOffset, transform.position.y, transform.position.z + zOffset), transform.rotation); tilesAll[tilesCreated] = newTile; |
| AssignMines(); |
[C#]?純文本查看?復制代碼
| 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | function CreateTiles() { ????tilesAll = new Tile[numberOfTiles]; ????tilesMined = new Array(); ????tilesUnmined = new Array(); ?????? ????var xOffset: float = 0.0; ????var zOffset: float = 0.0; ?????? ????for(var tilesCreated: int = 0; tilesCreated < numberOfTiles; tilesCreated += 1) ????{ ????????xOffset += distanceBetweenTiles; ?????? ????????if(tilesCreated % tilesPerRow == 0) ????????{ ????????????zOffset += distanceBetweenTiles; ????????????xOffset = 0; ????????} ?????? ????????var newTile = Instantiate(tilePrefab, Vector3(transform.position.x + xOffset, transform.position.y, transform.position.z + zOffset), transform.rotation); ????????tilesAll[tilesCreated] = newTile; ????} ?????? ????AssignMines(); } |
| 01 02 03 04 05 06 07 08 09 10 11 12 13 | function AssignMines() { ????tilesUnmined = tilesAll; ?? ????for(var minesAssigned: int = 0; minesAssigned < numberOfMines; minesAssigned += 1) ????{ ????????var currentTile: Tile = tilesUnmined[Random.Range(0, tilesUnmined.length)]; ?????????? ????????tilesMined.Push(currentTile); ????????tilesUnmined.Remove(currentTile); ?????????? ????????currentTile.GetComponent(Tile).isMined = true; ????} } |
?
讓格子看起來更有趣
現在,格子就矗立在Unity立方體上,讓我們把他們變成真的“格子”。在原文件中,你能夠找到一個叫做“puzzleObjects.fbx”的3D文件。把復制到的資源文件中,我們就能用它了。我們還要確保導入的文件它的比例為1,因為我們之前使用的設置就是這個比例。 文件導入設置如下:
?
然后設置一下預制物體格子,用tileImproved替換掉立方體原有的mesh。
?
當我們進行到這一步,重置格子的BoxCollider組件。這么做會讓碰撞體更加契合格子。
?
最后給格子重新賦值一個新的材質,不然格子純白色的,不好看。
?
注意:改變預制物體后記得要apply一下,這樣我們改動的東西才能應用到之后創建的預制物體上。之后創建的格子都會照著新的格子去復制。
添加一個數字展示在格子上 我們需要一個數字來顯示本格子周圍有多少地雷。實現這個功能的一個簡單方法就是使用Unity的3D文字。通過點擊GameObject ->CreateOther ->3DText創建,然后把它添加到格子上,就像這樣:
?
讓我們再改進一下:旋轉text讓它面朝上。先給它賦個0值,這樣好讓我們能夠知道字體大小是否合適。還要調整字體和文本的大小,讓字體顯得清晰就行。
?
?
好了,現在我們還要在代碼中能夠訪問3D文本,添加以下代碼: [C#]?純文本查看?復制代碼
| public var displayText: TextMesh; |
?
再次提醒,改變預制物體需要應用一下!
總結 我們已經實現了掃雷游戲的基礎函數,目前來說還不能運行,在下一個部分會添加更多的內容,敬請期待。
總結
- 上一篇: 【Unity3D开发小游戏】《扫雷》Un
- 下一篇: 控制台扫雷游戏