为什么使用单独的加载方法而不是构造函数?

时间:2014-01-31 19:39:48

标签: c# xna monogame opentk

OpenTK有一个单独的Load()方法,它在游戏必须加载时调用。 XNA和MonoGame更进一步,并使用构造函数Initialize和LoadContent。所有这些对我来说似乎都有用,因为当我应该加载某些内容时,使用该框架的程序员会感到困惑,并且我无法100%确定类在构造时是否已初始化。这是为什么这样做的?

2 个答案:

答案 0 :(得分:2)

XNA有一个原因是构造函数Initialize和LoadContent()。当您创建新游戏时,例如

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

调用Game1的构造函数并负责预初始化任务,例如

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

并设置类的属性。您可以像通常那样使用构造函数。调用构造函数后,将调用Game.Run()方法。这将启动游戏并调用initialize方法。因此,在上面的Program中,一旦game.Run()被调用,就会发生一些事情。首先,调用Game1的Initialize方法。这种方法通常类似于:

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();
    }

您可能会注意到,此游戏的projectionMatrix是在此方法中创建的(而不是构造函数),因为在调用Game.Run()后,graphicsDevice已初始化。在Initialize方法完成之后,调用游戏前任务Base.Initialize(),这会做两件事。首先,您添加到游戏中的任何GameComponents都会被枚举并初始化。其次,在游戏和游戏组件中初始化所有内容后调用LoadContent(),并且图形设备已准备就绪。

现在,您可能想知道为什么LoadContent()不是initialize方法的一部分。好吧,我认为这样做的主要原因是你可以根据需要重新加载内容,“例如当发生DeviceReset事件时”,或者你需要重置模型网格骨骼等内容。

总而言之,构造函数像通常那样创建类及其属性,然后一旦调用Initialize方法,游戏就会在所有GameComponents初始化后开始运行装了。

答案 1 :(得分:1)

XNA游戏(或任何其他游戏引擎/框架)的架构比简单的类架构稍微复杂一些。每种方法都有自己的责任,每个方法都在游戏的不同阶段进行调用。

首先,构造函数是初始化游戏的新实例,就像任何其他类一样,在构造函数中初始化游戏主机,平台和组件管理器。构造函数完成后没有调用任何方法,(你可能没有Initialize)。

然后,要启动Game Loop调用Run方法,此方法会设置GraphicsDeviceGameTimeGame Loop机制。只有这样才能调用Initialize方法。比赛开始前几步。然后调用BeginRun,第一个Update被解雇,然后游戏才“正式”运行。

现在缺少的部分是LoadContentLoadContent是三者中最“无情”的 - 虽然您可以自由地使用Initialize而不是Constructor,反之亦然,您可能不会使用Constructor也不会Initialize代替LoadContent,原因是LoadContent正在Event调用GraphicsDevice,只有在GraphicsDevice时才会Content准备使用你可以开始加载内容,原因是很多资源(GraphicsDevice)被存储在图形处理单元(GPU)内存(纹理,着色器等)中,所以你无法加载那种直到您通过Initialize访问GPU内存之前的内容。

总结:

  • 构造函数用于初始化游戏开始运行之前需要准备的所有内容(服务,内容管理器等)。
  • LoadContent方法用于初始化仅在游戏运行时使用的所有内容(例如游戏组件)。
  • ContentManager用于加载任何类型的内容(通常通过{{1}})。