0

I'm using GameStateManagement and I'm having an issue with memory in my game. I have each segment of the game as a different screen. I have a screen for the logo, a screen for the main title, and so on. I think I've been managing the screens wrong but I've been having trouble finding information to my problem.

When this logo screen moves on to the title menu screen it doesn't seem to free up the memory resources of this logo screen and I seem to be having that issue with all of my screens and the memory starts stacking up quite a bit. Am I doing the UnloadContent right? Am I needing to call Dispose() on my textures and such under UnloadContent? Am I removing the screen correctly? Any thoughts on what I'm not doing right?

Here is my logo screen:

namespace Tower_Defense
{
    class Logo : GameScreen
    {
        Tower_Defense curGame;
        GraphicsDeviceManager graphics;
        AudioManager audioManager;
        Texture2D logoTexture;
        int gamecycles;

        public Logo(Tower_Defense game, GraphicsDeviceManager g, AudioManager am)
        {
            curGame = game;
            audioManager = am;
            graphics = g;
            EnabledGestures = GestureType.Tap;
        }

        public override void LoadContent()
        {
            base.LoadContent();

            logoTexture = Load<Texture2D>("Textures/Backgrounds/logo");

            gamecycles = 0;
        }

        public override void UnloadContent()
        {
            base.UnloadContent();
        }

        public override void Draw(GameTime gameTime)
        {
            ScreenManager.SpriteBatch.Begin();

            ScreenManager.SpriteBatch.Draw(logoTexture, Vector2.Zero, Color.White);

            ScreenManager.SpriteBatch.End();
        }

        public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
        {
            gamecycles++;

            if (gamecycles >= 60)
            {
                ScreenManager.AddScreen(new TitleScreen(curGame, graphics, audioManager, false), null);
                this.UnloadContent();
                ScreenManager.RemoveScreen(this);
            }

            base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);
        }
    }
}
Ted
  • 277
  • 1
  • 3
  • 14

1 Answers1

0

ContentManager "owns" all of the resources that it loads. You cannot unload them yourself. You can only unload them with ContentManager.Unload - which unloads everything that that particular manager had loaded. (More details.)

Therefore, if you want to load and unload resources on a per-screen basis, you have to create an instance of ContentManager for each screen.

Community
  • 1
  • 1
Andrew Russell
  • 26,924
  • 7
  • 58
  • 104
  • That makes sense, but I'm having some problems. Creating a new ContentManager seems to require a IServiceProvider constructor so I was thinking maybe I could just pass the the same ContentManager around to each new screen and then just keep clearing it before entering each new screen. The base.UnloadContent() sort of confuses me. I tried just doing that thinking I'd be using the same content manager but it gave me a null texture when loading the next screen. This ContentManager stuff confuses me. – Ted Oct 25 '12 at 09:46
  • @Ted: You can get an `IServiceProvider` from `Game.Services` (this is the same service provider that `Game.Content`). `base` just refers to `GameScreen` ("call this method on my parent class"). You should be able to right-click it and press "Go To Definition" to see what it does (if you have the source for `GameScreen`). – Andrew Russell Oct 25 '12 at 09:51
  • Thanks for all your help, I'll grab that from Game.Services and try what you said again tomorrow, it's getting early. – Ted Oct 25 '12 at 10:15
  • Decided I didn't want to wait to try and seems I've gotten your suggestion of each screen having its own content manager to work. That has reduced my memory usage by a decent amount. – Ted Oct 25 '12 at 10:35