Through a simple ResourceManager management of XNA resources, WPXNA (two)

Recommended for you: Get network issues from WhatsUp Gold. Not end users.

Square has developed some Windows Phone some of the game, not what technology. Share your experiences here, only in order to exchange experiences and friends. Square will gradually will write the class uploaded to the hosting project, no good name, called WPXNA, finally, please master detour, so as not to waste time. (in order to focus and reduce space, some sample code may not strict enough. )

Resource type

In some simple 2D game design, we usually use the resources are some fonts, images and sounds. So here is not to model the video and content, to make a video and 3D models often need to spend a lot of time.

Here, square by enumeration type ResourceType to distinguish different resources:

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

In the above code, Image image resources, says Font font resource. Sound and Music have said sound resources, unlike the Music through the MediaPlayer class to play (generally MP3 file), while Sound generally refers to some small wav file.

Identification of resources

Square created a Resource structure to identify a resource, he has three open field, Name is the name of the resource, the name can not be repeated and other resources. Type is the resource type, also mentioned above is the ResourceType. Path is the access path resources, is the resource files in the project location, as shown below:

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;
    }

}

Because, only the correct loading resources, the game can run normally, so in the constructor of the Resource class, square made some checks on the parameters.

Management of resources

Then, we can manage resources by ResourceManager.

In the constructor, we accept a Resource array of structures, they also need to manage the resources.

internal readonly IList<Resource> Resources;

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

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

private ContentManager contentManager;
internal World World;

private readonly Dictionary<string, Texture2D> textures = new Dictionary<string, 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 { }

}

LoadContent calls the ResourceManager method to load resources, in the LoadContent method, we will create a new ContentManager object, and through his method of Load in our prior acceptance of resources.

To create the ContentManager, we also need to set the World field ResourceManager (you can also modify the attribute for him). So, before calling LoadContent, you need to make sure that the World field is not empty.

When you feel these resources has been of no use, call the UnloadContent method to release resources:

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 code above, we first of all the resources of a call to the Dispose method, and then call the Unload method of the ContentManager.

Use of resources

Finally, we in the World class specific use about ResourceManager.

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 created a ResourceManager, and pointed to a picture and a wave file we need.

protected override void OnNavigatedTo ( NavigationEventArgs e )
{
    // ...
    
    this.resourceManager.LoadContent ( );

    base.OnNavigatedTo ( e );
}

When the page loads, we call the LoadContent method to load the picture and sound. After that, we use them in the OnUpdate and OnDraw methods.

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 ( );
}

Through the GetTexture and GetSound methods of ResourceManager can get the picture and sound, only need to pass the name of the resource.

Finally, you need to UnloadContent in a place called ResourceManager.

This video
Project address

More about WPXNA
Square the development of the game
QQ group 213685539

The same article welcome square released in other locations

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download

Posted by Rick at November 21, 2013 - 10:05 AM