基於時間的動作
時間單位:ms
速度慢的電腦可以通過丟幀來保證動畫的速度
在Windows中讀取時間
用timeGetTime()函數,詳見MSDN
可以在函數的開頭用靜態變數來儲存時間:
void FrameUpdate() { static DWORD LastTime = timeGetTime(); |
時間相關的動畫
記錄動畫的開始時間,然後儲存每一幀相對開始時間的位移量
主要畫面格的格式,包括時間和變換矩陣:
typedef struct sKeyframe { DWORD Time; D3DMATRIX matTransformation; } sKeyframe; |
通過ElapsedTime來決定使用哪一幀
計算出值在0~1之間的一個標量值來確定目前時間相對於前後兩個主要畫面格的位置
float Scalar = (Time - Keyframes[Keyframe].Time)/TimeDiff;
由這個標量值可以插值出當前的變換矩陣:
// Calculate the difference in transformations D3DXMATRIX matInt = D3DXMATRIX(Keyframes[Keyframe2].matTransformation) - D3DXMATRIX(Keyframes[Keyframe].matTransformation); matInt *= Scalar; // Scale the difference |
這樣動畫就可以平滑地“播放”了
時間相關的運動
通常運動是相對於位移的,因此要計算它:
float CalcMovement(DWORD ElapsedTime, float PixelsPerSec) { return (PixelsPerSec / 1000.0f * (float)ElapsedTime); } |
沿軌道的運動
即不受使用者控制沿預定軌道的運動
直線軌道
這個簡單,知道起點、終點和當前的標量值就可求出:
| D3DXVECTOR3 vecPos = (vecEnd - vecStart) * Scalar + vecStart; |
曲線軌道
曲線不只是圓弧,這裡我們採用更為廣泛的曲線:Bezier曲線
我們需要4個點來確定曲線的方向和彎曲程度
那麼它是怎麼畫出來的呢?看下面的圖:
對每條線段進行均分,分得越多,曲線越光滑。然後把分割點像這樣串連起來:
Beaier曲線就這樣畫出來了,HOHO~
計算位置有個公式,怎麼推導這裡就不介紹了,可以查閱相關資料:
P0~P3是那4個控制點,s是scalar值
定義路徑
複雜路徑是一系列的軌道的組合,不僅是直線或曲線的問題,有時候是兩者的結合
可以把它定義成類似於鏈表的形式:
enum { PATH_STRAIGHT = 0, PATH_CURVED }; typedef struct { DWORD Type; //直線還是曲線 D3DXVECTOR3 vecStart, vecEnd; //直點和終點 D3DXVECTOR3 vecPoint1, vecPoint2; //如果是曲線,這就是中間那兩個控制點 } sPath; |
路徑用來移動遊戲中的角色和其它相關物體是很酷的,比如你的襪子隨風飄下
其中一個重要的應用就是用來控制攝像機實現電影中的各種鏡頭效果
例子, NND,編譯不了!不說了
Reference:
《Advanced Animation With DirectX》