Click here to Skip to main content
15,886,422 members
Articles / Programming Languages / C#

Use ResourceManager to Manage Resources in XNA, WPXNA (2)

Rate me:
Please Sign up or sign in to vote.
5.00/5 (1 vote)
23 May 2013CPOL2 min read 8.6K   3  
Use ResourceManager to manage resources in XNA

Introduction/Catalog

I have developed some games on Windows Phone. Here, I'll share my experiences and gradually upload some classes, no good name, I just call it WPXNA. (Some example code may not be stringent enough.)

  • Resource Type
  • Identify Resources
  • Resources Management
  • Use the Resources

Resource Type

In some simple 2D games, we usually use the resources as font, image and sound. So here is not related to video and model, it will spend a lot of time to make video and 3D models.

Here, I created an enum ResourceType to distinguish different types of resources:

C#
internal enum ResourceType
{
 Image,
 Font,
 Sound,
 Music,
}

In the above code, Image represents an image resource, Font represents the font resource. Sound and Music are sound resources, the Music will play by the MediaPlayer class (usually MP3 files), and Sound generally refers to certain small wav files.

Identify Resources

I created a Resource structure that identifies a resource, it has three internal fields, Name is the name for the resource. Type is the type of the resource, which is the ResourceType mentioned above. Path is the location of resource files in the project, as shown in the following figure:

C#
internal struct Resource
{
 internal readonly string Name;
 internal readonly string Path;
 internal readonly ResourceType Type;

 internal Resource ( string name, ResourceType type, string path )
 {
  if ( string.IsNullOrEmpty ( name ) || string.IsNullOrEmpty ( path ) )
   throw new ArgumentNullException ( "name, path", "name, path can't be null" );

  this.Name = name;
  this.Type = type;
  this.Path = path;
 }
}

Resources Management

Then, we can use the ResourceManager to manage the resources.

In the constructor, we accept an array of Resource structure, that needs to be managed.

C#
internal readonly IList<Resource> Resources;

internal ResourceManager ( IList<Resource> resources )
{ this.Resources = null == resources ? new Resource[] { } : resources; }

Of course, the ResourceManager is not able to load resources, so we need to use the ContentManager class:

C#
private ContentManager contentManager;
internal World World;

private readonly Dictionary<string, Texture2D> textures = new <Dictionarystring, Texture2D> ( );
private readonly Dictionary<string, SpriteFont> fonts = new Dictionary<string, SpriteFont> ( );
private readonly Dictionary<string, SoundEffectInstance> sounds = 
  new Dictionary<string, SoundEffectInstance> ( );
private readonly Dictionary<string, Song> music = new Dictionary<string, Song> ( );

public void LoadContent ( )
{
 if ( null == this.contentManager )
  this.contentManager = new ContentManager ( this.World.Services, contentDirectory );

 try
 {
  foreach ( Resource resource in this.Resources )
   switch ( resource.Type )
   {
    case ResourceType.Image:
     this.textures.Add ( resource.Name, 
       this.contentManager.Load<Texture2D> ( resolution + resource.Path ) );
     break;

    case ResourceType.Font:
     this.fonts.Add ( resource.Name, this.contentManager.Load<SpriteFont> ( resource.Path ) );
     break;

    case ResourceType.Sound:
     this.sounds.Add ( resource.Name, 
       this.contentManager.Load<SoundEffect> ( resource.Path ).CreateInstance ( ) );
     break;

    case ResourceType.Music:
     this.music.Add ( resource.Name, this.contentManager.Load<Song> ( resource.Path ) );
     break;
   }
 }
 catch { }
}

Call the LoadContent method of the ResourceManager to load a resource, in the LoadContent method, we will create a new ContentManager object, and use the Load method to load the resources.

To create a ContentManager object, we also need to set the World field of ResourceManager (you can also modify it to a property). So, before you call the LoadContent, you need to ensure that the World field is not null.

You can also call the UnloadContent method to release resources:

C#
public void UnloadContent ( )
{
 foreach ( Texture2D texture in this.textures.Values )
  texture.Dispose ( );

 foreach ( SoundEffectInstance sound in this.sounds.Values )
  sound.Dispose ( );

 foreach ( Song song in this.music.Values )
  song.Dispose ( );

 this.textures.Clear ( );
 this.fonts.Clear ( );
 this.sounds.Clear ( );
 this.music.Clear ( );

 if ( !this.Resources.IsReadOnly )
  this.Resources.Clear ( );

 if ( null != this.contentManager )
  this.contentManager.Unload ( );
}

In the above code, we call the Dispose method for all resources, and then call the Unload method of the ContentManager.

Use the Resources

Finally, we used the ResourceManager in our World class:

C#
private readonly ResourceManager resourceManager;

public World ( Color backgroundColor )
 : base ( )
{
 // ...

 this.resourceManager = new ResourceManager ( new Resource[] {
  new Resource ( "bird", ResourceType.Image, @"image\bird" ),
  new Resource ( "click", ResourceType.Sound, @"sound\click" )
 } );
 this.resourceManager.World = this;

}

In the constructor of the World, we create a ResourceManager object, and pointed out that we need a picture and a wave file.

C#
private void OnUpdate ( object sender, GameTimerEventArgs e )
{
 this.resourceManager.GetSound ( "click" ).Play ( );
}

private void OnDraw ( object sender, GameTimerEventArgs e )
{
 this.GraphicsDevice.Clear ( this.BackgroundColor );

 this.spiritBatch.Begin ( );
 this.spiritBatch.Draw ( this.resourceManager.GetTexture ( "bird" ), 
                         new Vector2 ( 20, 20 ), Color.White );
 this.spiritBatch.End ( );
}

Use the GetTexture and GetSound method to get a picture and sound, just passing the name of the resource.

Finally, you will also need to call UnloadContent method of the ResourceManager at a suitable position.

Get the code here: http://wp-xna.googlecode.com/, for more contents, please visit WPXNA.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
-- There are no messages in this forum --