第一部分:CCActionInterval家族(持續動作)
持續動作,顧名思義,就是該動作的執行將持續一段時間。因此持續動作的靜態產生函數,往往附帶一個時間值Duration。例如:
- CCActionInterval *moveByAction=CCMoveBy::actionWithDuration(0.5f,ccp(5,5));
持續動作類名尾碼:一般有兩種尾碼,一種是To,一種是By。To表示最終達到的目標值,By表示增量值。如:
- CCMoveBy::actionWithDuration(0.5f,ccp(5,5));//表示花0.5秒,按向量(5,5)移動一段距離
- CCMoveTo::actionWithDuration(0.5f,ccp(5,5));//表示花0.5秒,移動到座標(5,5)
持續動作比立即動作的數量要多很多,常用的CCActionInterval子類動作有:簡單的:CCMoveTo:移動到、CCMoveBy:按……移動CCJumpTo:跳躍到、CCJumpBy:按……跳躍CCBezierTo:貝茲移動到、CCBezierBy:按……貝茲移動CCRotateTo:旋轉到、CCRotateBy:按……旋轉CCScaleTo:縮放到、CCScaleBy:按……縮放CCSkewTo:切變到、CCSkewBy:按……切變CCTintTo:色彩坡形到、CCTintBy:按……色彩坡形CCFadeIn:從無到有,也叫淡入、CCFadeOut:從有到無,也叫淡出、CCFadeTo:改變不透明度到某個值CCBlink:閃耀CCDelayTime:延時複雜的:CCAnimate:幀動畫,這個我們在第四節講過,關於動畫的問題不是一句兩句就能說完,以後會慢慢展開CCGridAction家族:網格動畫封裝器:CCRepeat:重複執行幾次、CCRepeatForever:永遠執行、CCSequence:按序列執行、CCSpawn:同時執行、CCActionEase家族:補間動畫
第二部分:簡單的持續動作
這些動作都非常簡單,和立即動作的區別只是增加了一個執行時間而已。但還有一些要注意的地方:1.旋轉動作順時針是正方向2.關於貝茲曲線貝茲曲線的描述結構體如下:
- /** @typedef bezier configuration structure
- */
- typedef struct _ccBezierConfig {
- //! end position of the bezier
- CCPoint endPosition;
- //! Bezier control point 1
- CCPoint controlPoint_1;
- //! Bezier control point 2
- CCPoint controlPoint_2;
- } ccBezierConfig;
如果執行節點是this的話,那麼對應個點的位置。注意,當使用CCBezierTo時,ccBezierConfig的點都是絕對座標點。但如果使用CCBezierBy,ccBezierConfig的點都是相對座標點。這點要謹記。
第三部分:一些封裝器
這些動作單獨無法起作用,需要封裝其他動作類才行。他們的作用是對於動作的執行,增加一些變化。非常類似於裝飾者模式。1.CCRepeat:用於重複執行幾次動作,times表示執行次數
- static CCRepeat * CCRepeat::actionWithAction (CCFiniteTimeAction *pAction, unsigned int times)
使用舉例:在我的炸彈人例子中,用到如下寫法,我播放一個炸彈動畫若干次,然後啟動爆炸的相關代碼。
- CCFiniteTimeAction *action=getAnimate();//獲得炸彈播放動畫,自己實現的函數
- CCAction *sequneceAction = CCSequence::actions(
- CCRepeat::actionWithAction(action,5),
- CCCallFunc::actionWithTarget(this, callfunc_selector(Bomb::deadOnCallback)),
- NULL);
- sprite->runAction(sequneceAction);
2.CCRepeatForever:永遠執行一個動作
- static CCRepeatForever * CCRepeatForever ::actionWithAction (CCActionInterval *pAction)
使用舉例:比如,一個精靈我只會改變他的位置,但是不需要改變他的動畫,那麼我就可以使用這個來保持這個動畫一直運行,我在炸彈人的Monster類中使用了類似代碼:
- CCActionInterval *action=getAnimate();//獲得炸彈播放動畫,自己實現的函數
- spirte->runAction(CCRepeatForever::actionWithAction(action));
3.CCSequence:按序列執行動作,這會讓節點連續執行幾個動作。
- static CCFiniteTimeAction * CCSequence::actions (CCFiniteTimeAction *pAction1,...)
使用舉例:這個例子經常使用的時候,就是執行一個動作,然後回調。比如主角行走一個格子後,切換為站立狀態。我在炸彈人的Hero類中使用了這種方法:
- CCAction *sequneceAction = CCSequence::actions(moveByAction,CCCallFunc::actionWithTarget(this, callfunc_selector(Hero::moveDoneCallback)),NULL);
- this->runAction(sequneceAction);
注意最後要使用NULL結尾。表示傳參結束。我不明白為什麼非要強制加NULL,按道理說C++不定參數表,可以不用NULL的。看原始碼才發現,裡面用到了真值判斷刷迴圈。我不知道這是為了和ObjectiveC文法保持一致還是為什麼,我並不熟悉Objc。
- CCFiniteTimeAction* CCSequence::actions(CCFiniteTimeAction *pAction1, ...)
- {
- va_list params;
- va_start(params, pAction1);
-
- CCFiniteTimeAction *pNow;
- CCFiniteTimeAction *pPrev = pAction1;
-
- while (pAction1)
- {
- pNow = va_arg(params, CCFiniteTimeAction*);
- if (pNow)
- {
- pPrev = actionOneTwo(pPrev, pNow);
- }
- else
- {
- break;
- }
- }
-
- va_end(params);
- return pPrev;
- }
4.CCSpawn:同時執行幾個動作,最終動作的期間,由時間最長的那個動作確定。
- static CCFiniteTimeAction * actions (CCFiniteTimeAction *pAction1,...);
使用舉例:可以用CCSpacwn來做翻跟頭的動畫,只需要組合moveTo和RotateBy。Test中有這個代碼:
- CCAction* action = CCSpawn::actions(
- CCJumpBy::actionWithDuration(2, CCPointMake(300,0), 50, 4),
- CCRotateBy::actionWithDuration( 2, 720),
- NULL);
-
- m_grossini->runAction(action);
注意,從字面意思你就知道,不要在CCSequence中使用CCRepeatForever,兩者是互相衝突的。
第四部分:反動作反動作是使用一個介面實現的,該介面直接返回一個此動作的反動作。
- virtual CCFiniteTimeAction * reverse (void)
注意,並非所有動作都有反動作,xxxTo沒有,xxxBy則有。使用舉例:反動作很容易造出一個動作迴圈來,在Test中有這個代碼:
- CCActionInterval* jump = CCJumpBy::actionWithDuration(2, CCPointMake(300,0), 50, 4);
- CCFiniteTimeAction* action = CCSequence::actions( jump, jump->reverse(), NULL);
-
- m_grossini->runAction(action);