主美:有个优化需求,人物恰经验瓶的升级效果有点不太行,是瞬变的。
程序:是直接改经验条的Silder和经验文本的text
主美:现在要做一个经验上涨的效果,然后升级的时候播一下icon的动画。
特效:动画我已经挂上了,你调一下就行了。
程序,简单啊,做一个Tween不就好了
---lua伪代码
local twnAnim = Tweening.DOTween.To(function(fCurValue)
silder.value = fCurValue
end, fBeginValue, fEndValue, fTime)
程序:就是跨级有点麻烦,让主美妥协一下呗,跨级的话就放最后一级的从0经验开始的动画,应该还行吧。
特效:额,彳亍口巴。但是这里有点奇怪,这动画很不连贯啊(狂恰瓶子),经验槽一跳一跳的。
程序:这没办法,Tween动画就是写死的,你写好参数以后最多也就只能控制帧了。新的Tween进来就只能把旧的舍弃了。
特效:能不能不舍弃?
程序:啥意思
特效:比如建个Tween队列之类的
程序:卧槽?emmm。理论上可以,但是要保存的数据有点太多了,而且最好避免回调地狱。
程序:我突然想到是不是基本上连点瓶子,经验增长速度要变快的。
特效:最好是这样,不然没反馈啊。我咋知道恰第二个瓶子的时候有没有用。
程序:啊这。
程序:那更不可能用Tween了,在DOTween的过程中如果恰一个瓶子就要重建Tween,如果用队列,那后面不是都要重建……
程序:算了你先别管了,让我先自闭一会。
(研究了一会)
程序:这个我用协程写了,但是我不知道具体效果到什么程度,我把lua文件的位置给你,你改这个函数开头的几个变量就行
特效:啊这。也行吧
程序:要不我给你讲下怎么弄的
特效:可
---lua伪代码
function SomeView:DoAnimation()
local sliderAnimationTime = 2 --- 动画总时长
self.tbl.anim = {} --- 记录协程动画构建的所需数据
self.tbl.anim.StartValue = self.cur.score or 0 --- 动画的起始总经验(不是槽里的经验)
self.tbl.anim.EndValue = GetScore() --- 动画最终要达到的目标总经验
local off = self.tbl.anim.EndValue - self.tbl.anim.StartValue
self.tbl.anim.step = math.round(off / math.round(sliderAnimationTime / 0.02)) --- 计算步长
self.tbl.anim.step = math.max(1, math.min(50, self.tbl.anim.step)) --- 步长限制修正
--- 注意:如果动画还在进行,那么上面通过修改self.tbl.anim的属性是能够影响到下面协程
--- 的逻辑的。这就是协程的一个特点:独享一份变量
if self.cur.bAnim then
return
end
--- 协程停止。如果ui隐藏或关闭的动画也应该停止。
if self.cs_coroutine.sliderAnim then
Global.cs_coroutine:stop(self.cs_coroutine.sliderAnim)
end
self.cur.bAnim = true --- 初始化代码 ---
self.progressSliderHandle:ExSetActive(true) --- 进度条分界线的特效开启,停止动画后就关闭
local curScore = self.tbl.anim.StartValue --- 动画播放中 的总经验进度
local curLvl, curExp = GetLevelExp(curScore) --- 动画播放中 的当前经验槽的经验进度
--- 开启协程
self.cs_coroutine.sliderAnim = Global.cs_coroutine:start(function()
while true do
local _lvl, _exp = GetLevelExp(curScore)
local _limit = GetNextLevelNeedScore(_lvl) --- 当前动画所在经验槽的分母
if curScore >= self.tbl.anim.EndValue or _limit <= 0 then
--- 情况1,当总经验进度已经到了目标值时,动画结束,可以渲染最终的文本了
--- 注意:这里用的是EndValue而不是curScore对应的等级和经验,因为按照
--- 除法算步长最终到达的位置一定会有误差
local __lvl, __exp = GetLevelExp(self.tbl.anim.EndValue)
local __limit = GetNextLevelNeedScore(_lvl)
self:UpdateSliderValue(__lvl, __exp, __limit) ---- 更新UI数据
if curExp >= _limit or _limit <= 0 then
self.anim.levelUp:Play() --- 升级动画
end
--- 停止协程,关闭动画
self.cur.score = GetScore() ---保存下次的StartValue
self.cur.bAnim = false
Global.cs_coroutine:stop(self.cs_coroutine.sliderAnim)
self.progressSliderHandle:ExSetActive(false)
elseif curExp >= _limit then
--- 情况2,当当前经验槽满了,重置下当前槽
self:UpdateSliderValue(_lvl, curExp, _limit)
self.anim.levelUp:Play()
curExp = 0
else
--- 情况3,经验值动画正常增长,纯渲染
self:UpdateSliderValue(_lvl, curExp, _limit)
end
--- 更新到达的进度
curExp = math.min(_limit, curExp + self.tbl.anim.step)
curScore = math.min(self.tbl.anim.EndValue, curScore + self.tbl.anim.step)
coroutine.yield(nil)
end
end)
end
程序:基本上就是通过协程构建一个渲染循环,然后新的数据进来以后,重新计算步长,这样就能够越点越快了。
特效:迪奥诶,主美你来看下这样可以否
主美:我觉得可以了
特效:但是点得快为啥会忽快忽慢
程序:因为你速度很快的时候动画就很快播完了啊,要不你给我具体的文档,具体到每个速度函数的设计?
主美:算了,可以了可以了
(本文纯属虚构^^)
网友评论