سؤال

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?

هل كانت مفيدة؟

المحلول

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.

نصائح أخرى

The architecture of an XNA game (or any other game engine/framework) is a little more complicated than a simple class architecture. Each method has it's own responsibility, and each one is being called on entirely different stages of the game.

First off, the constructor is being class by initializing a new instance of the game, just like any other class, inside the constructor the game host, platform and component managers are being initialized. After the constructor had finished no method is being called, (neither Initialize as you might expect).

Then to start the Game Loop you call the Run method, this method sets up the GraphicsDevice, GameTime and the Game Loop mechanisms. only then the Initialize method is being called. a few steps before the game starts running. Then BeginRun is being called, the first Update is firing and only then the game is 'officially' running.

Now the part that is missing is the LoadContent. LoadContent is the most "unforgiving" of the three - while you may use Initialize instead of the Constructor freely and the other way around, you may not use the Constructor nor Initialize instead of LoadContent, the reason is that LoadContent is being called by an Event which is firing by the GraphicsDevice, only when the GraphicsDevice is ready for use you can start loading content, the reason is that many Resources(Content) are being stored inside the Graphics Processing Unit (GPU) memory (Textures, Shaders, etc.) so you cannot load that kind of content until you have access the GPU memory via the GraphicsDevice.

To wrap things up:

  • The constructor is being used to initialize everything that needs to be ready before the game starts running, (Services, Content Managers, etc.).
  • The Initialize method is being used to initialize everything that is being used only when the game is running (Game Components for example).
  • The LoadContent is being used to load any kind of content (usually via the ContentManager).
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top