Friday 18 May 2012

Level Manager revisited–residual objects from deleted levels

 

In a previous post I went through a level manager. This post picks up were that one left off.

If you create objects in the sub class levels, then when you set the level to null, thus not activating it next time around the Array. Then the objects contained within the Level 1 for example will still exist. For this reason we could implement Idisposable and a destructor to cleanup after the Level 1 object is deleted (see here) but that is beyond the scope of what we know here. I will cover this technique at a later date. Another more simple is reported here.

say we play Sounds and a backing track within a level Level 1. Thus in the constructor assuming the appropriate Sound and Song variables are declared

sound = g.Content.Load<SoundEffect>("Tank-Moving");
backtrack = g.Content.Load<Song>("Sleep Away");
soundInst = sound.CreateInstance();
soundInst.IsLooped = true;
soundInst.Play();
MediaPlayer.IsRepeating = true;
MediaPlayer.Play(backtrack);




we must cleanup after ourselves before the level is set to null. Otherwise the objects using the external resources (media player) may not be disposed of as they are still active.



public void cleanup()
{
soundInst.Stop();
if (MediaPlayer.State == MediaState.Playing)
MediaPlayer.Stop();
player = null;

}


It would be better put the cleanup routine in the Level class along with all the possible content objects and actually the player object should be there also. But as some objects are declared in the subclass the level manager must call the cleanup method of each Sub Class Level as when you delete a sub level the objects may not be decommissioned by the .NET garbage collector until they are no longer needed. The media player will continue to play as it is repeating and will definitely not be released.



The Level manager must be able to distinguish the type of the Level to call methods appropriate to that Level. So when we are iterating through the Level objects we check what type the level object is and call it’s appropriate clean up method. This method can be used to specialize actions (method calls) for levels also. So in the update for the level manager (look for the if (l.LevelState == LEVELSTATE.FINISHED)) statement when we are checking to see if the Level is finished we call the cleanup method thus



// if the current level has finished
if (l.LevelState == LEVELSTATE.FINISHED)
{ // Get rid of the level
if (l.GetType() == typeof(Level1))
{
Level1 current = (Level1)l;
current.cleanup();
}

Levels[CurrentLevel] = null;
etc..


What we do here is we check to see what type of level object we are dealing with. You can do this with any object using the GetType() function to return the Object type (you cannot use a switch statement with though). Then we cast the Level object as a Level1 object so we can call the cleanup routine for the appropriate level. You would need an if block for every level object that requires cleaning up.

No comments:

Post a Comment