为什么我必须在Game1类(XNA)中声明GraphicsDeviceManager?

时间:2013-11-01 21:57:36

标签: c# xna

首先,我是C#和XNA(在C ++之前)的新手

我搜索过网络的一半,我相信,整个stackoverflow,但我找不到答案。 在我的项目中,我想创建一个GraphicsManager:它的工作是为开放世界游戏加载/卸载资源,提供更抽象的渲染工具(加载tileset,从tileset中选择tile等)等。

这就是为什么将所有与图形相关的对象放在GraphicsManager中感觉很自然。

class GraphicsManager : Manager
{
    // provided by XNA project
    GraphicsDeviceManager graphics;
    SpriteBatch spriteBatch;

    public override void Initialize(Game caller)
    {
        mainObj = caller;
        graphics = new GraphicsDeviceManager(mainObj);
    }
}

// constructor of the Game class
public Game()
{     
    Graphics.GraphicsManager.Instance.Initialize(this);
    Content.RootDirectory = "Content";
}

经过一段时间后,我发现我需要在Initialize()之前创建GraphicsDeviceManager,因为它会强制它调用LoadContent() - 我可以理解:GraphicsDeviceManager的构造函数对提供的Game对象执行一些操作来改变它Initialize()方法(或类似的东西)。

这就是为什么我改变了我的代码,所以它在Game的构造函数中运行了GraphicManager的Initialize()。不幸的是,这种方式不会调用LoadContent()。为什么呢?

PS。仅仅在类中声明任何GraphicsDeviceManager对象就足够了,不需要实例化 - 然后它就可以工作了。这对我没有意义:/

@Scott W 我删除了Game构造函数,重命名了类(到Game1)并创建了这个方法:

protected override void Initialize()
    {
        // TODO: Add your initialization logic here
        Graphics.GraphicsManager.Instance.Initialize(this);

        Content.RootDirectory = "Content";

        base.Initialize();
    }

但现在它不会调用LoadContent。有什么想法吗?

1 个答案:

答案 0 :(得分:3)

严格地说,您不需要 GraphicsDeviceManager子类中创建Game对象。但是,在创建时,它通常需要Game实例(或子类实例,例如Game1)。

通常,您不希望为Game子类指定构造函数。这可能是导致问题与LoadContent没有被调用等有关的原因.XNA的Game构造函数会执行一些您未在其中复制的内容,也不会调用基本构造函数。我建议您在InitializeLoadContent内完成所有需要的工作,而不是调用基础构造函数;这就是他们的设计目标。

因此请取出Game类的构造函数(我还建议将其称为Game以外的其他内容,因为这也是XNA的类),并将初始化移到Game子类的Initialize

protected override void Initialize()
{
    Graphics.GraphicsManager.Instance.Initialize(this); 
    base.Initialize();
}

这是在GraphicsDeviceManager子类中创建Game个对象的标准方法。在Initialize覆盖中执行,不要创建构造函数。

另外,我建议不要为此创建一个单例,只需在GraphicsManager子类中直接添加Game对象,这是组合的基本用法。