Trying to draw objects randomly on screen 5 times, but it keeps drawing forever

So, my idea was to make generate a random number to draw objects in random locations on screen everytime i run the game. I’m trying to test it generating it randomly on positions Y between 500 and 1500 5 times. The thing is, it keeps drawing it one single time but forever. Each second it is drawn in a random position between 500 and 1500, and not drawing five times in different positions between 500 and 1500. Anyone got any idea what would be the best way to solve that? I know the problem is:

the Draw method runs every second, and that way, everysecond it keeps getting different positions for the objects. I know this because if i draw like this in my draw function:

        protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.CornflowerBlue);
        
        _spriteBatch.Begin(this.camera);
        mapa.draw(_spriteBatch, backGroundFloor);

        mapa.drawObjs(_spriteBatch, treesRocks1, 500);
        mapa.drawObjs(_spriteBatch, treesRocks1, 800);
        mapa.drawObjs(_spriteBatch, treesRocks1, 1500);

        player.anim.Draw(_spriteBatch);
        _spriteBatch.End();

        base.Draw(gameTime);
    }

It works fine. But with this, it occurs the error i just mentioned:

my drawObjs functions in my Mapa file:

public void drawObjs(SpriteBatch spriteBatch, Texture2D texture, float y)
    {
        for (int i = 0; i < 5; i++)
            {
                spriteBatch.Draw(texture, new Vector2(0, y), Color.White);
            }
        
    }

My Draw method:

        protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.CornflowerBlue);
        
        _spriteBatch.Begin(this.camera);
        mapa.draw(_spriteBatch, backGroundFloor);


            mapa.drawObjs(_spriteBatch, treesRocks1, rand.Next(500,1500));

        player.anim.Draw(_spriteBatch);
        _spriteBatch.End();

        base.Draw(gameTime);
    }

Well, the draw method is actually called once every frame, not once every second. By default, with fixed time step on, it draws 60 times a second.

Anyway, you’re only picking out a random number once and passing that to the drawObjs method. The for loop within then uses that random number to draw the texture in the same place five times. You would need to have a reference to a Random instance within the drawObjs method and call random.Next once per for loop iteration to get a different location for each iteration.

I see what you mean, what i did was change the code to this:

 public void drawObjs(SpriteBatch spriteBatch, Texture2D texture)
    {
        for (int i = 0; i < 5; i++)
        {
            float y = rand.Next(500, 1500);
            spriteBatch.Draw(texture, new Vector2(0, y), Color.White);
        }
    }

And my drawn method like this:

        protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.CornflowerBlue);
        
        _spriteBatch.Begin(this.camera);
        mapa.draw(_spriteBatch, backGroundFloor);


        mapa.drawObjs(_spriteBatch, treesRocks1);

        player.anim.Draw(_spriteBatch);
        _spriteBatch.End();

        base.Draw(gameTime);

but i still have the problem where everything is being drawn everytime, like this:

Are you trying to randomly determine the position of the trees only once, and then have them stay there? If so, you’ll need to get the random values once and then store them in a field in the map class. Although it might be better to actually have them as their own Scenery objects…

In the map class, create an array that will store the Y values of the trees. You could also instantiate an integer to keep track of how many tree objects you want to draw.

class Mapa
{
    int treeCount = 5;
    float[] treeLocations = new float[treeCount];
    // the rest of the class
}

Then, in the constructor, fill the array with random values:

public Mapa() // This would also have whatever parameters are being passed to the constructor, if any
{
    Random random = new Random();
    for (int i = 0; i < treeLocations.Length; i++)
        treeLocations[i] = random.Next(500, 1500);
}

Then, in your draw method, you would use the locations array when drawing instead of generating new random values each frame:

public void drawObjs(SpriteBatch spriteBatch, Texture2D texture)
{
    for (int i = 0; i < treeLocations.Length; i++)
        spriteBatch.Draw(texture, new Vector2(0, treeLocations[i]), Color.White);
}

Like I said, it would be better to encapsulate this behavior in its own class.

2 Likes

You really helped me understand and gave me a very clear answer. Thank you very much!

1 Like