June 26th, 2011, 12:57 PM
Magically static members
I have a simple MovingSquare class. I create an array of several of them and then randomly assign some values in the constructor. Each square has their own separate random color and random rotation velocity set in the constructor. When i create individual MovingSquare objects and then update and draw them to the screen, they are all identical. I ran the debugger and saw that during the constructor random values ARE assigned, but by the time update and draw are called, all the values that are RANDOMLY assigned during the NON static constructor in a NON static class are all the same.
public class MovingSquare
private Vector2 position;
private Vector2 direction;
private float velocity;
private Texture2D texture;
private float rotation; //not static
private float rotationVelocity; //not static
private Rectangle source;
private Vector2 center;
private Color randColor; //not static
private Random rand = new Random(); //not static
public const int SCREEN_WIDTH = 800;
public const int SCREEN_HEIGHT = 600;
public MovingSquare(Texture2D texture, Vector2 position, Vector2 direction)
this.texture = texture;
this.position = position;
this.direction = direction;
center = position + new Vector2(source.Width / 2, source.Height / 2);
source = new Rectangle(0, 0, 16, 16);
velocity = 1.5f;
randColor = new Color(rand.Next(0, 256), rand.Next(0, 256), rand.Next(0, 256));
rotation = (MathHelper.ToRadians((float)rand.Next(0, 360))) % MathHelper.TwoPi;
rotationVelocity = (float)(rand.Next(1, 20) * .01);
//all instance variables that are assigned in the constructor are considered "static" here
public void Update(GameTime gameTime)
float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
rotation = rotation + rotationVelocity;
this.position = new Vector2(position.X + (direction.X * velocity), position.Y + (direction.Y * velocity));
if (position.X < -1.0f)
position.X = SCREEN_WIDTH;
else if (position.X > SCREEN_WIDTH + 1)
position.X = 0.0f;
if (position.Y < -1.0f)
position.Y = SCREEN_HEIGHT;
else if (position.Y > SCREEN_HEIGHT + 1)
position.Y = 0.0f;
public void Draw(SpriteBatch spriteBatch)
spriteBatch.Draw(texture, position, source, randColor, rotation, new Vector2(source.Width / 2, source.Height / 2), 1.0f, SpriteEffects.None, 0.0f);
in Game1.cs, I construct the objects individually:
square1 = new MovingSquare(texture, startingPosition, randomDirection);
square2 = new MovingSquare(texture, startingPosition, randomDirection);
you would think the instance variables have random values here but they have the same "random" values that the first square have.
then in Update() method
square2.Update(gameTime); //square2's instance variables are now identical to square1's instance variables that were randomly generated in the constructor.
My first solution to this problem was to create properties for each one and then assign them when constructing the individual squares. Any values assigned to the objects outside the class (in Game1.cs) are not treated as static variables. I decided that this was an insane hack that shouldnt be necessary and would like a solution to this problem. Thanks for reading my post!
June 27th, 2011, 02:54 PM
Re: Magically static members
The documentation is your friend and should be your first resource:
If you want to create new random objects quickly then you should provide your own seed value as your code is likely running under the resolution of the system timer.
The random number generation starts from a seed value. If the same seed is used repeatedly, the same series of numbers is generated.
One way to produce different sequences is to make the seed value time-dependent, thereby producing a different series with each new instance of Random. By default, the parameterless constructor of the Random class uses the system clock to generate its seed value, while its parameterized constructor can take an Int32 value based on the number of ticks in the current time. However, because the clock has finite resolution, using the parameterless constructor to create different Random objects in close succession creates random number generators that produce identical sequences of random numbers.
June 27th, 2011, 06:38 PM
Re: Magically static members
By using the system timer as a seed you will get random numbers, I've been using this method in VB for years without issue. Failure to provide the parameter defaults to the clock and will often result in the same sequence of numbers as pointed out in the document above. Likewise if you provide a static number as a seed then your random sequence will repeat every time an instance is created.
Always use [code][/code] tags when posting code.
Tags for this Thread
Click Here to Expand Forum to Full Width
This is a CodeGuru survey question.