之前我们有用ProgressTimer实现技能CD,现在我们用它来实现一个能量条满的过程。
需求如下:
1.当没满一小格时底层不透明的匀速增加
2.当满一小格时上一层的从格子左边立马推进,同时这个格子会亮一下(用特效实现)
3.当整个能量条满时播放流光特效
部分代码:
local sprite = cc.Sprite:create("ui/Resources/btn/btn_jindutiao_1.png")
local shadowBar = cc.ProgressTimer:create(sprite)
shadowBar:setOpacity(50)
shadowBar:setType(cc.PROGRESS_TIMER_TYPE_BAR )
shadowBar:setPosition(self.view.shadowBar:getPosition())
shadowBar:setMidpoint(cc.p(0,1))
shadowBar:setBarChangeRate(cc.p(1,0))
self.view:addChild(shadowBar,1)
self.shadowBar = shadowBar
--sprite2不能直接拿sprite来用,即使他们的资源一样,否则只有一个暗的进度条在走
local sprite2 = cc.Sprite:create("ui/Resources/btn/btn_jindutiao_1.png")
local processBar = cc.ProgressTimer:create(sprite2)
processBar:setOpacity(200)
processBar:setType(cc.PROGRESS_TIMER_TYPE_BAR )
processBar:setPosition(self.view.progressBar:getPosition())
processBar:setMidpoint(cc.p(0,1))
processBar:setBarChangeRate(cc.p(1,0))
self.view:addChild(processBar,2)
self.processBar = processBar
跟技能CD不同的是类型设置为:cc.PROGRESS_TIMER_TYPE_BAR,而技能CD是径向的:cc.PROGRESS_TIMER_TYPE_RADIAL,而且这里要设置中点跟变化的比例,我们查看设置中点官方文档
红线部分的Y表示任意值,如我们要它从左到右增加,则processBar:setMidpoint(cc.p(0,1))和processBar:setMidpoint(cc.p(0,0))的效果是一样的,同理如果要它从右到左变化,则processBar:setMidpoint(cc.p(1,0))和processBar:setMidpoint(cc.p(1,1))的效果是一样的。
看下设置变化比例
因为我们是x方向匀速变化,而y方向始终100%显示,所以processBar:setBarChangeRate(cc.p(1,0))
初始化好之后,我们来实现匀速增加,定时器的代码就不贴了,反正是每秒给增加一个能量值,然后每秒都设置进度条的比例。
function Power:setProcess(percent)
local str = math.floor(percent/10)
if str > 10 then
str = 10
end
self.view.powerLab:setString(str)
local flag = false
if percent>= 100 then
local res = "res/common/image/effect/UI_001/UI_001_002.csb"
local node = cc.CSLoader:createNode(res)
local action = cc.CSLoader:createTimeline(res)
node:setAnchorPoint(0,0)
node:setPosition(cc.p(self.view.progressBar:getPositionX()-175,self.view.progressBar:getPositionY()))
self.view:addChild(node,4)
local function callBack()
node:removeFromParent()
end
action:setLastFrameCallFunc(callBack)
node:runAction(action)
action:gotoFrameAndPlay(0,false)
flag = true
else
fullFlag = false
end
--刚好满一小格时播放特效
local pos = string.find(tostring(percent),"0")
if pos and not fullFlag then--满了不播单个的特效了
-- print(percent,percent/10,math.floor(percent/10),percent%10,math.floor(percent%10))
local moveAction = cc.ProgressFromTo:create(0.2,self.lastProcessPercent,percent)
self.processBar:runAction(moveAction)
self.lastProcessPercent = percent
local res = "res/common/image/effect/UI_001/UI_001_001.csb"
local node = cc.CSLoader:createNode(res)
local action = cc.CSLoader:createTimeline(res)
node:setAnchorPoint(0.5,0.5)
local cellX = self.barBounding.width/10
local cellY = self.barBounding.height/2
local num = percent/10
local x = self.barBounding.x + (num-1)*cellX+cellX/2
local y = self.barBounding.y + cellY
node:setPosition(cc.p(x,y))
self.view:addChild(node,4)
local function callBack()
node:removeFromParent()
end
action:setLastFrameCallFunc(callBack)
node:runAction(action)
action:gotoFrameAndPlay(0,false)
if flag then
fullFlag = true
end
end
local shadowAction = cc.ProgressFromTo:create(1,self.lastShadowPercent,percent)
self.shadowBar:runAction(shadowAction)
self.lastShadowPercent = percent
end
这里和技能CD有个不一样的地方,动作我们不可能每次都从开始的地方增加,而是从上次的地方增加,所以不是用cc.ProgressTo,而是用cc.ProgressFromTo,它比之前的多一个参数,static ProgressFromTo * create (float duration, float fromPercentage, float toPercentage)
还有这里跟3.3有个不一样的地方,特效之前是用Armature,特效的一般创建方式大概是这样:
local resPath = "res/common/image/effect/"..res.."/"..res
ccs.ArmatureDataManager:getInstance():addArmatureFileInfo(resPath..".csb")
local armature = ccs.Armature:create(res)
armature:getAnimation():playWithIndex(0)
--特效播完的回调
local function animationEvent(armatureBack, movementType, movementID)
if movementType == ccs.MovementEventType.complete then
finishCallBack()
end
end
animation:setMovementEventCallFunc(animationEvent)
而新版本的creator制作的特效是用CC.Loader加载的,代码大致如下:
local res = "res/common/image/effect/UI_001/UI_001_001.csb"
local node = cc.CSLoader:createNode(res)
local action = cc.CSLoader:createTimeline(res)
node:runAction(action)
action:gotoFrameAndPlay(0,false)
local function callBack()
node:removeFromParent()
end
action:setLastFrameCallFunc(callBack)
官方文档的说明是这样使用的:
2.方便的接口:
self.root = cc.CSLoader:createNode("PlayScene.csb"):addTo(self)
注意最后的addTo函数,这些函数是quick提供的,在调用完会返回对象本身,所以我们可以像下面这样使用,不需要重复地去写变量名:
cc.Sprite:create(texture):move(x,y):rotate(r):addTo(p)
这些函数可以在src/cocos/framework/extends/下找到。
3.创建,添加动画:
local tlAct = cc.CSLoader:createTimeline("PlayScene.csb")
self.root:runAction(tlAct)
self.act_tag = tlAct:getTag()--用于后续获取动画
首先使用cc.CSLoader:createTimeline创建动画,然后使用runAction把这个动画挂载到加载出来的节点上。
4.播放动画:
local tlAct =self.root:getActionByTag(self.act_tag)
tlAct:gotoFrameAndPlay(0,false)
先通过tag获取动画,如上。然后调用gotoFrameAndPlay接口,这个接口有三个重载:
gotoFrameAndPlay(begin,end,loop)
gotoFrameAndPlay(begin,loop)
gotoFrameAndPlay(begin)
参数解释:
Begin:从第几帧开始播放
End:播放到第几帧
Loop:是否循环
setLastFrameCallFunc,特效播放到最后一帧都会掉这个函数。