Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

Okay so this is kind of weird, I have some code that creates particle.cs instances

 public void AddParticle()
    {
        for (int i = 0; i < Density; i++)
        {
        particle = new Particle();
        Randomnum = new Random();
        Direction = Randomnum.Next(360);
        InitialVel = AngleToVector(Direction);
        particle.Initialize(Texture, Position, 10, 2, InitialVel);
        particles.Add(particle);
        }
    }

When I set a breakpoint on particles.add I can see that the InitialVel is different for each entry in the particles list. When it gets down to the draw function the initialvel is the same in each and every entry in particles list thus they all draw on top of each other.

the wierd thing is when i set the breakpoint at particles.add and f5 through each of the 10 steps of the for loop the game pops up after the break points are done and all 10 particles are going in random directions as intended but without the break points they are stacked on top of one another and the InitialVel are all the same when it reaches the for loop in the draw method.

Emitter.cs Particle.cs

share|improve this question

2 Answers 2

up vote 2 down vote accepted

You should not be creating a new Random() in each call to AddParticle(), though you would expect each Random() call to use a new time-dependent seed. The problem is explained in MSDN:

The default seed value is derived from the system clock and has finite resolution. As a result, different Random objects that are created in close succession by a call to the default constructor will have identical default seed values and, therefore, will produce identical sets of random numbers. This problem can be avoided by using a single Random object to generate all random numbers.

This is why you see different behaviour when stepping through the code, because then several timesteps will surely pass between each Random() call.

The solution is straightforward, you already have Randomnum as a property of the Emitter, just seed it in Initialize() instead of AddParticle():

public void Initialize(Texture2D texture, Vector2 position,int density,int life,GameTime gameTime, float gravity)
{       
    Randomnum = new Random();
    particles = new List<Particle>();
    Texture = texture;
    Active = true;
    Position = position;
    Density = density;
    Life = life;
    timeCreated = gameTime.TotalGameTime;
    timeToLive = TimeSpan.FromSeconds(Life);
    Gravity = gravity;
    yvel = 0;

    AddParticle();  
}

public void AddParticle()
{
    for (int i = 0; i < Density; i++)
    {
    particle = new Particle();
    Direction = Randomnum.Next(360);
    InitialVel = AngleToVector(Direction);
    particle.Initialize(Texture, Position, 10, 2, InitialVel);
    particles.Add(particle);
    }
}
share|improve this answer
    
Thank you for the answer. Got my problem solve thanks. –  steakbbq Feb 19 '12 at 6:54

Don't create a random generator in each call to the AddParticle() method.

It will return always the same value.

Also you may want to pass a different seed to the the generator each time you create it, then you can use DateTime.Now.Millisecond as seed.

static readonly Randomnum = new Random(DateTime.Now.Millisecond);

public void AddParticle()
    {
        for (int i = 0; i < Density; i++)
        {
        particle = new Particle();
        Direction = Randomnum.Next(360);
        InitialVel = AngleToVector(Direction);
        particle.Initialize(Texture, Position, 10, 2, InitialVel);
        particles.Add(particle);
        }
    }
share|improve this answer
1  
Make fields that are read only static readonly. There is a small JITter performance implication of doing it this way. –  Jonathan Dickinson Feb 16 '12 at 9:04
    
+1 To add to this answer: The reason you see different values when you are debugging is because new Random(); uses a time-dependent seed and when you're looking at the code, time is passing. When the code is allowed to execute without interruptions, the time-dependent seed will always be the same and thus the "random" numbers will all be the same. –  John McDonald Feb 16 '12 at 21:19

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.