2012-04-20 14 views
6

Wenn ich XNA Framework (für Windows Phone) verwenden, funktioniert mein Spiel perfekt, aber wenn ich auf Silverlight/XNA Framework migrieren, bekam ich ein Problem mit Animation Verzögerung. Das Problem ist das folgende: Wenn ich einen festen Zeitschritt zu GameTimer (timer.UpdateInterval = TimeSpan.FromTicks (333333)) festlegte, wird der REAL-Zeitschritt nicht FIXED und Timer-Ereignisse (OnUpdate, OnDraw) mit verschiedenen Intervallen ausgelöst. Dieser Code zeigt mein Problem deutlicher:Silverlight/XNA Animation verzögert

Silverlight/XNA Framework: (Animation nacheilenden):

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: (Alle funktioniert gut):

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

Antwort

3

Basierend auf vielen Jahren in (und aus) der Videospiele-Branche: sollten Sie nicht gegen eine feste Bildrate in Silverlight/XNA/Mobile animieren.

Wenn möglich, ändern Sie Ihre App, um nur die Spielzeit zu laufen, sondern die gegen eine angenommene feste Bildrate (die Sie nie auf einem mobilen Gerät - zumindest bis sie viel mächtiger sind)).

Der Grund, XNA Spielmethoden nehmen eine GameTime ist, weil Sie nicht auf die Bildrate verlassen können ... überhaupt.

Kämpfen Sie nicht Rathaus ... gehen Sie mit den Standards. Machen Sie Ihre App so schnell wie möglich (z. B. wenn Ihre Animationen in einem Frame zu weit springen) oder verlangsamen Sie Ihre Animationsrate, um sie an die Plattform anzupassen (z. B. verlangsamen Sie Ihr Spiel/Ihre App).

Hinweis: Der Grund, warum Silverlight-Animation normalerweise glatter als Flash-Animation aussieht, liegt darin, dass alles zeitbasiert und interpoliert ist, nicht fester Rahmen.

+1

Thx für die Antwort. Ich dachte, mein Fehler: Ich verwendete Animation basierend auf festen Bildrate und berechnen Animation in Update-Methode für Frame-Index. Jetzt werde ich die Animation nach der tatsächlich verstrichenen Zeit in Draw-Methode berechnen. Thx viel. – Ivan

4

Wechsel zu

TimeSpan.Zero; 

Ja, ich weiß, das fühlt sich merkwürdig an und es ist sehr viel. Hab es von einem offiziellen Spielführer bekommen. Wenn ich das nicht benutze, bleibt mein Spiel wie verrückt.

+0

Thx. Die TargetElapsedTime wird in XNA Framework verwendet, wo das Spiel perfekt funktioniert. Mein Problem in Silverlight/XNA Framework (timer.UpdateInterval = TimeSpan.FromTicks (333333)). Wenn ich timer.UpdateInterval auf TimeSpan.Zero setze, wird die OnUpdate-Methode zu einem variablen Zeitschritt aufgerufen, aber ich brauche einen REAL-Zeitschritt. – Ivan

Verwandte Themen