2011-09-15 63 views
3

所以我正在做一個遊戲,在線教程。目前,我有一些FPS內置到系統中,和一個簡單的動畫,它使用像這樣的精靈件:C++/SDL動畫速度

if(frameCount > 12) 
     frameCount = 0; 

    //hero frames 
    SDL_Rect clip[ 13 ]; 

    clip[ 0 ].x = 0; 
    clip[ 0 ].y = 0; 
    clip[ 0 ].w = 44; 
    clip[ 0 ].h = 39; 

    clip[ 1 ].x = 51; 
    clip[ 1 ].y = 0; 
    clip[ 1 ].w = 44; 
    clip[ 1 ].h = 39; 

    clip[ 2 ].x = 102; 
    clip[ 2 ].y = 0; 
    clip[ 2 ].w = 44; 
    clip[ 2 ].h = 39; 
    ... 
    ... 
    SDL_BlitSurface(hero, &clip[ frameCount ], destination, &offset); 
    frameCount++; 

現在,這工作得很好,和while循環的每次迭代將導致它玩了下動畫中的框架(此動畫順便說一句,是角色類的一部分)。

我面臨的問題是動畫的速度。它發生在當前60的遊戲FPS上,我希望能夠單獨控制玩家動畫的速度,這樣我就可以把它放慢到合理的速度。

有沒有人有任何建議,我該怎麼做呢?

注:共有13幀。

回答

6

您的刷新率(60 fps)與動畫率分開。在我看來,最好的解決方案是將動畫速率與實時時鐘綁定。在SDL中,您可以使用SDL_Ticks()函數執行此操作,您可以使用該函數以毫秒分辨率來測量時間。

作爲一個例子,考慮本實施例中(不工作的代碼,只是一個草圖):

void init() { 
    animationRate = 12; 
    animationLength = 13; 
    startTime = SDL_Ticks(); 
} 

void drawSprite() { 
    int frameToDraw = ((SDL_Ticks() - startTime) * animationRate/1000) % animationLength; 
    SDL_BlitSurface(hero, &clip[ frameToDraw ], destination, &offset); 
} 

在情況下,它不明確,frameToDraw變量是通過計算自動畫過了多少時間來計算開始玩。您將其乘以動畫速率,並獲得動畫速率已經過去的絕對幀數。然後應用模運算符將此數減少到動畫長度的範圍,併爲您提供當時需要繪製的幀。

如果刷新率低於動畫速率,則精靈會跳過幀以跟上請求的動畫速率。如果刷新速度更快,則會重複繪製同一幀,直到顯示下一幀的時間到來。

我希望這會有所幫助。

2

Miguel寫的很棒。你可以使用的另一種方法是,使用計時器,將其設置爲以特定頻率觸發,並在該頻率下增加精靈索引。

請注意,您應該總是使您的渲染和邏輯分開。

+0

我同意,這個解決方案也可以,但是如果你的顯示速度低於動畫速率,它會使用更多的CPU,因爲你仍然會全速更新你的動畫狀態。 – Miguel

+0

我同意你的方法更快。然而這種方法更通用一些。例如,如果您想要在一段時間內跳過精靈更改或執行其他操作,則公式會變得複雜。 – Shahbaz

+0

我在解決方案中處理精靈更改的方式是讓每個角色跟蹤其狀態。遊戲邏輯觸發狀態改變,狀態改變意味着動畫可以停止,或改變爲一組不同的幀,等等。每個精靈都知道它的可能狀態是什麼。實際上,這很容易。 – Miguel