2009-06-30 9 views
6

Al intentar animar objetos basados ​​en Silverlight (a diferencia de utilizar algo como DoubleAnimation o Storyboard, que no es adecuado, por ejemplo, para juegos de ritmo rápido), por ejemplo mover una nave espacial en una dirección particular cada marco, el movimiento es nervioso y no muy suave. La pantalla incluso parece rasgarse.Animación Silverlight no lisa

Parece que no hay diferencia entre CompositionTarget y DistpatcherTimer. uso el método siguiente (en pseudocódigo):

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 

Esto debería resultar en un movimiento suave, ¿verdad? Pero no es así Aquí hay un ejemplo (Controles: WASD y Mouse): Silverlight Game. Aunque el efecto que describí no es muy frecuente en esta muestra, puedo asegurarle que incluso moviendo un solo rectángulo sobre un lienzo produce una animación nerviosa.

¿Alguien tiene una idea de cómo minimizar esto? ¿Hay otros enfoques para exponer la animación basada en cuadros usando Storyboards/DoubleAnimations que podría resolver esto?

Editar: Aquí un enfoque rápido y sucio, que anima un rectángulo con código mínimo (Controles: A y 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; 
    } 

Gracias ! Andrej

+1

+1 Intenté crear juegos en Silverlight 3 para descansar debido al tartamudeo, el desgarro y el parpadeo ... ¿Me pregunto si resolvieron esto en 4 o si sigue siendo tan inútil como Powerpoint para una animación fluida? Mi Amiga de más de 20 años con AMOS es una plataforma de desarrollo mejor y más fácil en este departamento;) –

+0

Hice una pregunta similar recientemente. Pensé que tenía algo que ver con mi hardware: MacBook Dual-Boot (Boot Camp), aunque tuve el mismo problema en todas las demás PC con Windows que tengo. Tenga en cuenta que la respuesta que marqué a la derecha no resolvió realmente el problema ... Observé el problema incluso para un guión gráfico moviendo un rectángulo simple. Espero que esto se resuelva pronto. http://stackoverflow.com/questions/5319562/silverlight-fast-moving-bitmap-does-not-update-smoothly –

Respuesta

3

Actualizar la posición cada 1 milisegundo es exagerado porque Silverlight simplemente no actualizará la pantalla tan rápido. Cuando modifica la posición de un objeto como ese (o cualquier otra actualización de ui), Silverlight marca el framebuffer como sucio y luego redibujará la pantalla, sin embargo, no redibujará la pantalla con más frecuencia que el MaxFrameRate.

Para establecer el MaxFrameRate simplemente:

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

Esto limita su aplicación a 60 cuadros por segundo que debería ser más que suficiente.

Cuestiones relacionadas