Search code examples
c#xnamonogameopentk

Why use separate load methods instead of the constructor?


OpenTK has a separate Load() method it calls when the game has to load. XNA and MonoGame take it another step further and have the constructor, Initialize and LoadContent. All this seems to do for me as the programmer using the framework is be confused when I'm supposed to load something in and that I can't be 100% sure that a class is initialized when it's constructed. For what reason is this done?


Solution

  • There is a reason that XNA has the constructor, Initialize, and LoadContent(). When you create a new game, such as in

    static class Program
        {
            static void Main()
            {
                using (Game1 game = new Game1())
                {
                    game.Run();
                }
            }
        }
    

    Game1's constructor is called and takes care of pre-initialize tasks, such as

    graphics = new GraphicsDeviceManager(this);
    Content.RootDirectory = "Content";
    Components.Add(new gamecomponent());
    

    and setting up the class's properties. You can use the constructor like to normally would. After the constructor is called, the Game.Run() method is called. This will start the game and call the initialize method. So in the above Program, once game.Run() is called, several things happen. First, Game1's Initialize method is called. This method usually looks something like:

    protected override void Initialize()
        {
            // now that the GraphicsDevice has been created, we can create the projection matrix.
            projectionMatrix = Matrix.CreatePerspectiveFieldOfView(
                MathHelper.ToRadians(45.0f), GraphicsDevice.Viewport.AspectRatio, 1f, 10000);
    
            base.Initialize();
        }
    

    As you may notice, the projectionMatrix for this game is created in this method (not the constructor) because the graphicsDevice has been initialized once Game.Run() is called. After the Initialize method completes pre-game tasks Base.Initialize() is called, which does two things. First, any GameComponents you have added to the game are enumerated through and initialized. Second, LoadContent() is called once everything is initialized, both in the game and the gamecomponents, and the graphicsdevice is ready.

    Now, you might wonder why LoadContent() isn't part of the initialize method. Well, I believe the main reason for this is so that you can reload the content if needed, "such as when the DeviceReset event occurs", or if you need to reset things like model mesh bones.

    So in summary, the constructor creates the class and its properties like it normally would, then once the Initialize method it called, the game starts running after all the GameComponents have been initialized and the Content is loaded.