Files
Quick-Cocos2dx-Community/quick/framework/transition.lua
u0u0 db03f8c295 Fork from Cocos2d-lua 3.3 final.
Add new Lua Binding for spSkeletonData.
Integrate win32 Player.
Add "exact_fit" mode for display
2015-09-07 20:03:29 +08:00

705 lines
19 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
--[[
Copyright (c) 2011-2014 chukong-inc.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
]]
--------------------------------
-- @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 操作会首先将对象的透明度设置为 00%,完全透明),然后再逐步增加为 255100%,完全不透明)。
如果不希望改变对象当前的透明度,应该用 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 操作会首先将对象的透明度设置为 255100%,完全不透明),然后再逐步减少为 00%,完全透明)。
如果不希望改变对象当前的透明度,应该用 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