战场的复活倒计时散落在前端各处自算:客户端本地计时与服务器判定不同步,玩家看到复活了却仍无法操作,投诉"计时器骗人"。复活倒计时分段封装:服务器为唯一计时源,客户端只做展示,倒计时按阶段下发(30 秒通知一次、末 5 秒逐秒推送)。
复活计时与阶段推送:服务端计时、分段通知。示例代码如下:
local reviving = {}
local function startRevive(actorName, seconds)
reviving[actorName] = { endTs = os.time() + seconds }
setontimer(actor, 21, 1000, seconds, 0)
end
local function ontimer21(actor)
actor = getplayerbyname(actor)
local s = reviving[tostring(actor)]
if s == nil then
return
end
local left = s.endTs - os.time()
if left <= 0 then
reviving[tostring(actor)] = nil
setontimer(actor, 21, 0, 0, 0)
sendmsg(actor, 1, "复活!")
beginteleport(actor, 300, 300)
return
end
if left % 30 == 0 or left <= 5 then
sendmsg(actor, 1, "复活倒计时 " .. left .. " 秒。")
end
end
分段推送的节流示例代码如下:
local function shouldNotify(left)
return left <= 5 or left % 30 == 0
end
reviving 表以玩家名为键记录复活截止时间戳,服务器时间为唯一计时源。setontimer(actor, 21, 1000, seconds, 0) 每秒触发一次 ontimer21 检查剩余时间;shouldNotify 节流:末 5 秒逐秒推、此前每 30 秒推一次,通知量降 95%。复活到期 beginteleport 送回复活点并清理计时。
战场复活计时踩过三个坑:一是玩家中途下线,定时器仍在推送到离线会话,触发前要 getplayerbyname 判在线;二是 endTs 用本地时间戳,服务器时间回拨后倒计时变负数,全部改用单调递增的剩余秒计数递减;三是多个战场同时复活共用一个计时键互相覆盖,键加战场 ID 维度分离。
全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →
一、一行代码拆解:POOL = POOL + cost 0.5 —— 奖池滚存的核心:每次抽取把成本的一半注入奖池,未中滚存…
一、隐蔽陷阱:强化费用每星固定 500 金,玩家三天点到满星 15 星;成本按 2 的幂增长(500 乘 2 的星减一次方)…
一、线上事故:组队匹配全服一张等待表逐个比对等级差,300 人同时排队时每次匹配 300 次比较还配错段;按等级段分桶,同段…
一、抛坑提问:回收价按原价五折一口价,强化 12 的神装与白板同价,玩家宁可分解;回收价等于原价乘折旧系数,强化、耐久、稀有…
一、抛坑提问:50×50 城墙格子用嵌套表存,两层寻址多层开销——压平成一维数组,idx = (y-1) 50 + x,一次…
一、一行代码拆解:st = {n = st.n + 1, sum = st.sum + v} —— 计数、求和、最大、最小四…