Procedural Animation in Silverlight 2

After some research, I'm recommending the use of Empty Storyboards for procedural animations.

What is an "Empty Storyboard"?  It is a Storyboard with no animations or specific target that simulates a game loop or per frame callback by having a short duration and once its Completed it Begins itself again.

A simple example looks like this in C#:

Storyboard timer = new Storyboard();
timer.Duration = TimeSpan.FromMilliseconds(500);
timer.Completed += new EventHandler(timer_Completed);
timer.Begin();

void timer_Completed(object sender, EventArgs e){
    if (conditionToKeepGoing)
        timer.Begin();
}

The other two options include the DispatcherTimer, which is not suitable for this type of quick ticking, and Storyboards with defined Targets and Animations.

Modifying Animation values at run-time does work smoothly and as expected.  But you are limiting your flexibility by tying every Target property that's animated to a matching Animation instance.  With an Empty Storyboard you are free to modify any property based on your calculations.

A combination of the two Storyboard method will most likely end up becoming the most powerful pattern.  During the game loop, within the empty Storyboard you can calculate your scene and when a different state is desired, you can call into an object's prepared routines or Storyboards with linked Animations.

I've modified the original HelloBeta2 to use an Empty Storyboard and there is commented out code which adds a Storyboard to each Line as its drawn that moves its second point after initial placement.  This simulates the "known routine" idea, and I could easily update the new location for the second point at run-time.

I've also added a StrokeWidth loop and DashArray, but that was just for my own entertainment.

posted on Jun 18th, 2008 | Permalink | Comments (7)

7 Comments »

  1. Hi Adam,

    Could you expand a bit on why a DispatcherTimer "is not suitable for this type of quick ticking" - I have been using empty Storyboards for gameloops in SL1 but thought that DispatherTimer was a nicer way to go for SL2.

    Cheers

    Ian

    Comment by Ian Blackburn - June 18, 2008 @ 3:51 AM
  2. Adam

    Is there a way to create a storyboard in xaml and change the value in one of the animations at runtime. Basically creating a dynamically moving animation? Or would it always have to be done through a "empty storyboard" method?

    Comment by Corey - June 18, 2008 @ 7:06 AM
  3. Adam,

    Nice article, but like Ian, I am interested in why you think DispatchTimer is less suitable than an Empty Storyboard for UI updates. Do you have any performance testing results?

    Thanks

    Koen

    Comment by Koen - June 18, 2008 @ 10:56 AM
  4. The DispatcherTimer is a lower resolution timer than the timer behind the Storyboard class, which causes loss in fidelity. Additionally, the Storyboard execution is more stable across the different supported OSs and Browsers. I'll put together a sample to show the comparision.

    @Corey - If you declare a Storyboard in XAML and give it an x:Name, then you can update the values of the Animation by referencing the Storyboards children. There is Silverlight 2 Beta 1 Animation lab from MIX that shows how to do this. The code is still same.

    Comment by Adam Kinney - June 18, 2008 @ 12:26 PM
  5. I think the problem with DispatcherTimer has more to do with threading than anything else. The StoryBoard is probably handled on another thread that is not affected by the UI thread.

    I've noticed in Beta 2, a distinct performance drop in DispatcherTimer, and it is terrible when other UI elements are doing things.

    In all, I think the UI thread is not very good if performance is your goal, it's better to use the StoryBoard.

    Comment by Sam - June 18, 2008 @ 7:14 PM
  6. Wow! I used the DispatcherTimer for my game loop. I assumed that it was the right way to go. It seems so much cleaner than using a XAML control. In my limited tests with Beta 1, I didn't see much of a difference between the techniques. However, I was wondering about the perf. Thanks for testing it and sharing your results. Next time I work on my game, I'll remember that and change the game loop to using an empty Animation.

    Comment by snyhol - June 18, 2008 @ 11:16 PM
  7. Awesome!

    As far as I know, the final version of Silverlight will support the CompositionTarget.Rendering event, which should make this somewhat easier.

    Comment by Ruurd Boeke - June 19, 2008 @ 10:39 AM

Leave a comment