2009-06-30 3 views
6

Quando si tenta di animare oggetti time/frame basati su Silverlight (al contrario di utilizzare qualcosa come DoubleAnimation o Storyboard, che non è adatto ad esempio per giochi a ritmo veloce), ad esempio spostando una navicella spaziale in una direzione particolare ogni telaio, il movimento è nervoso e non proprio liscio. Lo schermo sembra addirittura strappare.Animazione Silverlight non liscia

Non sembra esserci differenza tra CompositionTarget e DistpatcherTimer. Io uso il metodo seguente (in pseudocodice):

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 

Ciò dovrebbe tradursi in un movimento fluido, giusto? Ma non è così. Ecco un esempio (Controlli: WASD e Mouse): Silverlight Game. Sebbene l'effetto che ho descritto non sia troppo diffuso in questo esempio, posso assicurarvi che anche lo spostamento di un singolo rettangolo su una tela produce un'animazione vivace.

Qualcuno ha un'idea di come minimizzare questo. Esistono altri approcci all'animazione basata su fotogrammi, con l'utilizzo di Storyboard/DoubleAnimations che potrebbero risolvere questo problema?

Edit: Ecco un approccio rapido e sporco, l'animazione di un rettangolo con codice minimo (Comandi: A e 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; 
    } 

Grazie ! Andrej

+1

+1 Ho interrotto qualsiasi tentativo di creare giochi in Silverlight 3 a causa della balbuzie, della rottura e dello sfarfallio ... chiedo se hanno risolto questo in 4 o se è ancora inutile come Powerpoint per un'animazione fluida? Il mio Amiga di oltre 20 anni con AMOS è una piattaforma di sviluppo migliore e più facile in questo reparto;) –

+0

Ho fatto una domanda simile recentemente. Pensavo che avesse qualcosa a che fare con il mio hardware: MacBook Dual-Boot (Boot Camp), anche se avevo lo stesso problema su tutti gli altri PC Windows che ho. Si noti che la risposta che ho contrassegnato a destra non ha realmente risolto il problema ... Ho osservato il problema anche per uno storyboard che spostava un semplice rettangolo. Spero che questo sia risolto presto. http://stackoverflow.com/questions/5319562/silverlight-fast-moving-bitmap-does-not-update-smoothly –

risposta

3

Aggiornamento della posizione ogni 1 millisecondo è eccessivo, perché Silverlight semplicemente non aggiornerà lo schermo così velocemente. Quando modifichi la posizione di un oggetto come questo (o qualsiasi altro aggiornamento ui) Silverlight contrassegna il framebuffer come sporco e quindi alla fine ridisegna lo schermo, ma non lo ridisegna più spesso dello MaxFrameRate.

Per impostare il MaxFrameRate solo:

Application.Current.Host.Settings.MaxFrameRate = 60; 

questo limiterà l'applicazione per 60 fotogrammi al secondo, che dovrebbe essere più che sufficiente.