在上一篇我們生成了盤面上的珠子,並且隨機給了珠子屬性,接著我們需要把同屬性且相連的珠子分成同群組,方便日後計算combo,下圖是這次的目標。
首先要對Orb與PuzzleSystem腳本追加變數。
Orb腳本新增的變數。
using UnityEngine; using System.Collections.Generic; using UnityEngine.UI; public class Orb : MonoBehaviour { . . . public List<Orb> linkOrbs = new List<Orb>(); public bool group = false; public Text groupNum; void Start() { . . . } }linkOrbs用來儲存與自己相鄰珠子的Orb腳本,也就是上下左右的珠子,如下圖。
group是用來判斷該珠子是否已經被分配群組。
groupNum會顯示編號,使用Text物件。
Text新增在珠子預設物件下,滑鼠拖曳帶入,Text字體大小、顏色容易辨識就好。
在PuzzleSystem腳本中新增變數與設定變數。
using UnityEngine; using System.Collections.Generic; public class PuzzleSystem : MonoBehaviour { . . . public List<Orb> orbs = new List<Orb>();////(1) public List<List<Orb>> orbGroups = new List<List<Orb>>(); void Start() { InitGrid(); } void InitGrid() { . . . for (int r = 0; r < rowCount; r++) { for (int c = 0; c < columnCount; c++) { . . . orbs.Add(orb);////(2) } } for(int index = 0; index < orbs.Count; index++)////(3) { if (orbs[index].column != columnCount - 1)////(4) orbs[index].linkOrbs.Add(orbs[index + 1]); if(orbs[index].row != rowCount - 1) orbs[index].linkOrbs.Add(orbs[index + columnCount]); if (orbs[index].column != 0) orbs[index].linkOrbs.Add(orbs[index - 1]); if (orbs[index].row != 0) orbs[index].linkOrbs.Add(orbs[index - columnCount]); } } . . . }(1)PuzzleSystem中要新增兩個List,orbs一維List會儲存盤面中所有珠子的Orb腳本。
orbGroups二維陣列會儲存珠子的群組。
(2)在產生盤面的迴圈中,把當前的珠子腳本新增到orbs一維List中。
(3)最後在InitGrid函式結束前,設定珠子腳本下的linkOrbs,依序為右、上、左、下的珠子。
(4)透過if判斷排除四邊與角落的連結,例如最下一列的珠子不會有下面珠子的連結,最右一行不會有右邊珠子的連結。
做好上面的前置動作後,可以開始把珠子分群組。
在PuzzleSystem腳本中宣告分群函式。
using UnityEngine; using System.Collections.Generic; public class PuzzleSystem : MonoBehaviour { . . . public List<Orb> orbs = new List<Orb>(); public List<List<Orb>> orbGroups = new List<List<Orb>>(); void Start() { InitGrid(); OrbGroup(); } . . . void FindMembers(Orb orb, int groupNum) {}////(1) void OrbGroup()////(2) { orbGroups.Clear(); foreach (Orb orb in orbs)////(3) { if (orb.group == false)////(4) { orbGroups.Add(new List<Orb>());////(5) int groupNum = orbGroups.Count - 1;////(6) orbGroups[groupNum].Add(orb);////(7) orb.group = true;////(8) orb.groupNum.text = (groupNum).ToString();////(9) FindMembers(orb, groupNum);////(10) } } } }新增函式FindMembers與OrbGroup。
(1)FindMembers的參數為Orb腳本元件與整數的群組編號,至於函數中要執行的動作稍後再談。
(2)OrbGroup函式會在Start中呼叫,在InitGrid函式之後執行。
(3)使用迴圈找沒有加入群組的珠子。
(4)當orb.group == false成立,代表找到沒加入群組的珠子,執行條件式中的程式。
(5)建立新的珠子List,並新增到orbGroups中。
(6)宣告群組編號groupNum,並將數值設定為新增List的編號。
(7)將目前這顆沒有群組的珠子加入這個新增的List。
(8)將當前的珠子group設為true,表示它已經被加到某個群組中。
(9)設定Text元件的顯示文字,文字內容為群組編號。
(9)呼叫FindMembers函式,帶入參數為當前的珠子和編號。
到這裡可以先執行看看。
可以看到每個珠子都被給了一個群組編號,表示群組建立是成功的,接著我們要透過FindMembers函式內容找到同群組的珠子。
void FindMembers(Orb orb, int groupNum) { foreach (Orb linkOrb in orb.linkOrbs)////(1) { if (linkOrb.type == orb.type && linkOrb.group == false)////(2) { orbGroups[groupNum].Add(linkOrb);////(3) linkOrb.group = true; linkOrb.groupNum.text = groupNum.ToString(); FindMembers(linkOrb, groupNum);////(4) } } }(1)進入FindMembers函式,要搜尋的是與當前珠子相連的珠子,也就是linkOrbs。
(2)當相鄰珠子類型與當前珠子屬性相同,而且相鄰珠子又沒有加入群組時。
(3)加入當前的群組、設定group值、修改Text文字。
(4)再次呼叫FindMembers,這次要找的是這個相鄰珠子的linkOrbs,直到所有相連同屬性的珠子都加入群組為止。
以下是逐步執行的結果。
以上就是珠子相連判斷的說明,接著下一步就是消除珠子,而這篇做的相連判斷在消除時,會被歸類為同combo,當然這個做法有一個超有名的邏輯錯誤─W珠,這個問題就以後再說吧。
這次就到這裡。
2016/08/06修正:
進入OrbGroup函式第一行新增了orbGroups.Clear();,因為orbGroups會在之後重複使用,所以透過Clear來初始化群組。
沒有留言:
張貼留言