Cocos2d-x 的[Action]裡,定義了一些基本的『動畫動作類別』和『動作管理類別』。
那在眾多『動作類別』裡,我們該如何分辨它是什麼樣的類別?
我們先從基本的『動畫動作類別』開始講解,
每一個
『動畫動作類別』 都會有一個『xxxTo』、『xxxBy』。基本上只要看到這兩種結尾的Function,就不用懷疑,他就是一個
『動畫動作類別』。
[Action] + [To]
代表會從現在的的狀態,隨時間轉換到指定狀態。
Ex:
/**
* @param {Number} duration duration in seconds
* @param {cc.Point} position
* @return {cc.MoveTo}
* @example
* // example
* var actionTo = cc.MoveTo.create(2, cc.PointMake(windowSize.width - 40, windowSize.height - 40));
*/
cc.MoveTo.create = function (duration, position)
就跟字面上的意思一樣,這個『動畫動作類別』會讓綁定的宿主,『在
指定的時間內,從
目前的位置,移動到
指定位置』。
接下來就直接使用看看吧!
var actionMoveTo = cc.MoveTo.create(1,cc.ccp(128,128));
sprite.runAction(actionMoveTo);
我們接著用上次[cc.Sprite],在宣告[sprite]之後,加上以上程式碼。
執行了程式後,[sprite]會在一秒內,從本來的位置移動到(128 , 128)位置。
var actionRotateTo = cc.RotateTo.create(1,720);
sprite.runAction(actionRotateTo);
執行了這段程式碼後,[sprite]會在一秒內,改變角度至[720]度,初始值是0,也就是轉兩圈。
var actionScaleTo = cc.ScaleTo.create(1,0.5);
sprite.runAction(actionScaleTo);
執行了這段程式碼後,[sprite]會在一秒內,縮放至[0.5]倍,初始值是1,也就是變成一半大小。
var actionFadeTo = cc.FadeTo.create(1,128);
sprite.runAction(actionFadeTo);
執行了這段程式碼後,[sprite]會在一秒內,改變透明度至[128],初始值是255,也就是變為一半的透明度。
緊接著我們介紹
[Action] + [By]
我們看一下其中一段原始碼
/**
* @param {Number} duration duration in seconds
* @param {cc.Point} position
* @return {cc.MoveBy}
* @example
* // example
* var actionBy = cc.MoveBy.create(2, cc.PointMake(80, 80));
*/
cc.MoveBy.create = function (duration, position)
這個看起來和[Action] + [To]沒什麼不一樣,其實還是有差的,
依照原始碼給的範例,這個『動作類別』會讓綁定的宿主,從原本的座標個別累加至80。
而這類型的『動作類別』還有一個[reverse]函式,可以讓目標物件返回原本的狀態。
使用上與[Action] + [To]是一樣的,只是使用單這個『動作類別』,其實沒有很明顯的效果。
所以我們必須搭配『動作管理類別』一起使用。
『動作管理類別』總共有三種,分別是[cc.Sequence]、[cc.Spawn]和[cc.RepeatForever]。
[cc.Sequence]
/** helper constructor to create an array of sequenceable actions
* @param {Array|cc.FiniteTimeAction} tempArray
* @return {cc.FiniteTimeAction}
* @example
* // example
* // create sequence with actions
* var seq = cc.Sequence.create(act1, act2);
* // create sequence with array
* var seq = cc.Sequence.create(actArray);
*/
cc.Sequence.create = function (/*Multiple Arguments*/tempArray)
[cc.Sequence]這個類別會依照,傳入的『動作類別』以Queue的方式,依序執行動作,
以下以程式碼進行解說,
var actionMoveBy = cc.MoveBy.create(1, cc.ccp(80, 80));
var actionSequence = cc.Sequence.create(actionMoveBy,actionMoveBy.reverse());
sprite.runAction(actionSequence);
執行了上面這段程式碼後,[sprite]會先移動到自己座標(+80,+80)的位置,然後再移回原本的位置。
然而,依[cc.Sequence]的註解行上的說明,他是允許複數動作進行排程進行的。
所以我們也可以多定義幾個動作,再把它們排入[cc.Sequence]的行程裏,讓他依序去執行。
var actionMoveBy = cc.MoveBy.create(1, cc.ccp(80, 80));
var actionSequence = cc.Sequence.create(actionMoveBy,actionMoveBy.reverse());
sprite.runAction(actionSequence);
以上原始碼裏,我讓[cc.Sequence]進行四個動作行程,效果我就不多做解釋了!執行看看吧!
[cc.Spawn]
/**
* @param {Array|cc.FiniteTimeAction}tempArray
* @return {cc.FiniteTimeAction}
* @example
* // example
* var action = cc.Spawn.create(cc.JumpBy.create(2, cc.PointMake(300, 0), 50, 4), cc.RotateBy.create(2, 720));
*/
cc.Spawn.create = function (/*Multiple Arguments*/tempArray)
[cc.Spawn]這個類別不同於[cc.Sequence]的地方是它會讓加進來的所動作,同時進行。
看一段程式碼吧!
var actionMoveBy = cc.MoveBy.create(1, cc.ccp(80, 80));
var actionRotateBy = cc.RotateBy.create(0.5,360);
var actionSpawn = cc.Spawn.create(actionMoveBy,actionRotateBy);
sprite.runAction(actionSpawn);
運行了程式碼後,會看到[sprite]一邊移動,一邊旋轉。
但是因為旋轉的時間比較短,所以旋轉會比較早結束。
跟[cc.Sequence]一樣,他也是允許複數的動作同時進行,所以你也可以讓[sprite]一邊移動、旋轉、縮放…等動作,這些就自由發揮吧。
[cc.
RepeatForever ]
[cc.RepeatForever],跟字面上的意思一樣,他會一直重複動作。上前兩個不同的地方是,它只能接受一組動作,但是可以傳入的動作也包含[cc.Sequence]和[cc.Spawn]。
這樣說好了,其實所有的『動作管理類別』,都是一個『動作類別』,所以理所當然的,也可以互相加入彼此。
比如說,我想讓物體一邊放大、然後旋轉並移動到目的地,完畢之後再讓物體回到原本的位置,並且恢復原本大小,然後重複以上動作。
這些都是可以靠『動作管理類別』達成的。
我們就來實現以上的動作吧!
var actionMoveBy = cc.MoveBy.create(1, cc.ccp(80, 80));
var actionRotateBy = cc.RotateBy.create(0.5,360);
var actionScaleBy = cc.ScaleBy.create(0.5,2);
var actionSpawn = cc.Spawn.create(actionMoveBy,actionRotateBy,actionScaleBy);
var actionSequence = cc.Sequence.create(actionSpawn,actionSpawn.reverse());
var actionRepeat = cc.RepeatForever.create(actionSequence);
sprite.runAction(actionRepeat);
以上的程式碼,就實現了上述的動作要求。
其他比較重要的,還有一個[cc.CallFunc]的動作類別,我們先來看看他的原始碼
/** creates the action with the callback
* @param {object} selectorTarget
* @param {function|Null} selector
* @param {*|Null} data data for function, it accepts all data types.
* @return {cc.CallFunc}
* @example
* // example
* // CallFunc without data
* var finish = cc.CallFunc.create(this, this.removeSprite);
*
* // CallFunc with data
* var finish = cc.CallFunc.create(this._grossini, this.removeFromParentAndCleanup, true),
*/
cc.CallFunc.create = function (selectorTarget, selector, data)
[cc.CallFunc]這個動作,是作為程式的『Callback』用,因此若將它加在[cc.Sequence]的尾端,它就會在最後執行,依此類推。
[cc.CallFunc]的第一個參數,一般來說都是傳入『物件』本身(即動作的宿主)。
第二個參數則是想要呼叫的函式。
第三個參數是想傳遞的值,如範例,它傳入一個『true』的值,在『Callback』條件達成時就會一起被傳進去。
我們來看一段程式碼,
宣告
var actionMoveBy = cc.MoveBy.create(1, cc.ccp(80, 80));
var callback = cc.CallFunc.create(sprite, Main.callback, true);
sprite.runAction(cc.Sequence.create(actionMoveBy, actionMoveBy.reverse(),
Main.callback));
Callback函式
Main.callback = function (sprite, data) {
var actionRotateBy = cc.RotateBy.create(0.05, 5);
var callback = cc.CallFunc.create(sprite, Main.callback, true);
sprite.runAction(cc.Sequence.create(actionRotateBy,actionRotateBy.reverse(), Main.callback));
};
效果就自己執行看看吧!