Hidden Object: Episode 8 – Loop Game Music with a Behavior

In the last episode of Creating a Hidden Object Game is Silverlight 3 we finished off the magnifier feature. Now it is time to add some background music to the game and have it continually play.

First off, we need to find some appropriate music. I did a search for royalty-free & public domain music and came across a site by Derek R. Audette that contained such music. On the site, I found a piece of music called “Combustible Coffee Pot” written & performed by Derek R. Audette – ©MMV(Socan). Derek’s own description of the music is:

“Out of control drum fills, singing string sections and odd, tense, electronic pads make up this bizarre composition. Created to add a mood of intrigue to an independent film produced in 2005.”

Download the mp3 file and add it to the Audio folder.

In order to use the music in our game, we need to add a MediaElement control to LayoutRoot:

<MediaElement x:Name="musicElement"
    Source="/Audio/Combustible_Coffee_Pot.mp3"
    MediaEnded="musicElement_MediaEnded"/>

To get the continuous loop, we need to handle the MediaEnded event which sets the media position back to 0 and plays it again:

private void musicElement_MediaEnded(object sender, System.Windows.RoutedEventArgs e)
{
    musicElement.Position = new TimeSpan(0);
    musicElement.Play();
}

But as developers, we don’t want to make our designers go into code behind and enter C# code. Since Silverlight doesn’t support continuously lookping media, we are going to package this functionality into a custom behavior.

Create a folder under Interactivity called ContinuousMediaPlayBehavior and create new class based on the Behavior template by the same name. All we are going to do is attach an event handler to the MediaEnded event in the OnAttached method and remove the handler in the OnDetaching method. To get the AssociatedObject property to be strongly typed to a MediaElement and thus allow this behavior to only be attached to the MediaElement type we change the behavior so it is typed to MediaElement. When the MediaEnded event is fired, we set the position of the media back to 0 and replay it:

public class ContinuousPlayMediaBehavior : Behavior<MediaElement>
{
    public ContinuousPlayMediaBehavior() {}

    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.MediaEnded += AssociatedObject_MediaEnded;
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        AssociatedObject.MediaEnded -= AssociatedObject_MediaEnded;
    }

    void  AssociatedObject_MediaEnded(object sender, RoutedEventArgs e)
    {
        AssociatedObject.Position = new TimeSpan(0);
        AssociatedObject.Play();
    }
}

This is what the XAML looks like for this:

<MediaElement x:Name="musicMediaElement" Source="/Audio/Combustible_Coffee_Pot.mp3">
    <i:Interaction.Behaviors>
        <local:ContinuousPlayMediaBehavior/>
    </i:Interaction.Behaviors>
</MediaElement>

In the next episode, we will continue to work on the UI by adding various screens including one to control the volume of the background music we just added.

About the Author