cocos2D(九)---- CCAction

之前介紹CCNode的時候說過,動作是指在特定時間內完成移動、縮放、旋轉等操作的行爲,節點可以通過運行動作來實現動畫效果,這裏的動作就是指CCAction對象,它有很多的子類,每個子類都封裝了不同的動作效果。

先來看看CCAction的繼承結構圖

這裏我省略了瞬時動作(CCActionInstant)和間隔動作(CCActionInterval)的子類,因爲它們又包含了非常多的子類,待會再介紹它們的子類。

CCAction和CCFiniteTimeAction都是抽象類,只定義了一些基本屬性和方法,沒有實際用途,我們需要使用它們的子類來初始化動作,然後運行到節點上。


間隔動作

間隔動作就是指需要經過一段時間才能完成的動作,所有的間隔動作都繼承自CCActionInterval。比如CCRotateBy,可以在指定時間內旋轉指定的角度

[java] view plaincopy
  1. // 1秒內順時針旋轉360°  
  2. CCRotateBy *rotate = [CCRotateBy actionWithDuration:1 angle:360];  
  3. [sprite runAction:rotate];  


間隔動作的繼承結構圖:(只列出部分常用的)


由於CCActionInterval的子類太多了,這裏就不一一介紹了,可以查閱下API文檔

下面列舉一下常見的CCActionInterval的子類:

1.CCBlink

閃爍效果

[java] view plaincopy
  1. // 5秒內閃爍20次  
  2. CCBlink *blink = [CCBlink actionWithDuration:5 blinks:20];  
  3. [sprite runAction:blink];  

2.CCMoveBy和CCMoveTo

CCMoveBy是移動一段固定的距離,CCMoveTo是移動到指定的位置

[java] view plaincopy
  1. // 在1秒內,向右移動100單位,同時向上移動80單位  
  2. CCMoveBy *moveBy = [CCMoveBy actionWithDuration:1 position:CGPointMake(10080)];  

[java] view plaincopy
  1. // 在1秒內,從節點的當前位置移動到(100, 80)這個位置  
  2. CCMoveTo *moveTo = [CCMoveTo actionWithDuration:1 position:CGPointMake(10080)];  

3.CCRotateBy和CCRotateTo

CCRotateBy是在當前旋轉角度的基礎上再旋轉固定的角度,CCRotateTo是從當前旋轉角度旋轉到指定的角度

假設精靈在初始化的時候已經順時針旋轉了45°

[java] view plaincopy
  1. sprite.rotation = 45;  


如果使用了CCRotateBy

[java] view plaincopy
  1. CCRotateBy *rotateBy = [CCRotateBy actionWithDuration:1 angle:90];  
  2. [sprite runAction:rotateBy];  
  3.   
  4. // 在1秒內,再順時針旋轉90°,那麼sprite的最終旋轉角度是45° + 90° = 135°  

如果使用了CCRotateTo
[java] view plaincopy
  1. CCRotateTo *rotateTo = [CCRotateTo actionWithDuration:1 angle:90];  
  2. [sprite runAction:rotateTo];  
  3.   
  4. // 在1秒內,順時針旋轉到90°,sprite的最終旋轉角度就是90°  

4.CCScaleBy和CCScaleTo

CCScaleBy是在當前縮放比例的基礎上再縮放固定的比例,CCScaleTo是從當前縮放比例縮放到指定的比例

假設精靈在初始化的時候的縮放比例爲0.8

[java] view plaincopy
  1. sprite.scale = 0.8;  

如果使用了CCScaleBy
[java] view plaincopy
  1. CCScaleBy *scaleBy = [CCScaleBy actionWithDuration:1 scale:0.5];  
  2. [sprite runAction:scaleBy];  
  3. // 在1秒內,寬度和高度再縮小50%,那麼sprite最終縮放比例是0.8 * 0.5 = 0.4  

如果使用了CCScaleTo

[java] view plaincopy
  1. CCScaleTo *scaleTo = [CCScaleTo actionWithDuration:1 scale:0.5];  
  2. [sprite runAction:scaleTo];  
  3. // 在1秒內,寬度和高度縮小爲0.5倍,那麼sprite最終縮放比例是就0.5  

5.CCFadeIn和CCFadeOut和CCFadeTo

CCFadeIn是淡入,即由暗轉亮,從沒有到有;CCFadeOut是淡出,即由亮轉暗,從有到沒有;CCFadeTo用來修改節點的不透明度

[java] view plaincopy
  1. // 在2秒內,從沒有到有  
  2. CCFadeIn *fadeIn = [CCFadeIn actionWithDuration:2];  
  3.   
  4. // 在2s內,從有到沒有  
  5. CCFadeOut *fadeOut = [CCFadeOut actionWithDuration:2];  
  6.   
  7. // 在2s內,不透明度變爲120,即變爲半透明 (不透明度取值範圍是0-255)  
  8. CCFadeTo *fadeTo = [CCFadeTo actionWithDuration:2 opacity:120];  


6.CCRepeat

重複執行某個動作,可以指定重複的次數

[java] view plaincopy
  1. // 1秒中順時針旋轉360°  
  2. CCRotateBy *rotateBy = [CCRotateBy actionWithDuration:1 angle:360];  
  3. // 重複執行2次旋轉動畫  
  4. CCRepeat *repeat = [CCRepeat actionWithAction:rotateBy times:2];  
  5.   
  6. [sprite runAction:repeat];  

7.CCAnimate

按順序地播放圖片,可以實現幀動畫。

例如有下面10張圖片:(玩過街機的同學應該很熟悉,趙雲的大鵬展翅)

不難發現,如果從1.png 到 10.png按順序顯示圖片的話會形成一個動畫

下面用CCAnimate實現動畫效果

[java] view plaincopy
  1. // 用來存放所有的幀  
  2. NSMutableArray *frames = [NSMutableArray array];  
  3. // 加載所有的圖片  
  4. for (int i = 1; i<= 10; i++) {  
  5.     // 文件名  
  6.     NSString *name = [NSString stringWithFormat:@"zy.bundle/%i.png", i];  
  7.     // 根據圖片名加載紋理,一個圖片對應一個紋理對象  
  8.     CCTexture2D *texture = [[CCTextureCache sharedTextureCache] addImage:name];  
  9.     // 根據紋理初始化一個幀  
  10.     CGRect retct = CGRectMake(00, texture.contentSize.width, texture.contentSize.height);  
  11.     CCSpriteFrame *frame = [[[CCSpriteFrame alloc] initWithTexture:texture rect:retct] autorelease];  
  12.     // 添加幀到數組中  
  13.     [frames addObject:frame];  
  14. }  
  15.   
  16. // 根據幀數組初始化CCAnimation,每隔0.1秒播放下一張圖片  
  17. CCAnimation *animation = [CCAnimation animationWithFrames:frames delay:0.1];  
  18.   
  19. // 根據CCAnimation對象初始化動作  
  20. CCAnimate *animate = [CCAnimate actionWithAnimation:animation];  
  21.   
  22. [sprite runAction:animate];  
動畫效果如下:

裏是將10幀分爲10張不同的png圖片。爲了性能着想,其實最好將10幀打包成一個圖片,到時從這張圖片上面切割每一幀,這種圖片我們可以稱爲"紋理相冊",可以用TexturePacker製作紋理相冊


8.CCSequence

一般情況下,如果給節點同時添加幾個動作時,它們會同時運行。比如下面的代碼效果是一邊旋轉一邊縮放

[java] view plaincopy
  1. CCRotateBy *rotateBy = [CCRotateBy actionWithDuration:1 angle:360];  
  2. CCScaleBy *scaleBy = [CCScaleBy actionWithDuration:1 scale:2];  
  3.   
  4. [sprite runAction:rotateBy];  
  5. [sprite runAction:scaleBy];  
但是有時候我們想讓動作一個接着一個運行,那麼就要用到CCSequence
下面演示的效果是,讓精靈先變爲紅色,再從紅色變爲綠色,再從綠色變爲藍色

[java] view plaincopy
  1. CCTintTo *tintTo1 = [CCTintTo actionWithDuration:1 red:255 green:0 blue:0];  
  2. CCTintTo *tintTo2 = [CCTintTo actionWithDuration:1 red:0 green:255 blue:0];  
  3. CCTintTo *tintTo3 = [CCTintTo actionWithDuration:1 red:0 green:0 blue:255];  
  4. // CCTintTo也是CCActionInterval的子類,可以用於更改精靈的顏色。  
  5.   
  6. CCSequence *sequence = [CCSequence actions:tintTo1, tintTo2, tintTo3, nil];  
  7. [sprite runAction:sequence];  
CCSequence會按順序執行參數中傳入的所有動作


9.CCActionEase

當對節點使用CCMoveTo動作時,它會勻速移動到目的地,如果使用CCActionEase就可以使節點由慢到快或者由快到慢地移向目的地。因此CCActionEase是用來改變動作的運行時速度的。

CCActionEase是個非常強大的類,子類非常多,這裏只說明其中的幾個:

CCEaseIn:由慢到快

CCEaseOut:由快到慢

CCEaseInOut:先由慢到快,再由快到慢

舉個代碼例子:

[java] view plaincopy
  1. CCMoveTo *moveTo = [CCMoveTo actionWithDuration:4 position:ccp(300200)];  
  2. CCEaseInOut *easeInOut = [CCEaseInOut actionWithAction:moveTo rate:5];  
  3. [sprite runAction:easeInOut];  
你會看到精靈先由慢到快,再由快到慢。rate參數決定了速率變化的明顯程度,當它大於1時才有效


10.CCGridAction

使用CCGridAction的具體子類可以實現三維效果,例如翻頁效果(CCPageTurn3D)、波浪效果(CCWaves)、流體效果(CCLiquid)。雖然能實現很好看的3D效果,但是它有很大的缺點,如果不啓用深度緩衝,3D效果會有些失真,如果啓用了深度緩衝,會特別耗內存。

如果想開啓深度緩衝的話,就要修改EAGLView的初始化參depthFormat:

[java] view plaincopy
  1. EAGLView *glView = [EAGLView viewWithFrame:[window bounds]  
  2.                                    pixelFormat:kEAGLColorFormatRGB565     
  3.                                    depthFormat:GL_DEPTH_COMPONENT24_OES];  
可以改爲GL_DEPTH_COMPONENT16_OES(16位深度緩衝)或者GL_DEPTH_COMPONENT24_OES(24位深度緩衝),16位深度緩衝佔用的內存較少,但是仍然會有些失真


瞬時動作

瞬時動作(CCActionInstant)是指能夠瞬間完成的動作,可用於改變節點位置、翻轉節點形成鏡像、設置節點的可視性等。

下面大致看下瞬時動作的繼承結構圖:


看完這個圖,你可能覺得CCActionInstant好像沒有一點使用價值,因爲它的好多動作都可以通過修改節點屬性來完成。比如可以通過設置節點的visible屬性來代替使用CCShow\CCHide\CCToggleVisibility、可以通過修改節點的position屬性來代替使用CCPlace其實當它們與CCSequence結合使用時才有價值。比如,我們想先讓節點運行一個CCMoveTo移動到某個位置,移動完畢後再隱藏節點,這時候我們就可以將CCMoveTo、CCHide兩個動作按順序放進CCSequence中達到想要的效果

[java] view plaincopy
  1. // 移動到(300, 200)  
  2. CCMoveTo *moveTo = [CCMoveTo actionWithDuration:2 position:ccp(300200)];  
  3. // 隱藏節點  
  4. CCHide *hide = [CCHide action];  
  5.   
  6. CCSequence *sequence = [CCSequence actions:moveTo, hide, nil];  
  7.   
  8. [sprite runAction:sequence];  

有時候,在一個動作序列(CCSequence)裏面,我們需要在一個動作運行完畢後,調用某個方法執行一些操作,然後再執行下一個動作。那我們就可以結合CCCallFunc和CCSequence完成這個功能。

比如,我們讓精靈先變爲紅色,再從紅色變爲綠色,再從綠色變爲藍色,而且在每次變換顏色後都調用某個方法執行一些操作:

[java] view plaincopy
  1. // 變爲紅色  
  2. CCTintTo *tintTo1 = [CCTintTo actionWithDuration:2 red:255 green:0 blue:0];  
  3. // 變爲紅色後調用self的turnRed方法  
  4. CCCallFunc *fn1 = [CCCallFunc actionWithTarget:self selector:@selector(turnRed)];  
  5.   
  6. // 變爲綠色  
  7. CCTintTo *tintTo2 = [CCTintTo actionWithDuration:2 red:0 green:255 blue:0];  
  8. // 變爲綠色後調用self的turnGreen:方法,參數是運行當前動作的節點  
  9. CCCallFuncN *fn2 = [CCCallFuncN actionWithTarget:self selector:@selector(turnGreen:)];  
  10.   
  11. // 變爲藍色  
  12. CCTintTo *tintTo3 = [CCTintTo actionWithDuration:2 red:0 green:0 blue:255];  
  13. // 變爲藍色後調用self的turnBlue:data:方法,第一個參數是運行當前動作的節點,第二個參數是data的值  
  14. CCCallFuncND *fn3 = [CCCallFuncND actionWithTarget:self selector:@selector(turnBlue:data:) data:@"blue"];  
  15.   
  16. // 最後調用turnDone:方法,傳遞了一個@"done"字符串作爲參數  
  17. CCCallFuncO *fn4 = [CCCallFuncO actionWithTarget:self selector:@selector(turnDone:) object:@"done"];  
  18.   
  19. CCSequence *sequence = [CCSequence actions:tintTo1, fn1, tintTo2, fn2, tintTo3, fn3, fn4, nil];  
  20. [sprite runAction:sequence];  
下面是回調方法的實現:

[java] view plaincopy
  1. - (void)turnRed {  
  2.     NSLog(@"變爲紅色");  
  3. }  
  4.   
  5. // node是運行當前動作的節點  
  6. - (void)turnGreen:(id)node {  
  7.     NSLog(@"變爲綠色:%@", node);  
  8. }  
  9.   
  10. // node是運行當前動作的節點  
  11. - (void)turnBlue:(id)node data:(void *)data {  
  12.     NSLog(@"變爲藍色,%@,%@", node, data);  
  13. }  
  14.   
  15. - (void)turnDone:(id)param {  
  16.     NSLog(@"變換完畢:%@", param);  
  17. }  
你會發現,精靈變爲紅色後就會調用turnRed方法,變爲綠色後會調用turnGreen:方法,變爲藍色後會先調用turnBlue:data:方法,最後調用turnDone:方法

最後做一個總結:

下面這幾個類都會在運行動作時調用一個方法

CCCallFunc :調用方法時不傳遞參數

CCCallFuncN :調用方法時,可以傳遞1個參數,參數值是運行當前動作的節點

CCCallFuncND :調用方法時,可以傳遞2個參數,第1個參數是運行當前動作的節點,第2個參數是actionWithTarget:selector:data:方法中的data值

CCCallFuncO :調用方法時,可以傳遞1個參數,參數值是actionWithTarget:selector:object:方法中的object值


CCRepeatForever

CCRepeatForever直接繼承自CCAction,可以不停地運行某個間隔動作(CCActionInterval)。

如果你想讓精靈不停地旋轉,可以這樣寫:

[java] view plaincopy
  1. // 1秒內順時針旋轉360°  
  2. CCRotateBy *rotate = [CCRotateBy actionWithDuration:1 angle:360];  
  3. // 使用CCRepeatForever重複CCRotateBy動作  
  4. CCRepeatForever *repeat = [CCRepeatForever actionWithAction:rotate];  
  5. [sprite runAction:repeat];  
也能夠利用CCRepeatForever重複一個動作序列(CCSequence)

[java] view plaincopy
  1. // 變爲紅色  
  2. CCTintTo *tintTo1 = [CCTintTo actionWithDuration:1 red:255 green:0 blue:0];  
  3. // 變爲綠色  
  4. CCTintTo *tintTo2 = [CCTintTo actionWithDuration:1 red:0 green:255 blue:0];  
  5. // 變爲藍色  
  6. CCTintTo *tintTo3 = [CCTintTo actionWithDuration:1 red:0 green:0 blue:255];  
  7. CCSequence *sequence = [CCSequence actions:tintTo1, tintTo2, tintTo3, nil];  
  8.   
  9. CCRepeatForever *repeat = [CCRepeatForever actionWithAction:sequence];  
  10.   
  11. [sprite runAction:repeat];  

你會發現精靈的顏色狀態是:紅 -> 綠 -> 藍 -> 紅 -> 綠 -> 藍 -> 紅 ...,一直在紅綠藍3種顏色之間按順序切換


CCSpeed

CCSpeed也是直接繼承自CCAction,可以影響間隔動作(繼承自CCActionInterval的動作)的運行速度

[java] view plaincopy
  1. // 1秒內順時針旋轉360°  
  2. CCRotateBy *rotate = [CCRotateBy actionWithDuration:1 angle:360];  
  3. // 速度變爲原來的一半  
  4. CCSpeed *speed = [CCSpeed actionWithAction:rotate speed:0.5];  
  5. [sprite runAction:speed];  

本來1秒就完成旋轉的,設置speed爲0.5後,就需要2秒才能完成旋轉


原文地址:http://blog.csdn.net/q199109106q/article/details/8604436

感謝作者~!

發佈了27 篇原創文章 · 獲贊 3 · 訪問量 16萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章