transition.lua主要是動作相關的操作。
-------------------------------- -- @module transition --[[-- 為圖像創造效果 ]] local transition = {} local ACTION_EASING = {} ACTION_EASING["BACKIN"] = {cc.EaseBackIn, 1} ACTION_EASING["BACKINOUT"] = {cc.EaseBackInOut, 1} ACTION_EASING["BACKOUT"] = {cc.EaseBackOut, 1} ACTION_EASING["BOUNCE"] = {cc.EaseBounce, 1} ACTION_EASING["BOUNCEIN"] = {cc.EaseBounceIn, 1} ACTION_EASING["BOUNCEINOUT"] = {cc.EaseBounceInOut, 1} ACTION_EASING["BOUNCEOUT"] = {cc.EaseBounceOut, 1} ACTION_EASING["ELASTIC"] = {cc.EaseElastic, 2, 0.3} ACTION_EASING["ELASTICIN"] = {cc.EaseElasticIn, 2, 0.3} ACTION_EASING["ELASTICINOUT"] = {cc.EaseElasticInOut, 2, 0.3} ACTION_EASING["ELASTICOUT"] = {cc.EaseElasticOut, 2, 0.3} ACTION_EASING["EXPONENTIALIN"] = {cc.EaseExponentialIn, 1} ACTION_EASING["EXPONENTIALINOUT"] = {cc.EaseExponentialInOut, 1} ACTION_EASING["EXPONENTIALOUT"] = {cc.EaseExponentialOut, 1} ACTION_EASING["IN"] = {cc.EaseIn, 2, 1} ACTION_EASING["INOUT"] = {cc.EaseInOut, 2, 1} ACTION_EASING["OUT"] = {cc.EaseOut, 2, 1} ACTION_EASING["RATEACTION"] = {cc.EaseRateAction, 2, 1} ACTION_EASING["SINEIN"] = {cc.EaseSineIn, 1} ACTION_EASING["SINEINOUT"] = {cc.EaseSineInOut, 1} ACTION_EASING["SINEOUT"] = {cc.EaseSineOut, 1} local actionManager = cc.Director:getInstance():getActionManager() -- start -- -------------------------------- -- 創建一個緩動效果 -- @function [parent=#transition] newEasing -- @param Action action 動作對象 -- @param string easingName 緩沖效果的名字, 具體參考 transition.execute() 方法 -- @param mixed more 創建緩沖效果的參數 -- @return mixed#mixed ret (return value: mixed) 結果 -- end -- function transition.newEasing(action, easingName, more) local key = string.upper(tostring(easingName)) if string.sub(key, 1, 6) == "CCEASE" then key = string.sub(key, 7) end local easing if ACTION_EASING[key] then local cls, count, default = unpack(ACTION_EASING[key]) if count == 2 then easing = cls:create(action, more or default) else easing = cls:create(action) end end return easing or action end -- start -- -------------------------------- -- 創建一個動作效果 -- @function [parent=#transition] create -- @param Action action 動作對象 -- @param table args 參數表格對象 -- @return mixed#mixed ret (return value: mixed) 結果 -- end -- function transition.create(action, args) args = checktable(args) if args.easing then if type(args.easing) == "table" then action = transition.newEasing(action, unpack(args.easing)) else action = transition.newEasing(action, args.easing) end end local actions = {} local delay = checknumber(args.delay) if delay > 0 then actions[#actions + 1] = cc.DelayTime:create(delay) end actions[#actions + 1] = action local onComplete = args.onComplete if type(onComplete) ~= "function" then onComplete = nil end if onComplete then actions[#actions + 1] = cc.CallFunc:create(onComplete) end if #actions > 1 then return transition.sequence(actions) else return actions[1] end end -- start -- -------------------------------- -- 執行一個動作效果 -- @function [parent=#transition] execute -- @param cc.Node target 顯示對象 -- @param Action action 動作對象 -- @param table args 參數表格對象 -- @return mixed#mixed ret (return value: mixed) 結果 --[[-- 執行一個動作效果 ~~~ lua -- 等待 1.0 后開始移動對象 -- 耗時 1.5 秒,將對象移動到屏幕中央 -- 移動使用 backout 緩動效果 -- 移動結束后執行函數,顯示 move completed transition.execute(sprite, MoveTo:create(1.5, cc.p(display.cx, display.cy)), { delay = 1.0, easing = "backout", onComplete = function() print("move completed") end, }) ~~~ transition.execute() 是一個強大的工具,可以為原本單一的動作添加各種附加特性。 transition.execute() 的參數表格支持下列參數: - delay: 等待多長時間后開始執行動作 - easing: 緩動效果的名字及可選的附加參數,效果名字不區分大小寫 - onComplete: 動作執行完成后要調用的函數 - time: 執行動作需要的時間 transition.execute() 支持的緩動效果: - backIn - backInOut - backOut - bounce - bounceIn - bounceInOut - bounceOut - elastic, 附加參數默認為 0.3 - elasticIn, 附加參數默認為 0.3 - elasticInOut, 附加參數默認為 0.3 - elasticOut, 附加參數默認為 0.3 - exponentialIn, 附加參數默認為 1.0 - exponentialInOut, 附加參數默認為 1.0 - exponentialOut, 附加參數默認為 1.0 - In, 附加參數默認為 1.0 - InOut, 附加參數默認為 1.0 - Out, 附加參數默認為 1.0 - rateaction, 附加參數默認為 1.0 - sineIn - sineInOut - sineOut ]] -- end -- function transition.execute(target, action, args) assert(not tolua.isnull(target), "transition.execute() - target is not cc.Node") local action = transition.create(action, args) target:runAction(action) return action end -- start -- -------------------------------- -- 將顯示對象旋轉到指定角度,並返回 Action 動作對象。 -- @function [parent=#transition] rotateTo -- @param cc.Node target 顯示對象 -- @param table args 參數表格對象 -- @return mixed#mixed ret (return value: mixed) 結果 --[[-- 將顯示對象旋轉到指定角度,並返回 Action 動作對象。 ~~~ lua -- 耗時 0.5 秒將 sprite 旋轉到 180 度 transition.rotateTo(sprite, {rotate = 180, time = 0.5}) ~~~ ]] -- end -- function transition.rotateTo(target, args) assert(not tolua.isnull(target), "transition.rotateTo() - target is not cc.Node") -- local rotation = args.rotate local action = cc.RotateTo:create(args.time, args.rotate) return transition.execute(target, action, args) end -- start -- -------------------------------- -- 將顯示對象移動到指定位置,並返回 Action 動作對象。 -- @function [parent=#transition] moveTo -- @param cc.Node target 顯示對象 -- @param table args 參數表格對象 -- @return mixed#mixed ret (return value: mixed) 結果 --[[-- 將顯示對象移動到指定位置,並返回 Action 動作對象。 ~~~ lua -- 移動到屏幕中心 transition.moveTo(sprite, {x = display.cx, y = display.cy, time = 1.5}) -- 移動到屏幕左邊,不改變 y transition.moveTo(sprite, {x = display.left, time = 1.5}) -- 移動到屏幕底部,不改變 x transition.moveTo(sprite, {y = display.bottom, time = 1.5}) ~~~ ]] -- end -- function transition.moveTo(target, args) assert(not tolua.isnull(target), "transition.moveTo() - target is not cc.Node") local tx, ty = target:getPosition() local x = args.x or tx local y = args.y or ty local action = cc.MoveTo:create(args.time, cc.p(x, y)) return transition.execute(target, action, args) end -- start -- -------------------------------- -- 將顯示對象移動一定距離,並返回 Action 動作對象。 -- @function [parent=#transition] moveBy -- @param cc.Node target 顯示對象 -- @param table args 參數表格對象 -- @return mixed#mixed ret (return value: mixed) 結果 --[[-- 將顯示對象移動一定距離,並返回 Action 動作對象。 ~~~ lua -- 向右移動 100 點,向上移動 100 點 transition.moveBy(sprite, {x = 100, y = 100, time = 1.5}) -- 向左移動 100 點,不改變 y transition.moveBy(sprite, {x = -100, time = 1.5}) -- 向下移動 100 點,不改變 x transition.moveBy(sprite, {y = -100, time = 1.5}) ~~~ ]] -- end -- function transition.moveBy(target, args) assert(not tolua.isnull(target), "transition.moveBy() - target is not cc.Node") local x = args.x or 0 local y = args.y or 0 local action = cc.MoveBy:create(args.time, cc.p(x, y)) return transition.execute(target, action, args) end -- start -- -------------------------------- -- 淡入顯示對象,並返回 Action 動作對象。 -- @function [parent=#transition] fadeIn -- @param cc.Node target 顯示對象 -- @param table args 參數表格對象 -- @return mixed#mixed ret (return value: mixed) 結果 --[[-- 淡入顯示對象,並返回 Action 動作對象。 fadeIn 操作會首先將對象的透明度設置為 0(0%,完全透明),然后再逐步增加為 255(100%,完全不透明)。 如果不希望改變對象當前的透明度,應該用 fadeTo()。 ~~~ lua action = transition.fadeIn(sprite, {time = 1.5}) ~~~ ]] -- end -- function transition.fadeIn(target, args) assert(not tolua.isnull(target), "transition.fadeIn() - target is not cc.Node") local action = cc.FadeIn:create(args.time) return transition.execute(target, action, args) end -- start -- -------------------------------- -- 淡出顯示對象,並返回 Action 動作對象。 -- @function [parent=#transition] fadeOut -- @param cc.Node target 顯示對象 -- @param table args 參數表格對象 -- @return mixed#mixed ret (return value: mixed) 結果 --[[-- 淡出顯示對象,並返回 Action 動作對象。 fadeOut 操作會首先將對象的透明度設置為 255(100%,完全不透明),然后再逐步減少為 0(0%,完全透明)。 如果不希望改變對象當前的透明度,應該用 fadeTo()。 ~~~ lua action = transition.fadeOut(sprite, {time = 1.5}) ~~~ ]] -- end -- function transition.fadeOut(target, args) assert(not tolua.isnull(target), "transition.fadeOut() - target is not cc.Node") local action = cc.FadeOut:create(args.time) return transition.execute(target, action, args) end -- start -- -------------------------------- -- 將顯示對象的透明度改變為指定值,並返回 Action 動作對象。 -- @function [parent=#transition] fadeTo -- @param cc.Node target 顯示對象 -- @param table args 參數表格對象 -- @return mixed#mixed ret (return value: mixed) 結果 --[[-- 將顯示對象的透明度改變為指定值,並返回 Action 動作對象。 ~~~ lua -- 不管顯示對象當前的透明度是多少,最終設置為 128 transition.fadeTo(sprite, {opacity = 128, time = 1.5}) ~~~ ]] -- end -- function transition.fadeTo(target, args) assert(not tolua.isnull(target), "transition.fadeTo() - target is not cc.Node") local opacity = checkint(args.opacity) if opacity < 0 then opacity = 0 elseif opacity > 255 then opacity = 255 end local action = cc.FadeTo:create(args.time, opacity) return transition.execute(target, action, args) end -- start -- -------------------------------- -- 將顯示對象縮放到指定比例,並返回 Action 動作對象。 -- @function [parent=#transition] scaleTo -- @param cc.Node target 顯示對象 -- @param table args 參數表格對象 -- @return mixed#mixed ret (return value: mixed) 結果 --[[-- 將顯示對象縮放到指定比例,並返回 Action 動作對象。 ~~~ lua -- 整體縮放為 50% transition.scaleTo(sprite, {scale = 0.5, time = 1.5}) -- 單獨水平縮放 transition.scaleTo(sprite, {scaleX = 0.5, time = 1.5}) -- 單獨垂直縮放 transition.scaleTo(sprite, {scaleY = 0.5, time = 1.5}) ~~~ ]] -- end -- function transition.scaleTo(target, args) assert(not tolua.isnull(target), "transition.scaleTo() - target is not cc.Node") local action if args.scale then action = cc.ScaleTo:create(checknumber(args.time), checknumber(args.scale)) elseif args.scaleX or args.scaleY then local scaleX, scaleY if args.scaleX then scaleX = checknumber(args.scaleX) else scaleX = target:getScaleX() end if args.scaleY then scaleY = checknumber(args.scaleY) else scaleY = target:getScaleY() end action = cc.ScaleTo:create(checknumber(args.time), scaleX, scaleY) end return transition.execute(target, action, args) end -- start -- -------------------------------- -- 創建一個動作序列對象。 -- @function [parent=#transition] sequence -- @param table args 動作的表格對象 -- @return Sequence#Sequence ret (return value: cc.Sequence) 動作序列對象 --[[-- 創建一個動作序列對象。 ~~~ lua local sequence = transition.sequence({ cc.MoveTo:create(0.5, cc.p(display.cx, display.cy)), cc.FadeOut:create(0.2), cc.DelayTime:create(0.5), cc.FadeIn:create(0.3), }) sprite:runAction(sequence) ~~~ ]] -- end -- function transition.sequence(actions) if #actions < 1 then return end if #actions < 2 then return actions[1] end local prev = actions[1] for i = 2, #actions do prev = cc.Sequence:create(prev, actions[i]) end return prev end -- start -- -------------------------------- -- 在顯示對象上播放一次動畫,並返回 Action 動作對象。 -- @function [parent=#transition] playAnimationOnce -- @param cc.Node target 顯示對象 -- @param cc.Node animation 動作對象 -- @param boolean removeWhenFinished 播放完成后刪除顯示對象 -- @param function onComplete 播放完成后要執行的函數 -- @param number delay 播放前等待的時間 -- @return table#table ret (return value: table) 動作表格對象 --[[-- 在顯示對象上播放一次動畫,並返回 Action 動作對象。 ~~~ lua local frames = display.newFrames("Walk%04d.png", 1, 20) local animation = display.newAnimation(frames, 0.5 / 20) -- 0.5s play 20 frames transition.playAnimationOnce(sprite, animation) ~~~ 還可以用 Sprite 對象的 playAnimationOnce() 方法來直接播放動畫: ~~~ lua local frames = display.newFrames("Walk%04d.png", 1, 20) local animation = display.newAnimation(frames, 0.5 / 20) -- 0.5s play 20 frames sprite:playAnimationOnce(animation) ~~~ playAnimationOnce() 提供了豐富的功能,例如在動畫播放完成后就刪除用於播放動畫的 Sprite 對象。例如一個爆炸效果: ~~~ lua local frames = display.newFrames("Boom%04d.png", 1, 8) local boom = display.newSprite(frames[1]) -- playAnimationOnce() 第二個參數為 true 表示動畫播放完后刪除 boom 這個 Sprite 對象 -- 這樣爆炸動畫播放完畢,就自動清理了不需要的顯示對象 boom:playAnimationOnce(display.newAnimation(frames, 0.3/ 8), true) ~~~ 此外,playAnimationOnce() 還允許在動畫播放完成后執行一個指定的函數,以及播放動畫前等待一段時間。合理運用這些功能,可以大大簡化我們的游戲代碼。 ]] -- end -- function transition.playAnimationOnce(target, animation, removeWhenFinished, onComplete, delay) local actions = {} if type(delay) == "number" and delay > 0 then target:setVisible(false) actions[#actions + 1] = cc.DelayTime:create(delay) actions[#actions + 1] = cc.Show:create() end actions[#actions + 1] = cc.Animate:create(animation) if removeWhenFinished then actions[#actions + 1] = cc.RemoveSelf:create() end if onComplete then actions[#actions + 1] = cc.CallFunc:create(onComplete) end local action if #actions > 1 then action = transition.sequence(actions) else action = actions[1] end target:runAction(action) return action end -- start -- -------------------------------- -- 在顯示對象上循環播放動畫,並返回 Action 動作對象。 -- @function [parent=#transition] playAnimationForever -- @param cc.Node target 顯示對象 -- @param cc.Node animation 動作對象 -- @param number delay 播放前等待的時間 -- @return table#table ret (return value: table) 動作表格對象 --[[-- 在顯示對象上循環播放動畫,並返回 Action 動作對象。 ~~~ lua local frames = display.newFrames("Walk%04d.png", 1, 20) local animation = display.newAnimation(frames, 0.5 / 20) -- 0.5s play 20 frames sprite:playAnimationForever(animation) ~~~ ]] -- end -- function transition.playAnimationForever(target, animation, delay) local animate = cc.Animate:create(animation) local action if type(delay) == "number" and delay > 0 then target:setVisible(false) local sequence = transition.sequence({ cc.DelayTime:create(delay), cc.Show:create(), animate, }) action = cc.RepeatForever:create(sequence) else action = cc.RepeatForever:create(animate) end target:runAction(action) return action end -- start -- -------------------------------- -- 停止一個正在執行的動作 -- @function [parent=#transition] removeAction -- @param mixed target --[[-- 停止一個正在執行的動作 ~~~ lua -- 開始移動 local action = transition.moveTo(sprite, {time = 2.0, x = 100, y = 100}) .... transition.removeAction(action) -- 停止移動 ~~~ ]] -- end -- function transition.removeAction(action) if not tolua.isnull(action) then actionManager:removeAction(action) end end -- start -- -------------------------------- -- 停止一個顯示對象上所有正在執行的動作 -- @function [parent=#transition] stopTarget -- @param mixed target --[[-- 停止一個顯示對象上所有正在執行的動作 ~~~ lua -- 開始移動 transition.moveTo(sprite, {time = 2.0, x = 100, y = 100}) transition.fadeOut(sprite, {time = 2.0}) .... transition.stopTarget(sprite) ~~~ 注意:顯示對象的 performWithDelay() 方法是用動作來實現延時回調操作的,所以如果停止顯示對象上的所有動作,會清除該對象上的延時回調操作。 ]] -- end -- function transition.stopTarget(target) if not tolua.isnull(target) then actionManager:removeAllActionsFromTarget(target) end end -- start -- -------------------------------- -- 暫停顯示對象上所有正在執行的動作 -- @function [parent=#transition] pauseTarget -- @param mixed target -- end -- function transition.pauseTarget(target) if not tolua.isnull(target) then actionManager:pauseTarget(target) end end -- start -- -------------------------------- -- 恢復顯示對象上所有暫停的動作 -- @function [parent=#transition] resumeTarget -- @param mixed target -- end -- function transition.resumeTarget(target) if not tolua.isnull(target) then actionManager:resumeTarget(target) end end return transition
