quick lua 3.3常用方法和學習技巧之transition.lua


 

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM