7
\$\begingroup\$

In the past I have used Content.Load<type>("filename"); all over the place. This quickly becomes a nightmare to manage and worse you start having multiple copies of the same asset loaded in several different places.

Then I moved on to using a Resources class which basically looked like the following:

public class Resources
{
    public static Texture2D particle01;
    ...
    public static Texture2D particle93;

    public static Effect shader01;
    ...
    public static Effect shader32;

    public static Load(ContentManager content, GraphicsDevice device)
    { //load all the resources }

    public static Unload()
    { //unload all the resources }
}

Then I could simply use Resources.particle01 to get a reference to the resource from anywhere within the same namespace.

This was a nice approach because it eliminated the duplicates that I had in the past. Also all loading was done in a single class, so it was easy to keep track of the resources. And finally, I could simply right click, for example, particle93 and click find all references to find all the places that used that texture.

However, there are issues with this approach and I would like to know if there is a better solution out there.

\$\endgroup\$

4 Answers 4

8
\$\begingroup\$

Well for starters XNA's content manager doesn't load the same asset twice, it will just return a reference if something was already loaded.

As for your resource approach, I don't know if it's really the way to go since you basically hard code your content assets into your game.

A possible solution to your problem would be the factory pattern. Say you would like to load a level, stored as XML. You load the XML file and load the level by doing LevelFactory.Construct(xml); This factory inspects the XML file and loads all the assets associated with that level and puts them into the world. Sub-parts of the world like NPCs could be constructed by the level factory by calling the NPC factory and passing part of the XML file so that the NPC factory knows to load what textures and models.

Using this approach you get a 'cascading series' of factories that are all data driven so you can have a clear separation between content (the XML file and the files referenced by the XML file) and code (the factories). While still keeping the content loading code away from the other code. You now don't have todo Player = new Player(textureA, textureB, textureC); anymore, you can just ask the factory for a new player and it will figure out the rest.

Tip: you can always have a few methods for default objects or have a fallback when nothing is specified in the XML.

Hope this helps!

\$\endgroup\$
3
\$\begingroup\$

I used FlatRedBall, which has an amazing concept of Screens. Instead of worrying about loading/unloading textures, you instead write code like:

Sprite s = this.addSprite("spaceship");

And it will handle the content life-cycle for you. I also use this approach in my own framework, Radiant Wrench. I find that it keeps management to a minimal and just gets out of your way.

The code for managing sprites is not that trivial (you need a sprite class and screen class, for starters), so I would suggest give FRB or RW a try. You will always benefit from learning new ways to do things (sometimes better ways).

\$\endgroup\$
2
\$\begingroup\$

This might seem unfavorable to some but I tend to keep my resources local to the GameState that needs them, and each GameState has a ResourcePool of sorts. This is a nice way to keep level assets separate since I don't really need menu backgrounds Your Resources class would be better served as a structure, and the GameState will be responsible for Load and Unload.

Some of resource management in XNA is partly determined by how you import your content in the first place. Many people bind textures and effects to their models in the content processing phase of the build- leaving them to only manage meshes and the rest is already referenced within.

You seem to take the more classic "mix and combine" approach for more flexibility, so you need an approach that black-boxes the underlying work and cut the code you have to write in the long run. I haven't used FlatRedBall, but from what I can tell from the short description written here, it sounds like the Lazy Loading pattern. This is a concept worth looking into if you want to make your life easier with managing many resources.

\$\endgroup\$
1
  • \$\begingroup\$ Small comment, a struct that has references to non value-types has not much use. \$\endgroup\$
    – Roy T.
    Oct 4, 2011 at 6:29
1
\$\begingroup\$

I use a public static class called Assets. It contains dictionaries of each kind of asset, model, effect, spritefonts,etc, it has a load function where it looks in the content folder for folders such as "Textures", "Models", etc, and loads all the assets. Then when I want to call an Asset I just use something like Assets.Textures["SpriteSheetX"];

I don't know if this is bad practice but it's very easy. I mostly just pass around strings of the file name and deep down in the core it will load the asset from Assets.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .