電子游戲中玩家與系統進行互動的樂趣絕大多數取決於事件發生的不可預知性和隨機性。在unity3D的API中提供了Random類來解決隨機問題。
最簡單的應用就是在數組中隨機選擇一個元素,使用Random內置的方法可以進行選擇。代碼如下:
Floatelement=myArray[Random.Range(0,myArray.Length)];
Random.Range方法的兩個參數代表了選擇數據元素的范圍。
很多時候,游戲中運用更復雜的隨機事件,下面描述幾種常見的隨機事件案例
1:隨機選擇具有不同概率的事件
當你你需要選擇具有不同發生概率的事件元素時。運用的場景為在游戲中玩家遇到NPC時,NPC在系統內部有好幾種與玩家交互的方法。但是這些方法發生的概率並不相等。例如有50%幾率進行問好;25%幾率跑開;20%幾率攻擊玩家;5%幾率為玩家提供禮品。
學過概率統計學的同學,一定做過在連續時間內發生事件概率的模型。我們也可以將上面描述的需求抽象為一個模型,我們將整個NPC與玩家交互系統看做一個紙帶,按照事件發生的概率將紙帶分為若干段,將大概率事件排在前面,小概率事件排在后面。當玩家遇到NPC時代表在這個紙帶上隨機選擇一個點。抽象結果用圖如下:
隨機選擇的點在哪個事件范圍內就會發生相應的事件。將這個模型用代碼表示為:
float Choose(float[] Probs) { //將事件元素加入到數組中,如上面有4個元素,分別為50,25,20,5 { float total=0; Foreach(float elem in probs ) Total+=elem; } //Random.value方法返回一個0—1的隨機數 float randomPoint=Random.value*total; for(int i=0;i<pros.Length;i++ ) { if(randomPoint<probs[i]) return i; else randomPoint-=probs[i]; } return probs.length-1; }
過程描述:首先檢查隨機數是否小於第一個元素,如果小於那么第一個元素就被選擇了。否則用隨機數的值減去第一個元素的值然后與第二個元素進行比較,以此類推直到找到正確的元素為止。
過程驗證:如上圖所示,假如隨機數最終為82,那么首先將82與第一個元素50比較:82>50,因此應該將82-50=32與第二個元素25進行比較:32>25,因此應該將32-25=7與第三個元素20進行比較:7<20,那么第三個元素被選中,相對應的事件發生。
2:使用隨機數打亂數組順序
這個案例應用的最好場景就是紙牌游戲中的洗牌操作,思想也比較簡單,就是依次將數組內的每個元素與一個隨機序號的元素進行交換。代碼如下:
void Shuffle(int[] cards) { for(i=0;i<cards.Length;i++) { int temp=cards[i]; int randomIndex=Random.Range(0,cards.Length); cards[i]=cards[randomIndex]; cards[randomIndex]=temp; } }
3:使用隨機數在數組中無重復的選擇元素
在概率論中我們常常見到這樣題目:一個球隊10個人,要選擇5個人去參加比賽。在游戲中的應用場景為你希望在幾個不同的點隨機生成一個不相同的NPC。例如需要在10個NPC中隨機選擇5個,第一個NPC被選中的概率為5/10,如果第一個被選中了那么第二個被選中的概率就變成了4/9,如果第一個被淘汰那么第二個被選中的概率就為5/9
Transform[] spawnPoints; Transform[] ChooseSet(int numRequired) { Transform [] result=new Transform[numRequired]; Int numToChoose=numRequired; for(int numLeft=spawnPoints.Length;numLeft>0;numLeft--) { float prob=(numToChoose+0.0)/(numLeft+0.0); if(Random.value<=prob) { numToChoose--; result[numToChoose]=spawnPoints[numLeft-1]; if(numToChoose==0) break; } } return result; }
過程描述:掃描待選擇的NPC數組,如果生成的隨機數小於被選中的概率則表示該元素被選中,直到所需要的元素個數都被選中。
注意點:進行選擇的時候應該先將待選擇的NPC數組進行“洗牌“操作。