【游戏功能】
控制台抛过一条妙报错:attempt to divide by zero,出在狼怪挥爪那一帧。追下去哭笑不得——凝滞诀把时间缩放系数设成了零,狼怪的攻击间隔计数器拿零当除数,当场翻车。时间停止这种帅到没边的技能,实现起来最先翻车的往往是这种最土的算术。修完这个除零,凝滞诀整套拆给你看。
一、定场、独走、解冻三段戏
凝滞诀的一喝分三段。定场:玩家仰天一喝,一圈青白色的涟漪从脚下荡开满场,狼怪连同它飞到半路的毒箭一起定住——箭停在空中带着拖尾,狼怪定在迈步的姿势,一圈淡青色的光弧绕着它慢慢转,整个画面蒙上一层薄薄的青灰,颜色在替所有人宣布"时间停了"。独走:这三秒里只有玩家能动——照常跑位、照常劈砍,砍在定身的狼怪身上还是加伤的"破定"二十二点;飞到半路的毒箭也成了摆设,玩家从箭边上擦身走过,它纹丝不动。解冻:三秒一到,青灰褪去,狼怪带着半拍的回神硬直缓过来,停在半空的毒箭这会儿才呼啸着继续飞——时间还了回去,箭的账也照算。三段连起来,凝滞诀卖的不是控制,是"这半场我说了算"的三秒钟。
定格的画像要经得起逐帧看:狼怪停在迈步的半途,动画帧钉死不走;两根毒箭冻在半空,拖尾的颜色换成青白——冻住的东西不是消失,是被人按了暂停,画面的每一处都要有"暂停键按下去"的痕迹。玩家的特权也画在明处:全场只有玩家的脚底下没有那层青灰的蒙版,刀光在灰调的画面里格外亮——凝滞诀的帅,一半帅在颜色的特供里。定里劈刀加伤的"破定"二字缀在飘字尾巴上,玩家第一次定里出刀就读得懂:这三秒是白给的输出窗口,别浪费在走路上。
完整演示在这——点「凝滞!」定住全场,青灰里随便走随便砍:
fx-timestop
二、幂尔框架实现:时间缩放与豁免名单
幂尔框架里时间停止不是真的停表,是给实体分组挂缩放系数:
local Freeze = {}
local STOP_TIME = 3
local worldScale = 1
function Freeze.Cast()
worldScale = 0 -- 世界: 零速
SL:SetPlayerScale(1) -- 玩家: 豁免
SL:FlashScreen("#a5d6ff", 0.16)
SL:RingWave("player", 90, "frost_ring")
SL:ShowTipAbove("player", "凝滞!")
for _, b in ipairs(SL:GetProjectiles()) do
b.frozen = true -- 半路的箭: 挂起
end
SL:RegOnce("world_resume", STOP_TIME, Freeze.Resume)
end
function Freeze.Resume()
worldScale = 1
for _, b in ipairs(SL:GetProjectiles()) do
b.frozen = false -- 箭的账照算
end
SL:ShowTipAbove("player", "解!")
end
local function onTick(dt)
local wdt = dt * worldScale -- 世界帧差: 缩放而非除法
for _, m in ipairs(SL:GetMonsters()) do
SL:Advance(m, wdt)
end
end
SL:RegTick("freeze_tick", onTick)
SL:RegClick("freeze", Freeze.Cast)
return Freeze
那个除零事故的答案就在 Advance 的入参里:缩放做在乘法上,除法一个不留——间隔 / 缩放 这种写法是除零事故的老巢,缩放为零时乘法太平无事,除法当场爆炸。
调用顺序上还有一处细节:RegOnce 的回表定时器挂在真实时间上而不是世界时间上——凝滞三秒用现实钟计时,世界停不停它的表照走;要是挂进被缩放的时钟,凝滞永远走不完三秒,时停变成时停永动。弹道列表的一挂一放也要成对:凝滞时把箭标记挂起、解冻时逐根放回,漏放一根,那根箭就永远冻在半空——半空悬着一根毒箭的画面挺美,下一场战斗它突然解冻飞出来,就成灵异事件了。
三、豁免的边界与定里的小灶
豁免名单是这个玩法最要紧的一条线:玩家豁免了,那玩家的召唤物、玩家的飞行道具豁不豁?规范写死"玩家的东西跟着玩家走"——召唤物在凝滞里照样扑,玩家掷出的镖照样飞,狼怪的箭停着,这才是"你的三秒"。反过来,定里的狼怪挨打要不要加伤?演示给的答案是二十二点对十六点,破定加伤三成七——定住的三秒是输出窗口,白定不奖,玩家定完就砍的手才养得成。半路的箭解冻后要接着飞而不是消失,这是信用问题:定前它已经离弦,定是全场的事,账是它自己的。凝滞的时长和冷却的配比也有讲究:三秒定配八秒冷却,两轮凝滞之间狼怪有一段完整的攻击节拍,玩家不能靠凝滞永动;定里再按凝滞直接拒绝,灰字"正在凝滞"——时间不能套娃。最后一条给表现组:定住的东西要有"定"的样子——狼怪的动画帧停在当前帧而不是切回待机,箭的拖尾冻在半空,环境粒子也跟着停,画面里所有会动的东西一起憋住,只留玩家的刀光在青灰里走——凝滞诀的帅,一半帅在这一帧全员静止的画像上。
它要和定身系划清界限:定身只定一只怪,凝滞定的是全世界——箭、狼、尘土一起停,玩家的走位、拆招、绕后全在里面发生,它是"给我三秒自由",不是"给它三秒失去自由"。组队语境下这条线更敏感:你的凝滞冻不冻队友的技能弹道?规范写死冻——世界里只有施法者自己豁免,队友的火球也停在半空,这份一视同仁避免了一半的扯皮。另一条是时停类玩法的老毛病:定里打出的伤害要不要攒到解冻一次结清?答案是即时结清——定里每刀当场飘字、当场扣血,不做解冻爆账,玩家读得懂的反馈才是好反馈,攒着爆的那是烟花不是战斗。
全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →
【游戏功能】 控制技能的镜像问题是:锁住了怪,自己是不是也闲着?影锁把这道两难摆上台面:影锁四秒,它动不了、你也动不了——它…
【游戏功能】 打断为什么只有"清读条"一种?震魂偏要反过来——不清招、不断势,打在它读条半途的那一劲顺着招震进腑——中劲十秒…
【游戏功能】 蜂群为什么总是一只一只出?蜂王偏要让它们进化:放一只蜂王出来,杀掉小怪喂它——喂三只升一阶,三阶蜂王的毒刺一秒…
【游戏功能】 技能为什么总是不扣自己的血?血刃偏要反着来:开着血刃的每一刀先扣自己二血、命中回三血——净赚一但要打得中,空刀…
【游戏功能】 bn.t = bn.t - dt ——一行旗面倒计时的代码,撑起了破军旗全部的紧迫感:旗立三秒、圈内加攻三成,…
【游戏功能】 淬毒为什么要一毒到底?淬毒刃偏要一层一层叠:一刀淬一层毒、毒层一秒六地烂,六层封顶之后一刀下去毒伤三十六——叠…