Silverlight animation not smooth

Posted by Andrej on Stack Overflow See other posts from Stack Overflow or by Andrej
Published on 2009-06-30T15:43:16Z Indexed on 2010/05/13 16:44 UTC
Read the original article Hit count: 1147

Filed under:
|

Hi,

When trying to animate objects time/frame based in Silverlight (in contrast to using something like DoubleAnimation or Storyboard, which is not suitable e.g. for fast paced games), for example moving a spaceship in a particular direction every frame, the movement is jumpy and not really smooth. The screen even seems to tear.

There seems to be no difference between CompositionTarget and DistpatcherTimer. I use the following approach (in pseudocode):

Register Handler to Tick-Event of a DispatcherTimer
In each Tick:
Compute the elapsed time from the last frame in milliseconds
Object.X += movementSpeed * ellapsedMilliseconds

This should result in a smooth movement, right? But it doesn't. Here is an example (Controls: WASD and Mouse): Silverlight Game. Although the effect I described is not too prevalent in this sample, I can assure you that even moving a single rectangle over a canvas produces a jumpy animation.

Does someone have an idea how to minimize this. Are there other approaches to to frame based animation exept using Storyboards/DoubleAnimations which could solve this?

Edit: Here a quick and dirty approach, animating a rectangle with minimum code (Controls: A and D) Animation Sample

Xaml:

 <Grid x:Name="LayoutRoot" Background="Black">
    <Canvas Width="1000" Height="400" Background="Blue">
        <Rectangle x:Name="rect" Width="48" Height="48"
                   Fill="White"
                   Canvas.Top="200"
                   Canvas.Left="0"/>
    </Canvas>
</Grid>

C#:

private bool isLeft = false;
    private bool isRight = false;
    private DispatcherTimer timer = new DispatcherTimer();
    private double lastUpdate;

    public Page()
    {
        InitializeComponent();

        timer.Interval = TimeSpan.FromMilliseconds(1);
        timer.Tick += OnTick;

        lastUpdate = Environment.TickCount;
        timer.Start();
    }

    private void OnTick(object sender, EventArgs e)
    {
        double diff = Environment.TickCount - lastUpdate;

        double x = Canvas.GetLeft(rect);

        if (isRight)
            x += 1 * diff;
        else if (isLeft)
            x -= 1 * diff;

        Canvas.SetLeft(rect, x);

        lastUpdate = Environment.TickCount;
    }

    private void UserControl_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.D)
            isRight = true;

        if (e.Key == Key.A)
            isLeft = true;
    }

    private void UserControl_KeyUp(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.D)
            isRight = false;

        if (e.Key == Key.A)
            isLeft = false;
    }

Thanks! Andrej

© Stack Overflow or respective owner

Related posts about Silverlight

Related posts about animation