2012-04-20 14 views
6

Quando uso XNA Framework (per Windows Phone) il mio gioco funziona perfettamente, ma quando eseguo la migrazione su Silverlight/XNA Framework ho riscontrato un problema con il ritardo delle animazioni. Il problema è il seguente: Quando imposto il passaggio temporale fisso a GameTimer (timer.UpdateInterval = TimeSpan.FromTicks (333333)), il passo REAL time non è FISSO e gli eventi timer (OnUpdate, OnDraw) si attivano con intervalli diversi. Questo codice mostra il mio problema in modo più chiaro:Silverlight/XNA animation lagging

Silverlight/XNA Framework: (animazione in ritardo di sviluppo):

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: (tutto funziona benissimo):

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; 
} 

risposta

3

Basato su molti anni in (e fuori) dell'industria dei videogiochi: non si dovrebbe animare contro una frequenza fotogrammi fissa in Silverlight/XNA/Mobile.

Se possibile, cambiare la vostra applicazione per eseguire esclusivamente fuori il tempo di gioco, piuttosto l'operare nei confronti di un frame-rate fisso ipotizzate (che non troverete mai su un dispositivo mobile - , almeno fino a quando sono molto più potente).

Il motivo per cui i metodi di gioco XNA prendono uno GameTime è perché non si può fare affidamento sul frame rate ... ever.

Non combattere il municipio ... vai con gli standard. Crea la tua app il più velocemente possibile (ad es. Se le tue animazioni salteranno troppo in una cornice), o rallenti la tua velocità di animazione per adattarla alla piattaforma (ad esempio, rallenta il gioco/app).

Nota: il motivo per cui l'animazione di Silverlight di solito risulta più scorrevole dell'animazione Flash è perché tutto è basato sul tempo e interpolato, non su una cornice fissa.

+1

Thx per la risposta. Ho immaginato il mio errore: ho usato l'animazione basata sulla frequenza di fotogrammi fissa e calcolare l'animazione nel metodo di aggiornamento per indice di fotogrammi. Ora calcolerò l'animazione per il tempo reale trascorso nel metodo Draw. Thx molto. – Ivan

4

Cambia per

TimeSpan.Zero; 

Sì, lo so che questo sembra strano e lo è davvero. Ottenuto da una guida di gioco ufficiale. A meno che non lo usi, il mio gioco è pazzesco.

+0

Thx. L'utilizzo di TargetElapsedTime in XNA Framework, dove il gioco funziona perfettamente. Il mio problema in Silverlight/XNA Framework (timer.UpdateInterval = TimeSpan.FromTicks (333333)). Se imposto timer.UpdateInterval su TimeSpan.Zero, il metodo OnUpdate viene richiamato a un passo temporale variabile, ma ho bisogno di un passo temporale REAL fisso. – Ivan