Search code examples
c#monogame

Monogame children update method lag


So I'm pretty new to computer programming, but I know the basics of C#.

I'm working on a Monogame project and was making an update method for my sprites. Since my sprites are terraria based (I mean that every sprite is a different bodypart) I made a children list. In that list I put all the body sprites and I attach the list to a parent (center sprite of the player).

This is my basic sprite update method: (not only for player)

public virtual void Update(GameTime gameTime, Rectangle clientBounds)
{
    timeSinceLastFrame += gameTime.ElapsedGameTime.Milliseconds;

    if (timeSinceLastFrame > millisecondsPerFrame)
    {
        timeSinceLastFrame = 0;
        ++currentFrame.X;

        if (currentFrame.X >= sheetSize.X)
        {
            currentFrame.X = 0;
            ++currentFrame.Y;

            if (currentFrame.Y >= sheetSize.Y)
            {
                currentFrame.Y = 0;
            }
        }
    }
}

This is my player sprite update method in another class:

public override void Update(GameTime gameTime, Rectangle clientBounds)
{
    position += direction;

    // If sprite moves off screen
    if (position.X < 0)
    {
        position.X = 0;
    }

    if (position.Y < 0)
    {
        position.Y = 0;
    }

    if (position.X > clientBounds.Width - frameSize.X)
    {
        position.X = clientBounds.Width - frameSize.X;
    }

    if (position.Y > clientBounds.Height - frameSize.Y)
    {
        position.Y = clientBounds.Height - frameSize.Y;
    } 

    // Continue base update method 
    base.Update(gameTime, clientBounds);
}

And this is the draw method, wich works just fine:

public override void Draw(GameTime gameTime)
{
    spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.PointClamp, DepthStencilState.Default, RasterizerState.CullCounterClockwise);
    player.Draw(gameTime, spriteBatch);
    player.children.ForEach(c => c.Draw(gameTime, spriteBatch));
    spriteBatch.End();

    base.Draw(gameTime);
}

But the update method is lagging:

public override void Update(GameTime gameTime)
{
    player.children.Add(playerDeux);
    float millisecondsRunning = 30;
    float millisecondsWalking = millisecondsRunning  * 2f;

    if (player.running == true)
    {
        player.millisecondsPerFrame = millisecondsRunning;
    }

    else if (player.running == false)
    {
        player.millisecondsPerFrame = 65;
        playerDeux.millisecondsPerFrame = 30;
    }

    if (player.walking == false)
    {
        player.textureImage = Game.Content.Load<Texture2D>(@"Images/" + s1[1]);
    }

    player.Update(gameTime, Game.Window.ClientBounds);
    player.children.ForEach(c => c.Update(gameTime, Game.Window.ClientBounds));
    base.Update(gameTime);
}

So when I call the draw method on all the children it works just fine, but when I call the Update method on the children it lags very much and the program even stops working.

Is there a better way to do this?

EDIT: also note that this class is not done yet, it's just a test where I draw 2 sprites and update (animation plays) them. + The s1[1] in player.textureImage = Game.Content.Load(@"Images/" + s1[1]); is just a string name in an array.


Solution

  • There are some oddities with your code, but I think the main culprit is the player.children.Add(playerDeux). The way it is right now, you're adding playerDeux to the children list every single update, and then updating playerDeux once for every time Update has already run. It looks like you want to move this line of code to your Initialize or LoadContent methods.

    Also, you should probably load the texture only once in the LoadContent method and only reference the in-memory texture in the Update method. This isn't the main reason the game is this much laggy, but it is an unnecessary overhead.