1. 程式人生 > >CocosBuilder 學習筆記(3) AnimationManager 與 ccbi 檔案解析

CocosBuilder 學習筆記(3) AnimationManager 與 ccbi 檔案解析

【CocosBuilder】學習筆記目錄

1. 相關的類

先介紹和AnimationManager相關的幾個類:

CCBSequence

時間線。有成員duration(時間線時間,預設10秒)、name(時間線名)、SequenceId(Id)、ChainedSequenceId(重複執行的時間線Id)、SequenceProperty* mCallbackChannel(關鍵幀執行回撥)、SequenceProperty* mSoundChannel(關鍵幀執行Sound)。

CCBSequenceProperty

儲存keyframe的容器。

有成員name、int type、Vector keyframes(儲存關鍵幀keyframe)。

對於動畫而言,Property的name是動畫改變的屬性的名字,例如position、rotation等。

CCBKeyframe

關鍵幀。CCB的動畫是以關鍵幀為基礎的,我們可以在時間線上設定關鍵幀,併為關鍵幀設定屬性,CCB能夠實現在關鍵幀之間實現動畫。關鍵幀不僅可以用來設定動畫屬性,也能用於觸發回撥、聲音。

有相關成員value(屬性值)、time(發生的時間)、EasingType easingType(特效型別)、easingOpt(特效的值,部分特效有用)。

一個動畫,需要關鍵幀才能呈現出動畫效果。

2. 部分成員變數

CCBReader有成員animationManager,關聯了一個動畫管理器。還有成員Map<Node*, CCBAnimationManager*> animationManagers,將解析到的node和動畫管理器關聯。

AnimationManager是CCB專案中所有動畫的管理中心。

成員Vector sequences,實際儲存的是動畫的時間線。

成員map<Node*, map<int, Map<string, SequenceProperty*>>> nodeSequences,其結構較複雜,用下圖較為容易理解:

簡而言之:

nodeSequences儲存的是動畫管理器管理的node和node對應的所有Property,Property儲存關鍵幀,同一Property儲存的關鍵幀是在同一變換(動畫的屬性、回撥等)中起作用的。

node對應的Property按照Property所屬的時間線(Sequence)Id進行分類。

3. 解析過程中 AnimationManager 相關操作

解析ccbi檔案之前,設定成員rootContainerSize為螢幕大小,設定成員owner為this(執行CCBReader解析方法的場景或層)。

在解析ccbi檔案時,執行CCBReader的readSequences方法解析時間線設定Sequence成員變數,每個時間線儲存到容器sequences之中,並設定動畫管理器成員autoPlaySequenceId,作為自動執行的時間線Id。

對於每個時間線,還可以設定CallbackChannel和SoundChannel,這兩者都是SequenceProperty型別,在關鍵幀執行回撥或聲音。

接下來執行readNodeGraph方法,設定node相關的動畫內容,並存儲到容器nodeSequences之中。專案的根節點Layer作為成員rootNode。

.ccbi檔案解析完成之後,把根節點Layer和動畫管理器加入CCBReader成員容器animationManagers之中。

之後執行CCBReader關聯的animationManager的runAnimationsForSequenceIdTweenDuration方法,引數:自動執行的時間線Id(解析檔案時獲取並設定的),0。

4. runAnimationsForSequenceIdTweenDuration 方法

就動畫方面,readNodeGraph方法只是將動畫需要的屬性設定到了關鍵幀,並存儲在動畫管理器的容器中。真正將關鍵幀的動畫屬性轉為實際的動畫效果是依賴本方法。

1. 刪除根節點Layer的所有action(removeAllActionsFromTarget)。

2. 遍歷nodeSequences。對node刪除所有action。獲取當前node在當前時間線Id上的所有Property。

3. 遍歷這些Property。對每個Property,先通過第一個關鍵幀設定初始狀態。再設定動作序列。

動作序列設定流程:

1. Property內的關鍵幀數量最少為2。

2. 根據第一個關鍵幀的起始時間,設定延遲動作DelayTime。

3. 建立兩幀之間的動作。兩幀時間差作為動作時間,第二幀的狀態作為動作結束時的狀態。動作特效儲存在第一幀,讀取第一幀中的特效,對動作進行包裝,得到新動作。

4. 還有幀的情況下,進行迴圈,幀下標+1,對此時兩幀執行第三步(建立兩幀的動作)。

5. 所有動作加入動作序列,對當前node執行動作序列(runAction)。

4. 獲取當前時間線時間長度,根節點layer在時間線結束時,執行函式動作呼叫函式AnimationManager::sequenceCompleted。

回撥函式是在時間線結束後,可以通過ChainedSequenceId,設定並執行要重複執行的時間線。

5. 通過CallbackChannel的關鍵幀,生成一個回撥函式動作序列,根節點Layer執行該動作序列(runAction)。

6. 通過SoundChannel的關鍵幀,生成一個聲音動作序列,根節點Layer執行該動作序列(runAction)。

7. 此時的時間線Id作為runningSequence。在時間線執行結束後呼叫的sequenceCompleted方法會獲取該值,用來獲取當前時間線,從而設定下一時間線id並執行下一時間線。

5. 總結

CCB動畫的實質是多個動作的組合。

在解析ccbi檔案NodeGraph後,時間線和動畫相關內容已經全部讀取完成,並存儲到了相應的容器裡。接下來就要根據容器內動畫相關內容,設定動作,並交給對應的node執行動作。

node的動畫資訊(關鍵幀)是由SequenceProperty儲存,通過AnimationManager的容器關聯Node和Property。

node可能在多個時間線有動畫,所以要通過時間線Id給Node的Property進行分類。

Sequence僅作為時間線使用。時間線也有Property,其中的關鍵幀作為觸發回撥函式或聲音使