在上一篇我們生成了盤面上的珠子,並且隨機給了珠子屬性,接著我們需要把同屬性且相連的珠子分成同群組,方便日後計算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來初始化群組。






沒有留言:
張貼留言