具有随机速度的二维粒子系统

时间:2011-08-17 20:09:14

标签: c# .net gdi+ xna-4.0

我最近使用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代码中没有我调用randomize函数的地方,我注意到如果我这样做,我的粒子会有类似的模式行为。请原谅所有奇怪的算术,这只是实验。

3 个答案:

答案 0 :(得分:3)

好的,你要修复它的问题是创建一个没有种子的单个Random对象(你是),然后一遍又一遍地使用它。如下所示:

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;
}

要获得下限和上限之间的随机浮点值(浮点数或双精度数),可以使用以下内容:

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

编辑:并确保使用double或float。 Ints只是整数,双精度和浮点数可以存储实数,可能是VB使用的。

答案 1 :(得分:1)

如果您发布了一些代码,我们可能会指出您为每次调用创建new Random()对象的位置。

例如,Random number in a loop


看到代码后,

你知道(rnd.Next(2000)-1000)/100是一个只有整数的表达式吗?结果将转换为float,但始终以##.0结尾。

在VB I / J中产生一个双精度数。

答案 2 :(得分:-1)

随机类确保伪随机性,如果这是你正在使用的。看看RNGCryptoServiceProvider