2D система частиц со случайными скоростями - PullRequest
1 голос
/ 18 августа 2011

Я недавно использовал Visual Basic .Net для написания системы частиц, которая испускает частицы со случайными скоростями в направлениях x и y и зависит от силы тяжести.Я переключился на C # .Net и использовал XNA Game Studio, которая делает обработку графики намного более удобной, чем GDI +.

Проблема, с которой я столкнулся в C #, состоит в том, что случайные числа не являются «достаточно случайными».В моей системе частиц 2500 частиц, но вы можете четко видеть, что частицы распределены по сетке примерно на расстоянии 100 пикселей, и у меня не было этой проблемы с функцией Rnd () в Visual Basic.

Что такое VisualBasic делает то, чего нет в 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-коде нет места, где я вызываю функцию рандомизации, я заметил, что мои частицы, как и я, ведут себя аналогично образцу.Извините за странную арифметику, это всего лишь эксперименты.

Ответы [ 3 ]

3 голосов
/ 18 августа 2011

Хорошо, что вы делаете, чтобы исправить это, Чарльз, - это создать один случайный объект (которым вы являетесь) без начального числа и использовать его снова и снова.Так что-то вроде:

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.Целые числа - это только целые числа, двойные и плавающие числа могут хранить действительные числа и, вероятно, это то, что использовал VB.

1 голос
/ 18 августа 2011

Если бы вы опубликовали некоторый код, мы, вероятно, смогли бы указать, где вы создаете объект new Random() для каждого вызова.

Как, например, Случайное число вloop


После просмотра кода

знаете ли вы, что (rnd.Next(2000)-1000)/100 является целочисленным выражением?Результат будет преобразован в float, но всегда заканчивается ##.0.

В VB I / J дает двойное значение.

0 голосов
/ 18 августа 2011

Случайный класс обеспечивает псевдослучайность, если это то, что вы используете. Взгляните на RNGCryptoServiceProvider .

...