2011-08-17 71 views
1

我最近使用Visual Basic .Net編寫了一個粒子系統,該系統在x和y方向上發射具有隨機速度的粒子並受重力影響。我切換到C#.Net並使用了XNA Game Studio,這使得圖形處理比GDI +更加方便。具有隨機速度的二維粒子系統

我用C#的問題是隨機數不是「足夠隨機」的。我的粒子系統有2500個粒子,但您可以清楚地看到粒子以大約100像素的網格狀分佈,我沒有使用Visual Basic的Rnd()函數發生這種問題。

什麼是Visual Basic做哪些C#沒有,以及如何在C#中獲得相同的結果?

我試圖在遊戲循環的不同階段重新初始化我的隨機數,但最終我的粒子停留在一個位置或者只是在一個方向上發射恆定流。

這是我的C#代碼:在程序啓動後首先調用LoadContent。我使用毫秒作爲種子,以便每次使用不同的配置啓動。

下一次我重新種子是在渲染之前在系統上完成所有計算。我嘗試的另一種方法是在計算出每100個粒子後重新播種,但沒有區別。

 protected override void LoadContent() 
    { 
     // Create a new SpriteBatch, which can be used to draw textures. 
     spriteBatch = new SpriteBatch(GraphicsDevice); 
     mousePos = Content.Load<Texture2D>("Point"); 
     spriteTex = Content.Load<Texture2D >("Point"); 
     rnd = new Random(a.Millisecond); 
     for (int i = 0; i < spritePos .Length; i++) 
     { 
      newPos[i] = new Vector2(800, 450); 
      spritePos[i] = newPos[i] ; 
      Scale[i] = rnd.Next(100,500); 
      renderCol[i] = new Color(rnd.Next(255), rnd.Next(255), rnd.Next(255), 1); 
      spriteVelocity[i] = new Vector2((rnd.Next(2000)-1000)/100, -rnd.Next(500,1500)/100); 
      Life[i] = rnd.Next(60); 
      Rotate[i] = (rnd.Next(1000)-500) * 0.001f; 
      RotateSpeed[i] = (rnd.Next(1000)-500) * 0.0001f; 

     } 

    } 

這是我的VB代碼,在這裏我用的是RND功能的唯一的地方:

  For i = x To x + 1000 
       ptc(i) = New particle(New Vector((Rnd() * 200) - 200 * Rnd(), Rnd() * -100 - 200 * Rnd() - 200), New Vector(e.X, e.Y), 500, Color.FromArgb(Rnd() * 255, 255, 0)) 
       x += 1 
      Next 

在我的VB代碼沒有任何地方我所說的隨機化功能,我已經注意到,我的如果我這樣做,粒子具有相同的模式行爲。請原諒所有奇怪的算術,這都只是實驗。

+0

你能告訴我們你的代碼(包括VB.net和C#)嗎? – dtb

+0

你能發佈一段代碼嗎?也就是說,初始化新粒子並設置其速度的代碼。 –

+0

另外,確保你沒有爲你想創建的每個隨機數創建一個新的隨機實例[(link)](http://stackoverflow.com/questions/767999/random-number-generator-not-working -the路-I-有計劃的-C)。 – dtb

回答

3

好的,你如何解決它查爾,是創建一個沒有種子的單個隨機對象(你是),並反覆使用它。因此,像:

const double max = 1000.0; 
Random rand = new Random();  // Like mentioned, don't provide a seed, .NET already picks a great seed for you 
for(int iParticle = 0; iParticle < 2500; iParticle++) 
{ 
    double x = rand.NextDouble() * max;  // Will generate a random number between 0 and max 
    double y = rand.NextDouble() * max; 
} 

要獲得之間的隨機浮點值(float或double),下限和上限,您可以使用類似:

double x = (rand.NextDouble() * (max - min)) + min; 

編輯:並確保使用雙倍或浮動。Ints只是整數,雙打和浮點數可以存儲實數,並且可能是VB使用的。

+0

注意:如果你實際上需要一個Integer值,比如Color,使用rand.Next(255)是完美的,那就是你應該使用的。 –

+0

非常感謝,這是完美的解決方案!所以整數是問題。 –

+0

我不介意它的顏色,它有點難以看到任何圖案,但現在我的粒子實際上是「隨機的」。 –

-1

隨機類確保僞隨機性,如果這是你正在使用的。看看RNGCryptoServiceProvider

+0

我讀過很多關於隨機數和CSRNG在這個論壇上的大部分內容,在統計中我們也學到了關於僞隨機數的知識,而且他們實際上並不是隨機的,我錯誤的是簡單的VB函數Rnd()我得到了足夠的結果,但C#沒有。他們都是.Net,所以我想他們會使用相同的算法,但C#沒有Rnd()函數。 –

1

如果您發佈了一些代碼,我們可能已經能夠指出您爲每次調用創建一個new Random()對象的位置。

像,例如,Random number in a loop


看到代碼後,

你知道(rnd.Next(2000)-1000)/100是一個整數只體現在哪裏?結果將被轉換爲float,但始終以##.0結束。

在VB I/J中產生了兩倍。

+0

謝謝,但在循環中聲明我的隨機數只是使我的粒子似乎「圍繞原點轉動,它根本不移動,這就是爲什麼我如此難倒,任何試圖彌補我的困境的嘗試只會使它更加惡化,但我確信有一個解決方案。 –

+0

是的,我試過了約翰麥克的答案,這確實是讓我知道的整數oblems和C#抱怨類型轉換比VB要多得多。 –