2012-04-20 65 views
6

當我使用XNA Framework(對於Windows Phone)時,我的遊戲完美運行,但是當我在Silverlight/XNA Framework上遷移時,我遇到了動畫滯後問題。 問題如下: 當我將固定時間步長設置爲GameTimer(timer.UpdateInterval = TimeSpan.FromTicks(333333))時,REAL時間步不會以固定時間步長(OnUpdate,OnDraw)以不同的時間間隔觸發。 這個代碼顯示了我的問題更清楚:Silverlight/XNA動畫滯後

的Silverlight/XNA框架:(動畫滯後):

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框架:(所有工作正常):

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

回答

3

根據視頻遊戲行業內外許多年的發展(),您不應該在Silverlight/XNA/Mobile的固定幀速率下製作動畫。

如果可能的話,改變你的應用完全關閉遊戲時間運行,而在對一個假定固定幀速率運行(你永遠不會在移動設備上獲得 - 至少要等到他們有很多更強大 )。

XNA遊戲方法採取GameTime的原因是因爲你不能依賴幀速率...永遠。

不要打市政廳...去與標準。儘可能快地製作您的應用(例如,如果您的動畫在一幀中跳過太多),或者放慢動畫速度以適應平臺(即減慢您的遊戲/應用)。

注意:Silverlight動畫通常比Flash動畫看起來更流暢的原因是因爲所有內容都基於時間和內插,而不是固定幀。

+1

Thx回覆。 我想我的錯誤:我使用基於固定幀速率的動畫並通過幀索引在Update方法中計算動畫。 現在我將在Draw方法中以實際經過的時間計算動畫。 Thx很多。 – Ivan 2012-04-20 09:56:05

4

更改爲

TimeSpan.Zero; 

是的我知道這感覺很奇怪,它非常。從一些官方遊戲指南得到它。除非我使用這個,否則我的遊戲會很瘋狂。

+0

Thx。 TargetElapsedTime在XNA Framework中的使用非常完美。我在Silverlight/XNA框架中的問題(timer.UpdateInterval = TimeSpan.FromTicks(333333))。如果我將timer.UpdateInterval設置爲TimeSpan.Zero,則會在可變時間步驟調用OnUpdate方法,但我需要REAL固定的時間步長。 – Ivan 2012-04-20 07:55:14