游戏开始后将内容加载到游戏中?

时间:2017-10-14 06:40:22

标签: c# monogame

我希望在创建新对象后游戏开始后将内容加载到我的游戏中。

基本上,我有这段代码。

public class RenderObject
{
    public Texture2D image;
    public string graphic;
    public float angle;
    public Vector2 location;
    public float alpha = 1.0f;

    public static List<RenderObject> renderObjects = new List<RenderObject>();
    int _x;
    int _y;

    public RenderObject(int _x, int _y,string _graphic)
    {
        location = new Vector2(_x, _y);
        graphic = _graphic;
        renderObjects.Add(this);
    }

    public RenderObject(int _x, int _y)
    {
        this._x = _x;
        this._y = _y;
    }

    public void LoadContent(ContentManager content)
    {
        image = content.Load<Texture2D>(graphic);
    }

我有一个LoadContent函数,当它在常规LoadContent中使用时,它可以完美地运行..

protected override void LoadContent()
    {
        // Create a new SpriteBatch, which can be used to draw textures.
        spriteBatch = new SpriteBatch(GraphicsDevice);

        for (int i = 0; i < RenderObject.renderObjects.Count; i++)
        {
            RenderObject.renderObjects[i].LoadContent(this.Content);
        }





        //TODO: use this.Content to load your game content here 
    }

除了显然在创建新对象时不会调用它。每当创建一个新对象时,它都会崩溃,因为它本身的纹理会返回null,因为它没有被加载。我的解决方案是创建一个在LoadContent期间加载的静态Texture2D,但是拥有一个巨大的LoadContent加载游戏中的每一个资产似乎都是非常不直观的,所有这些都是手动编码的。

1 个答案:

答案 0 :(得分:0)

  

除了显然在创建新对象时不会调用

在创建对象本身后,是否有任何特定原因无法调用LoadContent?

我认为你有几个选择:

  • 如前所述,您可以在游戏循环的初始LoadContent方法中加载游戏所需的所有资源,或者如果您有加载级别/世界的话,可以加载。
  • 通过在相关对象上调用LoadContent()或者打破模式并将ContentManager传递给构造函数,为每个对象加载所需的内容。
  • 如果您想手动控制加载/卸载,可以通过继承类本身来创建自己的ContentManager实现,例如:

    public class MyContentManager : ContentManager
    {
        public MyContentManager(IServiceProvider serviceProvider):base(serviceProvider)
        {
        }
    
        public MyContentManager(IServiceProvider serviceProvider, string rootDirectory) : base(serviceProvider, rootDirectory)
        {
    
        }
    
        public void Unload(string name)
        {
            // unload specific resource
            LoadedAssets.Remove(name);
        }
    
        public Texture2D Load(string name)
        {
            return Load<Texture2D>(name);
        }       
    }
    

    如果您要调用contentManager.Unload(),它将卸载所有内容,但在上面的代码示例中,您可以控制特定资源。

拥有多个内容管理器并不罕见,例如,您可以拥有一个被认为是“常见”的内容管理器,它可以加载游戏所需的所有内容而不管级别,而另一个内容管理器将单独负责加载任何级别的特定资源并且当级别改变时也卸载它们。

在“AssetManager”之后说明我的意思:

public static class AssetManager
{
    private static ContentManager _common;

    public static MyContentManager Level { get; private set; }

    public static void Initialize(IServiceProvider serviceProvider)
    {
        _common = new ContentManager(serviceProvider, "commoncontentdirectory");
        Level = new MyContentManager(serviceProvider, "levelcontentdirectory");
    }

    // A shorthand for loading an asset through the common content manager.
    public static T Load<T>(string asset)
    {
        return _common.Load<T>(asset);
    }

    // A shorthand for unloading the entire content manager for current instance.
    public static void Unload()
    {
        _common.Unload();
    }
}

可以在Microsoft.Xna.Framework.Game

中初始化AssetManager
    protected override void Initialize()
    {
        AssetManager.Initialize(Content.ServiceProvider);

        base.Initialize();
    }

并在需要时使用“AssetManager”上的简写方法或通过Level属性使用级别内容管理器的实例来调用。