【游戏功能】
上一版藏了条只在长战斗里露头的隐蔽报错:吞劲的计数器跨场不清零——第一场怪喂满了五拳把它噎住,第二场新怪刚出手两拳就莫名被噎,账面上多出三拳来历不明的旧账。追到根上是噎住结算只清了演出没清计数器,怪换了账本没换。修完把清账写进换目标的那一拍,顺手把这套机制的正经写法整理成篇。吞劲纹的账很简单:它打你的每一拳都在给你记功,五拳封账,它自己噎住。这篇把整套模块拆开:配置表、记功账本、封账噎住、空门结算、清账时机、定时器、调试按钮,一段一段照抄能跑。
一、效果演示:喂它五拳,它自己噎住
演示场点「张口!」:一圈青纹张在怪身上——十二秒的吞劲期。怪的拳头一记记落在你身上,每挨一拳它头顶亮一颗绿珠——五颗珠子是封账线。第五拳落账的一拍,它双手掐脖子当场噎住:两秒的大空门,白挨你二十点的清算刀。噎完珠子清零,账本重开,接着喂。演示里试两笔账:硬挨五拳换两秒空门值不值——五拳六十多点血买它噎住加二十清算,外加两秒的随便输出,这笔账怎么算都不亏。吞劲纹教的是借力:它的凶是你的功,打你的每一拳都在填它自己的坟。
fx-swallow
二、底层原理:一本记功账加一次封账噎住
模块的机关是一对搭档。记功账:吞劲期里怪的每一拳进一颗珠——账认的是它打你,不认你打它,挨打是记账的唯一凭据。封账噎住:五珠封账的那一拍它当场噎住——两秒的空门加二十点的清算刀,噎完珠清账重开,下一轮接着喂。和反伤类机制的分野在"吞劲的清算是一口价的空门":反伤是它打你多少它掉多少,细水长流没有节奏;吞劲攒五拳换一声钟——空门的节奏感是玩家蹲的节目,账越满,等的那一声越响。
清账为什么挂在换目标那一拍?那场"第二场秒被噎"的报错就是账本没跟着怪走——账认怪不认场,换宿主的那一拍旧账必须当场撕掉,新怪从零起步,这既是公平也是那篇报错的正解。
三、核心代码:完整模块(上·骨架)
-- @file Swallow.lua
-- 吞劲纹 —— 喂它五拳,它自己噎住
local Swallow = {}
local CONST = {
CREST_LIFE = 12.0,
CREST_CD = 4.0,
STACK_CAP = 5,
CHOKE_LIFE = 2.0,
CHOKE_DMG = 20,
COLOR_SWAL = "#689868",
COLOR_DEEP = "#1e4018",
COLOR_GHOST = "#c8e8c0",
ZORDER_SWAL = 133,
ZORDER_FX = 135,
AUTOINC_BASE = 1095000,
}
local _crestT = 0
local _stacks = 0
local _chokeT = 0
local _cdLeft = 0
local _hostID = 0
local _crestFx = nil
local _scheduler = nil
local _autoInc = 0
local function GenID(prefix)
_autoInc = _autoInc + 1
return string.format("%s_%d", prefix or "SWL",
CONST.AUTOINC_BASE + _autoInc)
end
local function GetActorPos(id)
if not id then return nil end
local x = SL:GetValue("ACTOR_POSITION_X", id)
local y = SL:GetValue("ACTOR_POSITION_Y", id)
if not x or not y then return nil end
return { x = x, y = y }
end
local function SafeRemove(node)
if node and not GUI:Widget_IsNull(node) then
GUI:removeFromParent(node)
end
end
local function ShowTip(msg)
if msg and msg ~= "" then SL:ShowSystemTips(msg) end
end
-- 清账:换宿主的那一拍旧账当场撕掉
local function ResetStacks(newHost)
_stacks = 0
_hostID = newHost or 0
end
四、核心代码:完整模块(下·记功封账与噎住结算)
-- 记功:它打你的每一拳进一颗珠
SL:RegisterLUAEvent(LUA_EVENT_HURT_TAKEN, "SWL_Feed", function(srcID)
if _crestT <= 0 or _chokeT > 0 then return end
if srcID ~= _hostID then
ResetStacks(srcID)
return
end
_stacks = _stacks + 1
if _stacks >= CONST.STACK_CAP then
Swallow.Choke()
end
end)
-- 封账噎住:五珠封顶,空门加清算一并结账
function Swallow.Choke()
_stacks = 0
_chokeT = CONST.CHOKE_LIFE
local tid = SL:GetValue("MARK_TARGET_ID")
if not tid then return end
SL:AddBuff(tid, "CHOKE_STUN", CONST.CHOKE_LIFE)
SL:ActorHurt(tid, CONST.CHOKE_DMG)
SL:TipAbove(tid, "噎!-" .. CONST.CHOKE_DMG)
SL:PlayChokeFx(tid)
ShowTip("它噎住了——两秒空门,白拿二十")
end
function Swallow.Cast()
if _cdLeft > 0 or _crestT > 0 then return end
local tid = SL:GetValue("MARK_TARGET_ID")
if not tid then return end
_cdLeft = CONST.CREST_CD
_crestT = CONST.CREST_LIFE
ResetStacks(tid)
SafeRemove(_crestFx)
_crestFx = GUI:Layout_Create(GUI:Attach_SceneF(),
GenID("Crest"), 0, 0, 0, 0, false)
GUI:setLocalZOrder(_crestFx, CONST.ZORDER_SWAL)
SL:PlaySwallowUpFx(tid)
ShowTip("吞劲纹开了——它的每一拳都在给你记功")
end
-- 定时器:纹成倒计时与噎住消化
if not _scheduler then
_scheduler = SL:Schedule(function(dt)
_cdLeft = math.max(0, _cdLeft - dt)
if _chokeT > 0 then
_chokeT = _chokeT - dt
if _chokeT <= 0 then
ShowTip("它噎完了——拳头又落下来了")
end
end
if _crestT > 0 then
_crestT = _crestT - dt
local tid = SL:GetValue("MARK_TARGET_ID")
local tp = tid and GetActorPos(tid)
if _crestFx and tp then
GUI:setPosition(_crestFx, tp.x, tp.y - 96)
end
if _crestT <= 0 then
SafeRemove(_crestFx)
ResetStacks(0)
ShowTip("纹收了——账清了,回到平常的挨打")
end
end
end, 0.02)
end
SL:ScheduleOnce(function()
SL:BindDebugButton("张口", function()
Swallow.Cast()
end)
ShowTip("技能已加载: 吞劲纹 (调试按钮触发)")
end, 1.0)
function Swallow.Unload()
if _scheduler then SL:Unschedule(_scheduler) end
SL:UnregisterLUAEvent(LUA_EVENT_HURT_TAKEN, "SWL_Feed")
SafeRemove(_crestFx)
_crestT = 0
ResetStacks(0)
end
return Swallow
五、机制问答
问:换怪了旧账跟着走吗?
答:不跟——换宿主那一拍旧账当场清零,新怪从零珠起步,那场"第二场秒被噎"的报错就是这步没做。
问:噎住的两秒里玩家被打断吗?
答:不会——空门里它出不了手,你随便吃药随便输出,这2秒是完全属于你的窗口。
问:五颗珠子半场攒不满怎么办?
答:攒不满就白开——珠子认拳头不认时间,窝囊怪不出手的局一颗珠都攒不上,吞劲要挑凶怪开。
问:清算的二十点吃斩残加成吗?
答:不吃——清算是封账的固定价,单独结算不加成不暴击,这一刀的意义在开空门不在砍痛。
问:噎住期间它被队友杀死了账怎么办?
答:账随人死——宿主一倒账本作废,珠子清空,下一只怪从头喂起,账本一怪一册。
六、调参指南与商业服怎么用
第四笔是封账的门槛:五拳对怪的出手间隔是"十三秒喂满"的节奏——门槛太低噎住太频繁变成循环控制,太高三拳还没喂满纹先到期了。第三笔是空门的时长:两秒对玩家的一轮爆发是"够打两刀加个技能"的窗口——空门太短清算是孤零零的二十点,太长变成晕两秒半的换皮控制。第二笔是清算的定价:二十点对五拳六十多的代价是"三成回本加一个空门"——清算太高挨打成了挣钱,玩家会故意站桩喂拳,定价要压住这份邪道。第一笔是珠子的可见:五颗珠就是账本——玩家数珠就知道还差几拳,噎住的预告全靠这几颗珠吊着。常见坑三个:计数器跨场不清零的旧账报错;噎住和眩晕类控制的免疫表没对齐导致首领怪被白噎;珠子在纹过期后还挂在怪头顶没消失。
商业服里吞劲纹是"化功门"的气口:别人躲拳他吃拳——商城里珠子的样式做成品级,木珠、玉珠、舍利珠,那五颗一格格亮起的珠子就是化功门的念珠。运营落地还有两笔:一段是喂拳教学——教一句"越凶的怪喂得越快,噎住就是你的节拍",流派第一课是敢挨;一段是化功榜——按封账噎住的总次数排名,噎得最多的人有碑。变体做成化劲反哺:噎住期间你的刀附带吸血——空门的两秒从白打变成回血,化功门的气越来越长。这一篇的演示和整套模块照抄能跑,改的就是 CONST 那张表。
写完留一句给做挨打系的同学:吞劲纹卖的是"它的拳都是你的功"——那五颗一格格亮起的珠子和噎住时的清算大字,是把挨打从损耗改成储蓄的第一本功德簿。
全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →
接手二开的兄弟几乎都撞过同一堵墙:玩家嫌走路"一格一格像机器人",老板拍板要"丝滑移动",改服务端速度?不对。改客户端动画帧…
【游戏功能】 先看一个熟场面:法师的火球特效挂在怪的脚后跟上,明明技能说明写着"焚烧其面",火星子却在地上打滚。群里有位策划…
【游戏功能】 上周有个开服的老板在群里发了一段录屏:他的战士明明刀刀都砍中了,观众却一片"这刀挥空了吧"。他原话是"判定日志…
【游戏功能】 先说结论放在开头:怪的皮一会儿绿一会儿红,不是美术换了几套贴图,是染色系统在怪身上盖了一层"色镜"。开服群里有…
前两天群里有个架设的朋友问了个需求:中毒的人要变绿、每两秒掉一次血、毒还能叠五层,问是不是要在服务端把整套状态机重写。我说你…
【游戏功能】 先抛一个坑:五口钟一模一样大,为什么一口比一口疼?先后次序动不得吗?倒过来敲会怎样?这篇把编钟纹整套写法拆开:…