Tips/Tricks: Short Sounds, Fireworks and BitmapCache Speed

Jan 4, 2010

This blog post is a follow-up of the previous one dedicated to the Shock improvements.

I'll just list all tips or other interesting findings/updates in no particular order:

Playing Short Sounds in Silverlight (Improved)

You probably know by now that Silverlight (2,3) has an annoying issue with short sounds - sometimes the sound is not played correctly. The simple workaround is here

If you happen to play too many sounds/sec, the above workaround can cause your memory usage to grow more than you want to for short time. The easiest way to avoid the surge in mem usage is to cache the streams that contain the .mp3 sounds, like this:

private static Dictionary<string, Stream> _streams = new Dictionary<string, Stream>();

public static void PlayShortSound(string embeddedSoundName, double volume)
    Stream stream;
    if (!_streams.TryGetValue(embeddedSoundName, out stream))
        stream = Application.GetResourceStream(new Uri(String.Format("/Shock;component/Sounds/{0}", embeddedSoundName), UriKind.Relative)).Stream;
        _streams[embeddedSoundName] = stream;
    MediaElement media = new MediaElement();
    media.MediaFailed += media_MediaFailed;
    media.MediaEnded += media_MediaEnded;
    media.Volume = volume;
    media.AutoPlay = true;
    media.Position = TimeSpan.FromMilliseconds(0);

Then, just call the function like this example: PlayShortSound("explosion.mp3"). You can use this trick, because multiple sounds using the same stream don't cause issues with each other, which is nice.

"Shatter" Effect

In my previous blog post I mentioned the "shatter" brick effect, which is based on this one:

I changed the effect and made it self-recycling: removes itself from the parent after a given time period. It will also display "fireworks" in an area, not  a dot. All of these are really small modifications, but help make the effect "run and forget", and easy to use for "shattering" stuff like bricks.

Here's an usage sample:

public static TimeSpan ShatterEffectTimeSpan = TimeSpan.FromSeconds(0.3);              

Fireworks fireworks = new Fireworks(TimeSpan.FromSeconds(0.3), (int)width, (int)height, brickAppearance == BrickAppearance.Ice);
Canvas.SetLeft(fireworks, centerX);
Canvas.SetTop(fireworks, centerY);

And here's the source code. Note: get the complete sample from the link above and then change the 2 files below. The code won't compile, but you just have to call your own Random() function, and maybe fix few other basic things.

Fireworks.xaml.cs (4.98 kb)  MagicDot.cs (2.89 kb)

I want to call out something very interesting in the above effect (not made by me originally) - each MagicDot is created within its own container. I believe it will cause less layout work than putting all dots within the same container (this is a gut-feeling unverified speculation)

If you want to see the shatter effect in action, break the ice bricks on level 2 of Shock:

When (Not) To Use BitmapCache, Even For Images That Don't Move

I found out that if I use CacheMode="BitmapCache" for each brick (100+ per level), the performance suffers. This is very interesting, and is something to keep in mind when using bitmap cache.

Seems like the larger the image, the better.

More On Speed

Some blogs (don't remember where) mention that images with Opacity=0 still render and take valuable CPU/GPU time - I tested it and it seems that in Silverlight 4 Beta this is not the case.

I observed no noticeable speed change when a UserControl (the highscore) had Opacity=0 vs Visibility=Invisible. Note, however that Opacity=0 means you get hit testing, so there is some speed difference - don't just blindly overuse Opacity=0 instead of Visibility=Invisible.


blog comments powered by Disqus | Terms | Log in


About the author

Happy & enjoying life. Software enthusiast.
The opinions I express here and on are mine and not my employeer's (Microsoft).
This is the official blog of You can find Silverlight samples, coding stuff, and hopefully other interesting things here.