2011-10-13 76 views
2

我做了這個代碼來加載大約8個不同的紋理到具有紋理屬性的對象列表。XNA隨機選擇的紋理總是選擇相同的紋理

我有一個名爲「1.png,2.png,3.png,.......,46.png」的紋理的文件夾,我想用隨機選擇的紋理加載8個不同的對象。

 DockedFruitsList = new List<Fruit>(8); 
     for (int i = 0; i < 8; i++) 
     { 
      Fruit temp = new Fruit(); 
      temp = new Fruit(); 
      temp.Position = AvailablePositions[i]; 
      int random=(new Random().Next(0, 4600) % 46); 
      temp.Texture = Content.Load<Texture2D>(@"Fruits/" + random); 
      DockedFruitsList.Add(temp);   

     } 

的事情是,儘管隨機總是產生不同的號,抽籤的結果總是相同的紋理,它從運行到另一個運行的變化,但它總是對所有的8個紋理

相同
spriteBatch.Begin(); 
     for (int i = 0; i < DockedFruitsList.Count; i++) 
     { 
      spriteBatch.Draw(DockedFruitsList[i].Texture, DockedFruitsList[i].Position, Color.White); 
     } 
     spriteBatch.End(); 

回答

5

嘗試了這一點:

for (int i = 0; i < 100; i++) 
    Console.WriteLine(new Random().Next(0, 10)); 

賠率是,你會得到一個輸出這樣的:

5 
5 
5 
. 
. 
. 

這是因爲Random類的種子使用基於時間的值進行初始化。如果在相同的時間點初始化類的許多實例,那麼它們都將以相同的種子結束,因此它們將生成的值將全部相同。

你真正想要做的是創建一個Random實例並將其用於所有的隨機值。生成的值不會有任何關係對方:

var r = new Random(); 
for (int i = 0; i < 100; i++) 
    Console.WriteLine(r.Next(0, 10)); 

輸出:

2 
8 
0 
. 
. 
. 
+0

我已經確信,隨機的輸出是不同的數字,他們的問題是 Content.Load的執行(@「Fruits /」+ random); – SKandeel

+2

如果你在調試暫停的時候這樣做了,那麼它有可能改變。 –

+0

是的,你是對的:) 非常感謝你... – SKandeel

2

從MSDN:

從種子值的隨機數生成開始。 如果重複使用相同的種子,則會生成同一系列的數字。 默認情況下,Random類的參數的構造函數使用系統時鐘產生的種子值

它僅改變其值每隔幾毫秒,所以如果你非常快速調用 new Random()它會得到種子

系統時鐘使用相同的號碼,因此撥打Next...將產生相同的結果。

請注意,如果您對其進行了調試,則逐步執行代碼會使系統時鐘前進,因此,除非通過循環運行,否則不會出現錯誤,而不會中斷/逐步執行。


創建Random對象一次,並重新使用它(注意:現在我將random字符串和我打過電話隨機太不同的方法):

var rand = new Random(); 
    DockedFruitsList = new List<Fruit>(8); 
    for (int i = 0; i < 8; i++) 
    { 
     Fruit temp = new Fruit(); 
     temp = new Fruit(); 
     temp.Position = AvailablePositions[i]; 
     int random=(rand.Next(46) + 1); 
     temp.Texture = Content.Load<Texture2D>(@"Fruits/" + random.ToString()); 
     DockedFruitsList.Add(temp);   

    } 
0
new Random().Next(0, 4600) 

意味着你初始化每次(?也許使用相同的種子)RNG 之外將新該方法(靜態成員或類似)。

0

Random被播種的時間(GetTickCount()),時間只改變每隔幾毫秒。因此,在該間隔內創建的所有隨機實例將返回相同的序列。正確的事情是隻在循環外部創建一個Random的實例。

 DockedFruitsList = new List<Fruit>(8); 
     Random rand = new Random(); 
     for (int i = 0; i < 8; i++) 
     { 
      Fruit temp = new Fruit(); 
      temp = new Fruit(); 
      temp.Position = AvailablePositions[i]; 
      int random=(rand.Next(1, 46)); 
      temp.Texture = Content.Load<Texture2D>(@"Fruits/" + random); 
      DockedFruitsList.Add(temp);   

     } 

檢查Revisiting randomness瞭解更多詳情。

也沒有理由使用rand.Next(0, 4600)%46。您可以直接使用rand.Next(0,46)

請注意,該代碼仍然會返回重複條目。如果你想避免這種情況完全可以使用:

Random rand=new Random(); 
foreach(int randomFruid in Range(1,46).Shuffle(rand).Take(8)) 
{ 
    ... 
} 

隨着ShuffleIs using Random and OrderBy a good shuffle algorithm?

+0

他的文件名從1開始。 –

+0

他還需要'ToString'是'random'變量。 –

+0

謝謝..那就像一個魅力:) – SKandeel