當(dāng)前位置:
首頁(yè) >
3D扫雷
發(fā)布時(shí)間:2024/1/1
41
豆豆
掃雷的規(guī)則
? ?? ?掃雷,顧名思義,就是在一塊區(qū)域內(nèi)把所有非地雷的格子揭開即勝利;踩到地雷格子就算失敗。區(qū)域的大小隨難度的大小決定,有9X9(簡(jiǎn)單)到16X30(困難)之分,另外還有自定義的。
? ?? ?通過(guò)點(diǎn)擊格子來(lái)打開它,如果里面有雷,你就輸了;沒(méi)有雷,出現(xiàn)一個(gè)數(shù)字n,表示在與其相鄰的8個(gè)格子內(nèi)存在著n個(gè)雷。如果相鄰的格子沒(méi)有雷,那么這個(gè)格子也會(huì)被發(fā)現(xiàn)。
我們的需求
從上面的規(guī)則中,我們可以推斷出掃雷簡(jiǎn)單版需要的幾個(gè)要素: · 布滿格子的網(wǎng)格 · 格子能夠填充一個(gè)雷的大小 · 格子能夠隨著鼠標(biāo)的點(diǎn)擊響應(yīng)事件 · 當(dāng)某個(gè)各自響應(yīng)鼠標(biāo)點(diǎn)擊事件時(shí),它能夠計(jì)算出周圍的雷的數(shù)量。
創(chuàng)建一個(gè)基本的格子
? ?? ? 新建一個(gè)Unity項(xiàng)目,再創(chuàng)建一個(gè)cube命名為Tile。將它拖到項(xiàng)目文件中作為一個(gè)預(yù)制物體。我們會(huì)用這個(gè)沒(méi)有腳本的格子作為玩的范圍,而后我們會(huì)添加腳本給他。
創(chuàng)建網(wǎng)格生成器 新建一個(gè)空的物體命名為Grid,同樣把它作為預(yù)制物體。它將作為游戲區(qū)域和所有格子的生成器。再新建一個(gè)Js腳本,命名為Grid,將其添加到Grid物體上面。Grid腳本主要?jiǎng)?chuàng)建了一個(gè)域,如下: [C#]?純文本查看?復(fù)制代碼
? ?? ?然后,指定Grid物體上面的Tile Prefab公有變量,將預(yù)制物體Tile賦值給它。numberOfTiles變量表示允許你創(chuàng)建的格子數(shù),DistanceBetweenTiles聲明了調(diào)整格子間距的大小。
現(xiàn)在,網(wǎng)格生成器還沒(méi)有具體功能,在CreateTile()函數(shù)中添加以下代碼: [C#]?純文本查看?復(fù)制代碼
如果你執(zhí)行當(dāng)前的場(chǎng)景,就會(huì)創(chuàng)建一行格子,就像這樣:
?
這個(gè)函數(shù)復(fù)制了我們指定數(shù)量的格子,然后我們將他們放置一行,通過(guò)distanceBetweenTiles控制他們之間的距離。調(diào)整距離以達(dá)到適當(dāng)?shù)木嚯x。 對(duì)于掃雷游戲,我們需要的是讓格子擺成一個(gè)網(wǎng)格,而不是一條線。為了實(shí)現(xiàn)這種效果,我們還需要在Grid代碼的開始添加以下代碼:
[C#]?純文本查看?復(fù)制代碼
調(diào)整CreateTile()函數(shù),就像這樣:
[C#]?純文本查看?復(fù)制代碼
如果運(yùn)行程序,應(yīng)該就像這樣:
如果你設(shè)置的tilesPerRow變量合適,生成器便會(huì)創(chuàng)建一個(gè)很棒的規(guī)則區(qū)域。如果你編程能力很強(qiáng)的話,你還可以嘗試更好的優(yōu)化方案。
將炸彈放入格子中
既然我們已經(jīng)創(chuàng)建了基座掃雷格子,那么我們就可以給它添加“炸彈”了。新建一個(gè)Js腳本,命名為Tile,并將它添到Tile預(yù)制物體上,然后聲明一個(gè)bool變量。 [C#]?純文本查看?復(fù)制代碼
這個(gè)變量表示在格子中是否存在炸彈。接著我們得將“炸彈”放進(jìn)網(wǎng)格中。為了實(shí)現(xiàn)這樣的效果,我們需要改變Tile預(yù)制物體的游戲物體類型,使其轉(zhuǎn)變?yōu)槲覀儎倓倓?chuàng)建的Tile類,如下: [C#]?純文本查看?復(fù)制代碼
然后把Tile物體再次賦值給這個(gè)變量。現(xiàn)在我們就可以開始訪問(wèn)這些變量了。賦值炸彈還是有些技巧的,我們應(yīng)該在網(wǎng)格生成器中賦值。 首先,在Grid代碼中用三個(gè)數(shù)組來(lái)表示一個(gè)格子的數(shù)據(jù): [C#]?純文本查看?復(fù)制代碼
這里,我們需要初始化數(shù)組。初始化操作放在CreateTiles函數(shù)中進(jìn)行,如下: [C#]?純文本查看?復(fù)制代碼
然后,還是在CreateTiles函數(shù)中改變實(shí)例化操作的參數(shù),如下: [C#]?純文本查看?復(fù)制代碼
在CreateTiles函數(shù)最后添加AssighMines函數(shù): [C#]?純文本查看?復(fù)制代碼
CreateTiles函數(shù)整體如下:
[C#]?純文本查看?復(fù)制代碼
然后,實(shí)現(xiàn)AssighMines函數(shù): [C#]?純文本查看?復(fù)制代碼
代碼梳理:當(dāng)一個(gè)格子Tile在CreateTiles函數(shù)中被創(chuàng)建的時(shí)候,這個(gè)格子便會(huì)被添加到tileAll數(shù)組中,所有的格子還會(huì)被復(fù)制到tileUnmined數(shù)組中。在這個(gè)數(shù)組中,我們隨機(jī)選擇格子給其添加炸彈。添加炸彈的操作就是設(shè)置變量isMined為true,即表示本格子內(nèi)存在炸彈。
?
讓格子看起來(lái)更有趣
現(xiàn)在,格子就矗立在Unity立方體上,讓我們把他們變成真的“格子”。在原文件中,你能夠找到一個(gè)叫做“puzzleObjects.fbx”的3D文件。把復(fù)制到的資源文件中,我們就能用它了。我們還要確保導(dǎo)入的文件它的比例為1,因?yàn)槲覀冎笆褂玫脑O(shè)置就是這個(gè)比例。 文件導(dǎo)入設(shè)置如下:
?
然后設(shè)置一下預(yù)制物體格子,用tileImproved替換掉立方體原有的mesh。
?
當(dāng)我們進(jìn)行到這一步,重置格子的BoxCollider組件。這么做會(huì)讓碰撞體更加契合格子。
?
最后給格子重新賦值一個(gè)新的材質(zhì),不然格子純白色的,不好看。
?
注意:改變預(yù)制物體后記得要apply一下,這樣我們改動(dòng)的東西才能應(yīng)用到之后創(chuàng)建的預(yù)制物體上。之后創(chuàng)建的格子都會(huì)照著新的格子去復(fù)制。
添加一個(gè)數(shù)字展示在格子上 我們需要一個(gè)數(shù)字來(lái)顯示本格子周圍有多少地雷。實(shí)現(xiàn)這個(gè)功能的一個(gè)簡(jiǎn)單方法就是使用Unity的3D文字。通過(guò)點(diǎn)擊GameObject ->CreateOther ->3DText創(chuàng)建,然后把它添加到格子上,就像這樣:
?
讓我們?cè)俑倪M(jìn)一下:旋轉(zhuǎn)text讓它面朝上。先給它賦個(gè)0值,這樣好讓我們能夠知道字體大小是否合適。還要調(diào)整字體和文本的大小,讓字體顯得清晰就行。
?
?
好了,現(xiàn)在我們還要在代碼中能夠訪問(wèn)3D文本,添加以下代碼: [C#]?純文本查看?復(fù)制代碼
把3D文本拖到對(duì)應(yīng)的變量上面:
?
再次提醒,改變預(yù)制物體需要應(yīng)用一下!
總結(jié) 我們已經(jīng)實(shí)現(xiàn)了掃雷游戲的基礎(chǔ)函數(shù),目前來(lái)說(shuō)還不能運(yùn)行,在下一個(gè)部分會(huì)添加更多的內(nèi)容,敬請(qǐng)期待。
我們的需求
從上面的規(guī)則中,我們可以推斷出掃雷簡(jiǎn)單版需要的幾個(gè)要素: · 布滿格子的網(wǎng)格 · 格子能夠填充一個(gè)雷的大小 · 格子能夠隨著鼠標(biāo)的點(diǎn)擊響應(yīng)事件 · 當(dāng)某個(gè)各自響應(yīng)鼠標(biāo)點(diǎn)擊事件時(shí),它能夠計(jì)算出周圍的雷的數(shù)量。
創(chuàng)建一個(gè)基本的格子
? ?? ? 新建一個(gè)Unity項(xiàng)目,再創(chuàng)建一個(gè)cube命名為Tile。將它拖到項(xiàng)目文件中作為一個(gè)預(yù)制物體。我們會(huì)用這個(gè)沒(méi)有腳本的格子作為玩的范圍,而后我們會(huì)添加腳本給他。
創(chuàng)建網(wǎng)格生成器 新建一個(gè)空的物體命名為Grid,同樣把它作為預(yù)制物體。它將作為游戲區(qū)域和所有格子的生成器。再新建一個(gè)Js腳本,命名為Grid,將其添加到Grid物體上面。Grid腳本主要?jiǎng)?chuàng)建了一個(gè)域,如下: [C#]?純文本查看?復(fù)制代碼
| 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() { } |
現(xiàn)在,網(wǎng)格生成器還沒(méi)有具體功能,在CreateTile()函數(shù)中添加以下代碼: [C#]?純文本查看?復(fù)制代碼
| 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); } |
?
這個(gè)函數(shù)復(fù)制了我們指定數(shù)量的格子,然后我們將他們放置一行,通過(guò)distanceBetweenTiles控制他們之間的距離。調(diào)整距離以達(dá)到適當(dāng)?shù)木嚯x。 對(duì)于掃雷游戲,我們需要的是讓格子擺成一個(gè)網(wǎng)格,而不是一條線。為了實(shí)現(xiàn)這種效果,我們還需要在Grid代碼的開始添加以下代碼:
[C#]?純文本查看?復(fù)制代碼
| public var tilesPerRow: int = 4; |
[C#]?純文本查看?復(fù)制代碼
| 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); ????} } |
如果你設(shè)置的tilesPerRow變量合適,生成器便會(huì)創(chuàng)建一個(gè)很棒的規(guī)則區(qū)域。如果你編程能力很強(qiáng)的話,你還可以嘗試更好的優(yōu)化方案。
將炸彈放入格子中
既然我們已經(jīng)創(chuàng)建了基座掃雷格子,那么我們就可以給它添加“炸彈”了。新建一個(gè)Js腳本,命名為Tile,并將它添到Tile預(yù)制物體上,然后聲明一個(gè)bool變量。 [C#]?純文本查看?復(fù)制代碼
| 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#]?純文本查看?復(fù)制代碼
| 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; ????} } |
?
讓格子看起來(lái)更有趣
現(xiàn)在,格子就矗立在Unity立方體上,讓我們把他們變成真的“格子”。在原文件中,你能夠找到一個(gè)叫做“puzzleObjects.fbx”的3D文件。把復(fù)制到的資源文件中,我們就能用它了。我們還要確保導(dǎo)入的文件它的比例為1,因?yàn)槲覀冎笆褂玫脑O(shè)置就是這個(gè)比例。 文件導(dǎo)入設(shè)置如下:
?
然后設(shè)置一下預(yù)制物體格子,用tileImproved替換掉立方體原有的mesh。
?
當(dāng)我們進(jìn)行到這一步,重置格子的BoxCollider組件。這么做會(huì)讓碰撞體更加契合格子。
?
最后給格子重新賦值一個(gè)新的材質(zhì),不然格子純白色的,不好看。
?
注意:改變預(yù)制物體后記得要apply一下,這樣我們改動(dòng)的東西才能應(yīng)用到之后創(chuàng)建的預(yù)制物體上。之后創(chuàng)建的格子都會(huì)照著新的格子去復(fù)制。
添加一個(gè)數(shù)字展示在格子上 我們需要一個(gè)數(shù)字來(lái)顯示本格子周圍有多少地雷。實(shí)現(xiàn)這個(gè)功能的一個(gè)簡(jiǎn)單方法就是使用Unity的3D文字。通過(guò)點(diǎn)擊GameObject ->CreateOther ->3DText創(chuàng)建,然后把它添加到格子上,就像這樣:
?
讓我們?cè)俑倪M(jìn)一下:旋轉(zhuǎn)text讓它面朝上。先給它賦個(gè)0值,這樣好讓我們能夠知道字體大小是否合適。還要調(diào)整字體和文本的大小,讓字體顯得清晰就行。
?
?
好了,現(xiàn)在我們還要在代碼中能夠訪問(wèn)3D文本,添加以下代碼: [C#]?純文本查看?復(fù)制代碼
| public var displayText: TextMesh; |
?
再次提醒,改變預(yù)制物體需要應(yīng)用一下!
總結(jié) 我們已經(jīng)實(shí)現(xiàn)了掃雷游戲的基礎(chǔ)函數(shù),目前來(lái)說(shuō)還不能運(yùn)行,在下一個(gè)部分會(huì)添加更多的內(nèi)容,敬請(qǐng)期待。
總結(jié)
- 上一篇: 【Unity3D开发小游戏】《扫雷》Un
- 下一篇: 控制台扫雷游戏