环境:cocos2d 3.10 Lua
参考:cocos2d-x 示例 ActionsProgressTest
注: 从个人博客园移植而来
简介
进度条动画相关,主要的类接口有:
ProgressTo
: 进度控制,在指定时间内达到指定百分比ProgressFromTo
: 进度控制,在指定时间内从一个百分比到另一个百分比ProgressTimer
: 根据百分比渲染内部的精灵,其变化可以是水平的或者垂直的。(注意渲染的是Sprite而不是ImageView)
其类继承图:
ProgressTo
和ProgressFromTo
的实现,要借助于ProgressTimer
。因此接下来说明下它的常用方法。
ProgressTimer的常用接口:
方法 | 说明 |
---|---|
static ProgressTimer* create(Sprite* sp) | 创建进度条,其参数为精灵对象 |
void setSprite(Sprite *sprite) | 设置进度条使用的Sprite对象 |
Sprite* getSprite() | 获取进度条使用的Sprite对象 |
void setType(Type type) | 设置进度条的类型,有两种:RADIAL:BAR: |
Type getType() | 获取进度条类型 |
void setPercentage(float percentage) | 设置进度条百分比,0~100 |
float getPercentage() | 获取进度条百分比 |
void setReverseProgress(bool reverse) – C++void setReverseDirection(bool value) – lua | 设置反转进度条的方向,如果true为顺时针,如果false为逆时针 |
bool isReverseDirection() | 获取方向是否为反转状态 |
void setMidpoint(const Vec2& point) | 用于修改进度条的中点位置,如果为RADIAL类型,中心则代表圆心位置如果为BAR类型,中心则代表着进度条展开的方向,因此:从左->右展开时,设置为Vec2(0,y)从右->左展开时,设置为Vec2(1,y)从下->上展开时,设置为Vec2(x,0)从上->下展开时,设置为Vec2(x,1) |
Vec2 getMidpoint() | 获取中点位置 |
void setBarChangeRate(const Vec2& barChangeRate ) | 设置BAR类型进度条非变化方向的显示比例 |
Vec2 getBarChangeRate() | 获取BAR类型进度条变化的比例值 |
ProgressTo与ProgressFromTo的进度计算,可参考:
void ProgressTo::update(float time)
{
((kProgressTimerCast)(_target))->setPercentage(_from + (_to - _from) * time);
}
//
void ProgressFromTo::update(float time)
{
((kProgressTimerCast)(_target))->setPercentage(_from + (_to - _from) * time);
}
关于ProgressTimer的绘制可参考:
void ProgressTimer::onDraw(const Mat4 &transform, uint32_t flags)
其实现原理就是通过时间来计算Sprite的顶点vertex的位置而已。
示例
实现方式第一种:
local barBgSpr = cc.Sprite:create("res/bar1.png")
barBgSpr:setPosition(cc.p(winSize.width/2, winSize.height*5/6))
self:addChild(barBgSpr,1)
local barSpr = cc.Sprite:create("res/bar2.png")
-- 创建,注意其参数属性只能为Sprite
local processTimer = cc.ProgressTimer:create(barSpr)
processTimer:setPosition(cc.p(winSize.width/2, winSize.height*5/6))
--[[
设置进度类型,有两种
PROGRESS_TIMER_TYPE_BAR:条形
PROGRESS_TIMER_TYPE_RADIAL: 径向就是绕圆心,设置该模式后,就不用再设定
setBarChangeRate的属性了
]]
processTimer:setType(cc.PROGRESS_TIMER_TYPE_BAR)
--[[
设置PROGRESS_TIMER_TYPE_BAR类型进度条变化率
cc.p(1,0) y=0表示竖向没有变化
cc.p(0,1) x=0表示横向没有变化
该类型为横向变化
]]
processTimer:setBarChangeRate(cc.p(1, 0))
processTimer:setMidpoint(cc.p(0, 0))
-- 设置进度条百分比
processTimer:setPercentage(0)
self:addChild(processTimer,2)
--[[
ProgressTo: 参数: 持续时间(秒),进度(0~100)
ProgressFromTo: 参数:持续时间(秒), 起始进度,结束进度
二者的区别在于: ProgressTo不可重复执行
]]
local action1 = cc.ProgressTo:create(5,100)
local action1 = cc.ProgressFromTo:create(5,0,100)
local action = cc.RepeatForever:create(action1)
processTimer:runAction(action)
实现方式第二种:(模拟血条)
local barSpr = cc.Sprite:create("res/pu_hart.png")
local processTimer = cc.ProgressTimer:create(barSpr)
processTimer:setPosition(cc.p(winSize.width/2, winSize.height*4/6))
processTimer:setType(cc.PROGRESS_TIMER_TYPE_BAR)
-- 设置竖向变化
processTimer:setBarChangeRate(cc.p(0, 1))
processTimer:setMidpoint(cc.p(0, 0))
processTimer:setPercentage(0)
self:addChild(processTimer,2)
local action1 = cc.ProgressFromTo:create(5,0,100)
local action = cc.RepeatForever:create(action1)
processTimer:runAction(action)
实现方式第三种:(模拟技能变化)
-- 技能框
local barBgSpr = cc.Sprite:create("res/111.png")
barBgSpr:setPosition(cc.p(winSize.width/2, winSize.height*3/6))
self:addChild(barBgSpr,1)
-- 技能(应该添加一个技能遮罩层的,但是没有资源)
local barSpr = cc.Sprite:create("res/222.png")
local processTimer = cc.ProgressTimer:create(barSpr)
processTimer:setPosition(cc.p(winSize.width/2, winSize.height*3/6))
-- 设置进度类型为径向
processTimer:setType(cc.PROGRESS_TIMER_TYPE_RADIAL)
processTimer:setPercentage(0)
self:addChild(processTimer,2)
local action1 = cc.ProgressFromTo:create(5,0,100)
local action = cc.RepeatForever:create(action1)
processTimer:runAction(action)
拓展:针对于实现方式第一种,也可以通过时间调度器来控制,我们使用LoadingBar来编写示例,如下:
-- 进度条
self._loadingBar = ccui.LoadingBar:create()
self._loadingBar:loadTexture("res/sliderProgress.png")
self._loadingBar:setPosition(cc.p(winSize.width/2, winSize.height*2/6 - 95))
self._loadingBar:setDirection(ccui.LoadingBarDirection.LEFT)
self._loadingBar:setPercent(0)
self:addChild(self._loadingBar)
local scheduler = cc.Director:getInstance():getScheduler()
if self._timeScheduler ~= nil then
scheduler:unscheduleScriptEntry(self._timeScheduler)
self._timeScheduler = nil
end
-- 每0.1秒刷新
self._timeScheduler = scheduler:scheduleScriptFunc(function(delta)
-- 判定当前的进度
local curpercent = self._loadingBar:getPercent()
if curpercent < 100 then
curpercent = curpercent + delta*10
self._loadingBar:setPercent(curpercent)
else
-- 如果进度 > 100 则重置
self._loadingBar:setPercent(0)
end
end, 0.1, false)
End