完整课程入口:996 全套课程体系 | Lua 学习路径 | 幂尔框架 mirs.cn
战斗里的伤害飘字是创建销毁最频繁的 UI 元素:团战每秒几十个数字生成又消失。每个数字独立创建 label 控件的方式,GC 与节点树操作会吃掉 2~3ms 的帧时间。飘字对象池把 label 控件循环复用,配合数字缓动动画,战斗特效的 UI 开销可以压到 0.3ms 以内。
local pool = {}
local function acquire()
for _, label in ipairs(pool) do
if not label.inUse then
label.inUse = true
return label
end
end
local label = GUI:Text_Create(fxLayer, "dmg_" .. os.clock(), 0, 0, 18, "#FFFFFF", "")
label.inUse = true
pool[#pool + 1] = label
return label
end
local function showDamage(x, y, text)
local label = acquire()
GUI:Text_SetText(label, text)
label:setPosition(x, y)
label:runAction(cc.Sequence:create(
cc.Spawn:create(cc.MoveBy:create(0.6, cc.p(0, 60)), cc.FadeOut:create(0.6)),
cc.CallFunc:create(function() label.inUse = false end)
))
end
动画结束的 CallFunc 把控件归还池中,整个过程零创建零销毁。同屏 30 个飘字连续触发时,UI 线程耗时稳定在 0.3ms 左右,相比每次新建的方式帧耗时下降约 85%。
池上限与溢出策略:池上限 40 个,全部占用时新的飘字直接丢弃(战斗中低价值的旧飘字本就不需要全部展示)。归位清理:归还时重置缩放与透明度(上个动画可能停在半透明状态),防止状态串场。场景切换清池:切场景时把池整体随界面层销毁重建,避免跨场景引用失效节点。
飘字优化离不开聚合:同一目标 0.5 秒内的多次伤害合并为一条累计飘字,触发频率从每击一次降为每 0.5 秒一次,池的压力与视觉噪声同步下降。对象池、聚合、预算控制(特效预算表)三项合起来,战斗 UI 的性能上限就有了制度保障。
暴击伤害使用更大字号、独立颜色与额外缩放动画,与普通伤害在一屏内可分辨。区分显示的数据来源是结算结果里的暴击标志,飘字接口按标志选择样式。样式差异是战斗反馈的重要组成,同一套池子按标志切样式即可,无需两套实现。