2012-04-20 14 views
6

Cuando uso XNA Framework (para Windows Phone) mi juego funciona perfectamente, pero cuando migro en Silverlight/XNA Framework tuve un problema con el retraso de la animación. El problema es el siguiente: Cuando configuro el paso de tiempo fijo para GameTimer (timer.UpdateInterval = TimeSpan.FromTicks (333333)), el paso de tiempo REAL no se FIJA y los eventos de temporizador (OnUpdate, OnDraw) se activan con intervalos diferentes. Este código muestra mi problema con mayor claridad:Retraso de animación Silverlight/XNA

Silverlight/XNA Framework: (retraso de Animación):

TimeSpan curNow; 
TimeSpan lastUpdate; 
TimeSpan lastDraw; 

public GamePage() 
{ 
    timer = new GameTimer(); 
    timer.UpdateInterval = TimeSpan.FromTicks(333333); 
    timer.Update += OnUpdate; 
    timer.Draw += OnDraw; 
} 

private void OnUpdate(object sender, GameTimerEventArgs e) 
{  
    curNow = new TimeSpan(DateTime.Now.Ticks); 
    TimeSpan elapsed=e.ElapsedTime;//Always constant and has value: 33ms 
    TimeSpan realElapsed = curNow - lastUpdate;//Real elapsed time always changing and has a value between: 17-39ms (sometimes more then 39ms) 
    lastUpdate = curNow; 
} 

private void OnDraw(object sender, GameTimerEventArgs e) 
{ 
    curNow = new TimeSpan(DateTime.Now.Ticks); 
    TimeSpan elapsed=e.ElapsedTime;//Always changing and has a value between: 17-39ms (sometimes more then 39ms) 
    TimeSpan realElapsed = curNow -lastDraw;//Always changing and has a value between: 17-39ms (sometimes more then 39ms) 
    lastDraw= curNow; 
} 

XNA Framework: (Todo funciona bien):

TimeSpan curNow; 
TimeSpan lastUpdate; 
TimeSpan lastDraw; 

public Game() 
{ 
    // Frame rate is 30 fps by default for Windows Phone. 
    TargetElapsedTime = TimeSpan.FromTicks(333333); 
} 

protected override void Update(GameTime gameTime) 
{  
    curNow = new TimeSpan(DateTime.Now.Ticks); 
    TimeSpan elapsed=gameTime.ElapsedGameTime;//Always constant and has value: 33ms 
    TimeSpan realElapsed = curNow - lastUpdate;//Real elapsed time has a value between: 34-35ms (sometimes more then 35ms) 
    lastUpdate = curNow; 
} 

protected override void Draw(GameTime gameTime) 
{  
    curNow = new TimeSpan(DateTime.Now.Ticks); 
    TimeSpan elapsed=gameTime.ElapsedGameTime ;//Value between: 33-34ms (sometimes more then 34ms) 
    TimeSpan realElapsed = curNow - lastDraw;//Value between: 34-35ms (sometimes more then 35ms) 
    lastDraw = curNow; 
} 

Respuesta

3

Basado en muchos años dentro (y fuera) de la industria de los videojuegos: no debe animar a una velocidad de cuadro fija en Silverlight/XNA/Mobile.

Si es posible, cambie su aplicación para ejecutarla únicamente fuera del tiempo de juego, en lugar de operar contra una velocidad de fotogramas fija asumida (que nunca obtendrá en un dispositivo móvil - al menos hasta que sean mucho más poderosas)

La razón por la cual los métodos de juegos de XNA toman GameTime es porque no puede confiar en la velocidad de cuadros ... nunca.

No pelee el ayuntamiento ... vaya con los estándares. Haga su aplicación lo más rápido posible (por ejemplo, si sus animaciones saltan demasiado lejos en un marco), o reduzca la velocidad de su animación para adaptarse a la plataforma (es decir, reduzca la velocidad de su juego/aplicación).

Nota: El motivo por el cual la animación de Silverlight generalmente se ve más suave que la animación de Flash es porque todo está basado en el tiempo e interpolado, no en un marco fijo.

+1

Thx para la respuesta. Me di cuenta de mi error: utilicé la animación basada en la velocidad de fotogramas fija y calculé la animación en Actualizar método por índice de fotogramas. Ahora voy a calcular la animación por tiempo real transcurrido en el método Dibujar. mucho. – Ivan

4

Cambiar para

TimeSpan.Zero; 

Sí, sé que esto se siente raro y lo es mucho. Lo tengo de alguna guía oficial del juego. A menos que use esto, mi juego queda rezagado.

+0

Thx. El uso de TargetElapsedTime en XNA Framework donde el juego funciona perfectamente. Mi problema en Silverlight/XNA Framework (timer.UpdateInterval = TimeSpan.FromTicks (333333)). Si configuro timer.UpdateInterval en TimeSpan.Zero, el método OnUpdate se invoca en un paso de tiempo variable, pero necesito el paso de tiempo fijo REAL. – Ivan