從代碼的角度講,行爲其實就是改變實體的屬性,如座標、角度等,這些屬性大部分都可以靠實體類自身封裝的方法來設置,之所以要用行爲單獨封裝它們,還是爲了使操作更加簡便。試想,當我們要讓一個實體連續執行一段行爲序列或者不斷重複執行一個行爲時,編碼會變得相當複雜,如果這一過程還是在一定時間內逐漸完成的該怎麼辦,各種複雜的行爲摻雜在一起同時執行,是不是想一想就頭大呢?這就是行爲類存在的最大意義,它會使編碼過程變得異常簡單,就像是策劃在寫腳本一樣~
行爲類的基類是CCAction,任何一種行爲都是由它拓展衍變而來的。行爲類可以分爲四大類:有限次執行類、速度行爲類和跟隨移動類,有限次執行類又可以分爲瞬時行爲類和過程行爲類。
圖中的CCAction是基類,比較抽象,在實際開發中不會直接用到,更多的是在參數傳遞中充當‘泛型’;CCFiniteTimeAction從字面就能看出來(finite = 有限的),是有限次執行類,它是最爲普通的行爲,就是按時間順序做一系列事情,做完後行爲結束;CCRepeatForever的名字更易懂了,無限重複行爲類,就是說它可以讓節點反覆的做一件事,除非把行爲或節點刪除,否則永遠不會停止;CCSpeed的作用是調整行爲實例的執行速度,因此它依賴於其它的行爲,單獨的CCSpeed沒有意義;CCFollow可以使節點跟隨指定的另一個節點移動。
下面我就介紹一下這些類的工作原理:
CCAction聲明瞭如下方法:
+(id) action
創建一個CCAction實例,其實就是封裝了alloc、init和autorelease方法。
-(void) startWithTagert: (id)aTarget
將節點與行爲對象相關聯。
-(void) stop
取消節點與行爲的關聯,即停止行爲。
-(void) isDone
檢測行爲是否執行完畢。
-(void) step
計算自身行爲的執行狀況,即任務完成了多少,並調用自身的update。
-(void) update
執行自身行爲的主邏輯,是行爲的核心算法。
-(void) pause
暫停行爲(可恢復)。
-(void) unPause
從暫停中恢復。
-(BOOL) isRunning
檢測行爲是否在更新邏輯。
*需要注意的是,CCAction是抽象類,很多方法都是空的,它主要靠自己的子類去實現接口,因此不能直接用CAction的對象描述節點的行爲。
CCFiniteTimeAction
CCFiniteTimeAction是所有有限次執行類(或者也可以叫順序執行類吧)的基類,這種類在遊戲中的應用是相當多的,因此儘管它也是個抽象類,但對於它的理解將直接影響到遊戲開發的效率與質量。
-( CCFiniteTimeAction*) reverse
CCFiniteTimeAction只增加了一個接口,其作用是反向執行一個行爲,比如一個行爲對象的作用是將節點右移10個像素,那麼當這個對象執行了reverse後,執行它的節點會向左移動10像素。但是CCFiniteTimeAction只是聲明瞭該方法,實現還是交給了它的子類。
CCRepeatForever
CCRepeatForever的接口和CCFiniteTimeAction大致相同(除了初始化),只是實現方法不同。它們的區別是:CCFiniteTimeAction執行有限次,有結束的一刻,而CCRepeatForever永遠不會自己停止,會無限的執行;CCFiniteTimeAction的子類有具體的行爲含義,可以獨立存在,而CCRepeatForever沒有具體含義,它只表示會重複地執行,因此它必須依附於有具體含義的行爲。
+(id) actionWithAction: (CCActionInterval*)action
CCRepeatForever其實是對另一個行爲的封裝,參數action就是被封裝的行爲對象。
CCSpeed
CCSpeed的接口和CCRepeatForever一樣,沒有什麼特別之處,它的作用就是改變其它行爲的執行速度,比如一個精靈以每秒10幀的速度切換自己的frame來播放動畫,CCSpeed可以將其改成每秒20幀或每秒5幀。
CCFollow
+(id) actionWithTarget: (CCNode*)fNode
使節點跟隨另一個節點移動,參數fNode即爲被跟隨的節點。
+(id) actionWithTarget: (CCNode*)fNode worldBoundary: (CGRect)rect
使節點跟隨另一個節點移動,參數rect表示跟隨者只能在該區域內移動,如超出該範圍,則停止跟隨。
CCActionInterval
持續性(防和諧= =)行爲類,CCFiniteTimeAction的子類,因此能和所有繼承自CCFiniteTimeAction的類的對象組成行爲序列,換句話說,它不能和CCRepeatForever、CCSpeed以及CCFollow組成行爲序列。它和CCActionInstant的區別在於:CCActionInterval行爲的執行需要一定的時間(或者說一個過程),而CCActionInstant的行爲都是瞬間完成的,沒有過程(類似節點的各種“set”方法)。
+(id) actionWithDuration: (ccTime)d
持續行爲類的標誌性方法,作用爲創建一個在d秒內執行完自身行爲的對象並返回。
-(id) initWithDuration: (ccTime)d
初始化,將設置行爲的執行時間設置爲d秒。
CCActionInstant
瞬時行爲類,CCFiniteTimeAction的子類,能和所有繼承自CCFiniteTimeAction的類的對象組成行爲序列。它與CCActionInterval的唯一區別就是沒有執行過程。CCActionInstant的接口沒有什麼特別之處,就不單獨介紹了。
下面列出的是瞬時行爲類的子類
CCHide 隱藏節點,效果類似於CCNode的setVisible:No ,將其封裝成action是爲了使其可以和其他行爲組成一個連續的行爲序列。
[CCHide action]
CCShow 顯示節點,效果類似於CCNode的setVisible:Yes ,與CCHide的作用正好相反。
[CCShow action]
CCToggleVisibility 切換節點可見性,即當節點可見時設爲不可見,不可見時設爲可見。
[CCToggleVisibility action]
CCPlace 放置節點,效果類似於CCNode的setPosition。
[CCPlace actionWithPosition:pos]
CCFlipX 橫向翻轉節點,效果等同於CCNode執行setFlipX函數。
[CCFlipX actionWithFlipX:isFlip]
CCFlipY 縱向翻轉節點,效果等同於CCNode執行setFlipY函數。
[CCFlipY actionWithFlipYX:isFlip]
CCCallFunc 自定義行爲,效果爲調用一個自定義的方法,通過方法的實現來達到自己想要的效果。
[CCCallFunc actionWithTarget:self selector:@selector(fun)]
CCCallFuncN 自定義行爲,效果與CCCallFunc基本相同,只是會將節點對象作爲參數傳遞給被調用的函數。
[CCCallFuncN actionWithTarget:self selector:@selector(fun:)]
CCCallFuncND 自定義行爲,效果與CCCallFuncN基本相同,只是可以額外傳遞一個參數給被調用的函數。
[CCCallFuncND actionWithTarget:self selector:@selector(fun:data:) data:object]
*需要特別注意的是,CallFunc雖然是瞬時行爲,但這個“瞬時”只體現在它調用函數是在一瞬間完成的,但這個函數的執行可能需要一段時間,就是說CallFunc的行爲已經做完了,開始執行序列後面的行爲,但被調用的函數還沒有完成,此時它們是並行的。
下面是持續行爲類,它們全部繼承自CCActionInterval
CCMoveTo 將節點移動到指定座標。
[CCMoveTo actionWithDuration:time position:pos]
CCMoveBy 使節點根據參數發生相對位移。
[CCMoveBy actionWithDuration:time position:pos]
CCJumpTo 使節點跳躍到指定的位置,可以設置高度和次數。
[CCJumpTo actionWithDuration:time position:pos height:height jumps:times]
CCJumpBy 和CCJumpTo類似,但是位移是相對位移。
[CCJumpBy actionWithDuration:time position:pos height:height jumps:times]
CCBezierBy 使節點按貝塞爾曲線運動。
[CCBezierBy actionWithDuration:time Bezier:path] (path的類型是ccBezerConfig,這是一個結構體,成員見下方)
CGPoint endPosition 曲線的終點座標(相對於起點的偏移量,非絕對座標),圖中的P3
CGPoint controlPoint_1 曲線第一個弧度的參考點座標(相對於起點的偏移量,非絕對座標),圖中的P1
CGPoint controlPoint_2曲線第二個弧度的參考點座標(相對於起點的偏移量,非絕對座標),圖中的P2
CCScaleTo 設置節點的縮放倍率。
[CCScaleTo actionWithDuration:time scale:rate]
[CCScaleTo actionWithDuration:time scaleX:x scaleY:y]
CCScaleBy 縮放節點(相對)
[CCScaleBy actionWithDuration:time scale:rate]
[CCScaleBy actionWithDuration:time scaleX:x scaleY:y]
CCRotateTo 設置節點的旋轉角度。
[CCRotateTo actionWithDuration:time angle:rotate]
CCRotateBy 旋轉節點
[CCRotateBy actionWithDuration:time angle:rotate]
CCBlink 使節點閃爍,可以設置閃爍次數。
[CCBlink actionWithDuration:time blinks:times]
CCTintTo 設置節點色調。
[CCTintTo actionWithDuration:time red:r green:g blue:b]
CCTintBy 使節點色調發生偏移。
[CCTintBy actionWithDuration:time red:r green:g blue:b]
(*顏色的參數類型其實就是無符號的byte)
CCFadeTo 逐漸改變透明度
[CCFadeTo actionWithDuration:time opacity:color]
CCFadeIn 淡入。
[CCFadeIn actionWithDuration:time]
CCFadeOut 淡出。
[CCFadeOut actionWithDuration:time]
CCDelay 延遲,即增加一個間歇時間。
[CCDelay actionWithDuration:time]
複合行爲
CCSequence 行爲序列(繼承自CCActionInterval),即將若干個待執行的行爲按順序組合在一起,然後依次執行,如果中間有持續行爲的話則等到前一個行爲執行完畢後再執行下一個(CCCallFunc是並行),因此單獨的CCSequence對象是沒有意義的。
[CCSequence actions:act0, act1, act2, nil] (act0、act1、act2都是單獨的行爲對象)
[CCSequence actionsWithArray:act] (act是保存着行爲對象的數組)
CCSpawn 並行行爲(繼承自CCActionInterval),即將若干個待執行的行爲組合在一起,同時執行它們,行爲的執行時間以最長的那個行爲爲準,就是說當全部的子行爲結束時,CCSpawn纔算結束。單獨的CCSpawn對象也沒有意義。
[CCSpawn actions:act0, act1, act2, nil]
[CCSpawn actionsWithArray:act]
CCRepeat 重複執行行爲(繼承自CCActionInterval),就是將一個已知的行爲或行爲序列多次執行,執行的次數通過參數設定,效果類似於CCRepeatForever,但CCRepeat只執行有限次,有運行結束的那一刻。
[CCRepeat actionWithAction:act times:times]
*上面的三個類都是容器,可以容納多個行爲,它們之間也可以互相容納。
CCAnimation 動畫,這個行爲有點特殊,它並非繼承自CCAction以及CCAction的任何子類,相對來說是個獨立的行爲。CCAnimation的作用是根據一個幀序列連續切換,形成一個動畫,可以說是專門爲精靈類準備的。
變速類行爲
這類行爲的作用就是改變另一行爲的速度,基類是CCEaseAction,繼承自CCActionInterval。
CCEaseIn 由快至慢
CCEaseOut 由慢至快
CCEaseInOut 由快至慢再由慢至快
CCEaseSineIn 由快至慢
CCEaseSineOut 由慢至快
CCEaseSineInOut 由快至慢再由慢至快
CCEaseExponentianIn 由極快至慢
CCEaseExponentianOut 由慢至極快
CCEaseExponentianInOut 由極快至慢再由慢至極快
CCActionmanager
這個類其實並不屬於行爲類,它的父類是NSObject,而不是CCAction,但它又與CCAction密不可分,因此在這裏單獨介紹下。
CCActionmanager是個標準的單例類,它的作用顧名思義,就是管理行爲類的對象,工作原理是:當節點執行runAction時,會把action通過addAction方法將對象傳遞給CCActionmanager的單例,該實例再把這個action添加到自己的行爲序列中。CCActionmanager通過schedule定時刷新自己的update方法,在這個方法中去調用行爲序列中每個action的step(會有一些篩選條件,比如暫停的行爲不會update),這些step方法再根據自身的完成進度去update或是結束行爲。就是說實際上是由CCActionmanager驅動的每個action去更新自己的邏輯,而runAction方法只是將行爲對象添加進CCActionmanager的更新隊列罷了。當節點被清除或是行爲結束時,CCActionmanager會自動將action從隊列中剔除,無需開發者操心。