OpenTK有一个单独的Load()方法,它在游戏必须加载时调用。 XNA和MonoGame更进一步,并使用构造函数Initialize和LoadContent。所有这些对我来说似乎都有用,因为当我应该加载某些内容时,使用该框架的程序员会感到困惑,并且我无法100%确定类在构造时是否已初始化。这是为什么这样做的?
答案 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
方法,此方法会设置GraphicsDevice
,GameTime
和Game Loop
机制。只有这样才能调用Initialize
方法。比赛开始前几步。然后调用BeginRun
,第一个Update
被解雇,然后游戏才“正式”运行。
现在缺少的部分是LoadContent
。 LoadContent
是三者中最“无情”的 - 虽然您可以自由地使用Initialize
而不是Constructor
,反之亦然,您可能不会使用Constructor
也不会Initialize
代替LoadContent
,原因是LoadContent
正在Event
调用GraphicsDevice
,只有在GraphicsDevice
时才会Content
准备使用你可以开始加载内容,原因是很多资源(GraphicsDevice
)被存储在图形处理单元(GPU)内存(纹理,着色器等)中,所以你无法加载那种直到您通过Initialize
访问GPU内存之前的内容。
总结:
LoadContent
方法用于初始化仅在游戏运行时使用的所有内容(例如游戏组件)。ContentManager
用于加载任何类型的内容(通常通过{{1}})。