views:

79

answers:

2

Hello,

I start learning Silverlight and would like to create some simple game. I am using CompositionTarget.Rendering event for my animation

But animation is not smooth, I developed games before and I used double buffer to avoid such problems, but I can't find if it possible with Silverlight.

Does anybody know how to create smooth animation with CompositionTarget.Rendering event.

Thanks, .NET Developer.

A: 

How much processing do you perform in Rendering event? As one option you can render part of your scene into WriteableBitmap and only use rendering event to swap bitmaps.

AlexEzh
I display only one red rectangle on blue background. Can you give a link how to swap bitmaps in Silverlight, or some more info about this trick?
Alexander Shapovalov
A: 

Are you assuming that the Rendering event fires at a constant rate? It's not guaranteed to. On my machine it usually fires 60 times per second, but sometimes it's a bit faster and sometimes noticeably slower. It seems to skip a frame on occasion, which could cause your animation not to be smooth.

However, the event gives you the information to determine exactly how long it's been since the last frame (though you have to know how to get it), and you can code your animation to take this into account. Move farther if it's been a longer amount of time since the last frame, etc.

You need to take the EventArgs that's passed to your event handler, cast it to RenderingEventArgs, and then read its RenderingTime property. Calculate the delta in RenderingTime since your last event; that tells you how long it's been since your last frame was shown, and you can use that to pace your animations.

CompositionTarget.Rendering += CompositionTarget_Rendering;

...

private static TimeSpan? _lastRenderTime;
private void CompositionTarget_Rendering(object sender, EventArgs e) {
    var args = (RenderingEventArgs) e;
    var elapsed = _lastRenderTime.HasValue ?
                      args.RenderingTime - _lastRenderTime.Value :
                      TimeSpan.Empty;
    _lastRenderTime = args.RenderingTime;

    // "elapsed" tells you how long since the last frame.
    // Now you can update your animation accordingly. For example,
    var left = Canvas.GetLeft(_myControl);
    left += elapsed.TotalSeconds * 100;
    Canvas.SetLeft(_myControl, left);
}

I've heard that, at least in WPF, RenderTime doesn't tell you the current time, but rather what time it will be when the frame is shown on the screen. I haven't seen that substantiated from official sources, and even if it's true, I don't know if it's true for Silverlight as well. But whatever the case, it will give you the best possible information for writing your animation.

Joe White