?

基于Unity3D游戲引擎的三消類游戲算法的設計與實現

2021-09-10 05:49章國雁
鞍山師范學院學報 2021年4期
關鍵詞:數組寶石語句

章國雁

(安徽工商職業學院 信息工程學院,安徽 合肥 231131)

隨著游戲行業的發展,中國游戲用戶的數量呈現爆發式的增長.新型冠狀病毒肺炎疫情雖然影響了一些行業的發展,卻促進了游戲行業的進一步發展.隨著游戲行業的發展,出現了各類型的游戲,如射擊類、休閑類、動作類、RPG類、解密類等.在各類型的游戲中,休閑娛樂類的輕度游戲一直受到用戶的歡迎,因為現代社會工作節奏快、壓力大,人們希望在工作間隙能夠有個適度的放松休閑.休閑類游戲由于較好利用了用戶的碎片化時間,其游戲玩法簡單、快速上手,因此擁有龐大的用戶群體.

近些年,不少學者對使用游戲引擎進行游戲開發做了較多的研究,李昊宇[1]在基于Unity3D的橫版過關游戲一文中介紹了經典的過關游戲“馬里奧”,并在之前的傳統玩法基礎上加入了新的玩法和創意;孟子權等[2]在基于Unity3D的環境保護類游戲研究與實現一文中提出了游戲與環境保護主題相結合的創意設計,讓用戶在玩游戲的同時更多地關注環境保護;張勝男等[3]在基于Unity3D的尋寶游戲的設計與制作一文中實現了以各類生活知識為線索、以拓展知識為目的的尋寶游戲,兼顧了娛樂和教育的內容;陳麗梅等[4]分析了基于Unreal Engine的第三人稱動作游戲的設計與實現;郭建軍等[5]、岳書丹等[6]、付夢遠等[7]對使用Unity3D引擎制作塔防類游戲進行了研究與實現.以上學者的研究成果給游戲開發從業人員提供了新的創意和思路.

1 案例概要

本文以Unity3D游戲引擎為開發平臺,使用C#程序設計語言,介紹一款三消類休閑游戲“寶石迷陣”的算法設計及實現步驟.游戲以寶石為主題,通過移動交換位置相鄰的2個寶石,當相鄰的3個或3個以上寶石類型匹配相同時,系統自動消除寶石并給予相應獎勵,當獎勵達到滿足條件時給予通關.

2 案例關鍵節點的算法設計及實現思路

2.1 如何隨機產生不同類型的寶石矩陣

為了增加游戲的趣味性,“寶石迷陣”游戲提供9種不同類型的寶石樣式,剛開始運行時,初始界面隨機產生7行10列不同類型的寶石矩陣,如圖1所示.設計思路:(1)使用普通數組gemstoneBgs[]存儲9種不同類型的寶石樣式,當寶石被生成時,從數組中隨機產生一種寶石樣式;(2)使用動態數組gemstoneList來存儲游戲運行時產生的7行10列共70個寶石,可以通過一個雙重循環語句把寶石順序存儲在動態數組中,由于動態數組可以動態增加或減少數組的大小,可以很好地適應游戲運行過程中寶石被消除和生成時的數量動態變化,具有較好的擴展性.

圖1 隨機產生不同類型寶石矩陣

2.2 如何實現相鄰寶石的位置交換

要實現寶石的交換,需要同時滿足以下條件:(1)第一次點擊的寶石和第二次點擊的寶石進行交換,第二次點擊的寶石不能和第三次點擊的寶石交換,即以2次點擊為一個交換循環,交換過后重新開始;(2)相互交換的寶石必須在位置上屬于水平方向上相鄰或者垂直方向上相鄰.針對第一個條件,本文通過設定一個臨時變量currentGemstone來保存第一次被點擊的寶石.當寶石第一次被點擊時,判斷currentGemstone的值,如果為空,則存儲當前被點擊的寶石;如果不為空,則進入第二個條件判斷.針對第二個條件的解決思路為:當第一次被點擊的寶石,即currentGemstone里存儲的寶石和第二次被點擊的寶石進行交換前,需要計算出兩個寶石的行坐標差值和列坐標差值的和;當行差值和列差值二者和為1時,表示兩個寶石處于行相鄰或者列相鄰,可以進行交換操作,否則不滿足第二個條件,不能進行寶石交換.

2.3 如何檢測相同類型的寶石

當寶石被初始化生成或者被點擊交換后,程序需要檢測是否有相同類型的寶石,發現有相同的寶石則進行消除.相同類型寶石的判斷條件為:同一行里面的寶石超過3個相鄰的寶石為相同類型;或者同一列里面的寶石超過3個相鄰的寶石為相同類型.針對以上條件,程序實現的思路為:(1)首先判斷每一行的寶石.通過使用雙重循環語句,外循環為遍歷每一行,內循環為遍歷當前行的每一列,取出當前列的寶石和當前列后一位(即當前列的值+1)的寶石、當前列的寶石和當前列后兩位(即當前列的值+2)的寶石倆倆進行比較,如果寶石的類型相同,則判斷參與比較的相鄰3個寶石為當前行相同類型的寶石,暫時保存相同類型的寶石到matchesGemstone動態數組中.(2)接著判斷每一列的寶石.再次通過使用雙重循環語句,外循環為遍歷每一列,內循環為遍歷當前列的每一行,取出當前行的寶石和當前行上面一位(即當前行的值+1)的寶石、當前行的寶石和當前行上面兩位(即當前行的值+2)的寶石倆倆進行比較,如果寶石的類型相同,則判斷參與比較的相鄰3個寶石為當前列相同類型的寶石,暫時保存相同類型的寶石到matchesGemstone動態數組中.

2.4 如何消除和增補寶石

通過程序檢測到相同類型的寶石后,不能馬上消除寶石,因為可能會存在3個以上相鄰的寶石或者行列交叉都相同的寶石情況,程序需要先暫時保存所有相同的寶石到matchesGemstone動態數組,待所有行和所有列全部檢測結束后,統一進行消除.當相同的寶石被消除后,游戲需要及時進行寶石的增補,便于玩家進行下一次的操作.寶石的消除和增補功能實現思路為:(1)循環遍歷保存著相同類型寶石的matchesGemstone動態數組,消除遍歷到的當前寶石;(2)讀取當前被消除的寶石所在列,循環遍歷該列的每一個寶石,從當前寶石的上一行開始,向下一行移動一個位置,從下往上依次對該列的所有寶石做位移操作后,在該列的最上方空出一個位置等待寶石的增補;(3)實例化一個新的寶石物體,從寶石樣式數組gemstoneBgs[]中隨機取出一個寶石,放在空出的位置上.通過以上步驟實現了寶石消除和增補的算法.

3 案例關鍵節點的算法實現

基于上述的程序算法和實現思路,在Unity3D引擎中實現寶石迷陣游戲案例的制作,其關鍵節點的實現步驟如下:

3.1 資源導入和寶石預制體創建

在Unity3D引擎的Project窗口中,導入本案例的資源包,包含有9張不同效果的寶石圖片和1張游戲背景圖片,背景音樂和寶石交換、匹配、銷毀、生成時的各種音效.將9張寶石圖片類型從普通Texture修改為精靈Sprite(2D and UI)類型.為了增強游戲界面中寶石的顯示效果,適當放大每個寶石的大小,依次修改每個寶石圖片X軸和Y軸的縮放項數值為1.2,保存每個寶石圖片為預制體,如圖2所示.

圖2 9種類型的寶石預制體

3.2 寶石的初始化和隨機生成

游戲初始界面需要生成一個7行10列的寶石矩陣,如圖1所示.通過一個雙重循環語句保存生成的寶石,外循環語句保存每一行的寶石,內循環語問保存當前行中遍歷的每一列寶石,其部分核心代碼如下:

public Gemstone gemstone;//寶石變量

public int rowNum = 7;//行數

public int columnNum = 10;//列數

public ArrayList gemstoneList;//動態數組,用來保存生成的寶石

void Start () {

gemstoneList = new ArrayList ();//數組的初始化

//雙重循環語句順序存儲每一個生成的寶石

for (int rowIndex = 0;rowIndex < rowNum;rowIndex++) {

//臨時動態數組,用來存儲當前行的每一列寶石

ArrayList temp = new ArrayList();

for(int columnIndex=0;columnIndex < columnNum;columnIndex++){

Gemstone gemstone = AddGemstone(rowIndex,columnIndex);

temp.Add (gemstone);

}

gemstoneList.Add (temp);

}

}

每個寶石在生成時需要隨機產生一個類型.通過實例化函數Instantiate()生成寶石,通過隨機讀取寶石類型數組gemstoneBgs[]的值產生不同的寶石.其部分核心代碼如下:

//生成寶石函數

public Gemstone AddGemstone(int rowIndex,int columnIndex){

Gemstone gemstone = Instantiate (gemstone) as Gemstone;//實例化生成寶石

gemstone.transform.parent = this.transform;//指定位置

gemstone.RandomCreateGemstoneBg();//生成隨機的寶石類型

return gemstone;

}

//生成隨機的寶石類型函數

public void RandomCreateGemstoneBg(){

gemstoneType = Random.Range (0,gemstoneBgs.Length);//隨機產生一個0至數組長度之間的整數值

gemstoneBg = Instantiate(gemstoneBgs[gemstoneType]) as GameObject;//產生一種寶石的樣式

gemstoneBg.transform.parent = this.transform;//指定位置

}

3.3 寶石的點擊和交換

當寶石第一次被點擊時,需要存儲到currentGemstone變量中,等待和下一次被點擊的寶石進行交換,同時在交換之前需要判斷兩者是否在同一行相鄰或者同一列相鄰,其部分核心代碼如下:

//點擊寶石函數

public void Select(Gemstone gemstone){

if (currentGemstone == null) {//第一次點擊

currentGemstone = gemstone;//保存當前點擊的寶石

currentGemstone.isSelected = true;//標記該寶石為已選中

return;

}else{//第二次點擊

if( Mathf.Abs(currentGemstone.rowIndex - gemstone.rowIndex)+Mathf.Abs(currentGemstone.columnIndex - gemstone.columnIndex) == 1 ){

//如果寶石相鄰,則進行交換

StartCoroutine (ExangeAndMatches(currentGemstone,gemstone));

}else{

audio.PlayOneShot(errorClip);//播放交換失敗的音效

}

currentGemstone.isSelected = false;//重置標志位

currentGemstone = null;//清空

}

}

3.4 檢測相同類型的寶石

根據上述2.3節的判斷條件,程序先后檢測行方向和列方向的所有寶石類型,即寶石的gemstoneType字段值,該字段為整型,如果參與比較的寶石gemstoneType相同,則為相同類型的寶石.以檢測每一行的寶石為例,其部分代碼如下:

bool CheckHorizontalMatches(){//實現檢測水平方向的寶石類型

bool isMatches = false;

for (int rowIndex = 0;rowIndex < rowNum;rowIndex++) {//遍歷行

for(int columnIndex =0;columnIndex < columnNum - 2;columnIndex++){//遍歷列

//判斷相鄰寶石的gemstoneType值

if((GetGemstone (rowIndex,columnIndex).gemstoneType == GetGemstone (rowIndex,columnIndex+1).gemstoneType ) && (GetGemstone (rowIndex,columnIndex).gemstoneType == GetGemstone (rowIndex,columnIndex+2).gemstoneType )){

AddMatches (GetGemstone (rowIndex,columnIndex));//存儲相同寶石

AddMatches (GetGemstone (rowIndex,columnIndex+1));//存儲相同寶石

AddMatches (GetGemstone (rowIndex,columnIndex+2));//存儲相同寶石

isMatches = true;

}

}

}

return isMatches;

}

3.5 消除和增補寶石

程序檢測完成,如果發現相同類型的寶石,則需要進行消除操作,使用循環語句遍歷matchesGemstone動態數組,刪除該數組保存的每一個元素(寶石).寶石刪除后,需要移動寶石的位置進行填充,并生成新的寶石.以消除為例其部分核心代碼如下:

//遍歷matchesGemstone動態數組消除寶石

void RemoveMatches(){

for(int i=0;i< matchesGemstone.Count;i++){

Gemstone gemstone = matchesGemstone[i] as Gemstone;

RemoveGemstone(gemstone);//調用消除寶石函數

}

matchesGemstone = new ArrayList ();

}

4 結束語

寶石迷陣游戲案例注重三消類游戲的算法設計與實現過程,使用Unity3D游戲引擎作為開發平臺,后期可以發布到普通PC電腦、Mac電腦、安卓、IOS、平板、游戲主機等多種平臺,使本游戲案例具備較好的跨平臺特性.本案例游戲算法的設計思路對于游戲開發的教學和行業應用有積極的促進作用.

猜你喜歡
數組寶石語句
JAVA稀疏矩陣算法
“種”棵寶石樹
JAVA玩轉數學之二維數組排序
更高效用好 Excel的數組公式
寶石迷蹤
尋找勾股數組的歷程
寶石樹
上樹捉魚
基本算法語句
我喜歡
91香蕉高清国产线观看免费-97夜夜澡人人爽人人喊a-99久久久无码国产精品9-国产亚洲日韩欧美综合