【游戏功能】
上一版出过一场"永远差一"的诡异报错:对账纹的两本账永远对不平——头账加一、地账加一,眼看平了,判定却总说差一。查了半天是判定的时序:两笔账在同一帧里各自入账,判等却夹在两笔之间跑——头账先进地账未进,每一帧都差着半口。修完把判等挪到两笔都落账之后,账才第一次真正对平。这篇把整改后的整套模块拆开:配置表、双账记录、对平判定、翻倍结算、定时器、调试按钮,一段一段照抄能跑。
一、效果演示:两本账对平了,下一刀翻倍
演示场点「对账!」:两本账同时开张——头账记你的刀,怪头顶蹦"头1";地账记它的爪,你脚边蹦"地1"。它一爪你一刀,两本账一比一地涨——涨到相等的那一拍,"账平!"的金字双方同时亮起,你的下一刀自带翻倍:二十四点劈下去,两本账清零重新记。演示里试两笔账:见刀就砍的乱账和对齐节拍的对账——乱打的人账目错开一辈子吃不着翻倍,会对账的人每一拍平账都领一份二十四。对账纹教的是对拍:不是比谁打得快,是比谁打得齐。
fx-ledgermatch
二、底层原理:两本分账加一次对平判定
模块的机关是一对搭档。双账记录:纹成期里两本账各记各的——头账记你出的刀,地账记它落的爪,两本账各自涨各自的,谁也不管谁。对平判定:每一笔账入完之后查一次两本账的读数——读数相等且大于零的那一拍算对平,翻倍的许可当场挂上,下一刀兑现。和增伤类机制的分野在"对账的倍数是俩人凑出来的":普通增伤看你自己,对账的翻倍要它的爪来配——它不出手你的头账孤零零涨,永远等不来对平,这份倍数是打出来的默契,不是白给的施舍。
判定为什么挂在每笔之后而不是每帧查一次?每帧查的版本两笔同帧入账时会漏掉中间态——那场"永远差一"的报错就是判等插在了两笔中间;挂在一笔之后,账面永远是完整状态,判定永远有据可查。
三、核心代码:完整模块(上·骨架)
-- @file LedgerMatch.lua
-- 对账纹 —— 两本账对平了,下一刀翻倍
local LedgerMatch = {}
local CONST = {
CREST_LIFE = 14.0,
CREST_CD = 4.0,
BASE_HIT = 12,
DOUBLE_HIT = 24,
COLOR_MATCH = "#c8b060",
COLOR_DEEP = "#584820",
COLOR_GHOST = "#f8ecc0",
ZORDER_MATCH = 133,
ZORDER_FX = 135,
AUTOINC_BASE = 1120000,
}
local _crestT = 0
local _cdLeft = 0
local _tallyT = 0
local _tallyG = 0
local _doubled = false
local _crestFx = nil
local _scheduler = nil
local _autoInc = 0
local function GenID(prefix)
_autoInc = _autoInc + 1
return string.format("%s_%d", prefix or "LDM",
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 CheckBalance()
if _tallyT > 0 and _tallyT == _tallyG then
_doubled = true
SL:TipAboveMe("账平!")
ShowTip("两本账对平了——下一刀翻倍")
end
end
四、核心代码:完整模块(下·双账记录与翻倍结算)
-- 头账:你的每一刀记一笔,记完即查
SL:RegisterLUAEvent(LUA_EVENT_MELEE_HIT, "LDM_T", function()
if _crestT <= 0 then return 0 end
_tallyT = _tallyT + 1
SL:TipAbove(SL:GetValue("MARK_TARGET_ID"),
"头" .. _tallyT)
CheckBalance()
return 0
end)
-- 地账:它的每一爪记一笔,记完同样查
SL:RegisterLUAEvent(LUA_EVENT_HURT_TAKEN, "LDM_G", function(dmg)
if _crestT <= 0 then return dmg end
_tallyG = _tallyG + 1
CheckBalance()
return dmg
end)
-- 翻倍结算:对平许可挂在下一刀上,兑现即清账
SL:RegisterLUAEvent(LUA_EVENT_MELEE_DAMAGE, "LDM_Pay", function()
if not _doubled then return 0 end
_doubled = false
_tallyT = 0
_tallyG = 0
SL:TipAboveMe("对平!")
return CONST.DOUBLE_HIT - CONST.BASE_HIT
end)
function LedgerMatch.Cast()
if _cdLeft > 0 or _crestT > 0 then return end
local myID = SL:GetValue("USER_ID")
_cdLeft = CONST.CREST_CD
_crestT = CONST.CREST_LIFE
_tallyT = 0
_tallyG = 0
_doubled = false
SafeRemove(_crestFx)
_crestFx = GUI:Layout_Create(GUI:Attach_SceneF(),
GenID("Match"), 0, 0, 0, 0, false)
GUI:setLocalZOrder(_crestFx, CONST.ZORDER_MATCH)
SL:PlayMatchUpFx(myID)
ShowTip("两本账开了——它一爪我一刀,对平了下一刀翻倍")
end
-- 定时器:纹成倒计时与账面清收
if not _scheduler then
_scheduler = SL:Schedule(function(dt)
_cdLeft = math.max(0, _cdLeft - dt)
if _crestT > 0 then
_crestT = _crestT - dt
if _crestT <= 0 then
SafeRemove(_crestFx)
ShowTip("账收了——没对平的账各回各家")
end
end
end, 0.02)
end
SL:ScheduleOnce(function()
SL:BindDebugButton("对账", function()
LedgerMatch.Cast()
end)
ShowTip("技能已加载: 对账纹 (调试按钮触发)")
end, 1.0)
function LedgerMatch.Unload()
if _scheduler then SL:Unschedule(_scheduler) end
SL:UnregisterLUAEvent(LUA_EVENT_MELEE_HIT, "LDM_T")
SL:UnregisterLUAEvent(LUA_EVENT_HURT_TAKEN, "LDM_G")
SL:UnregisterLUAEvent(LUA_EVENT_MELEE_DAMAGE, "LDM_Pay")
SafeRemove(_crestFx)
_crestT = 0
_doubled = false
end
return LedgerMatch
五、机制问答
问:两本账同帧入账会不会漏判?
答:不会——判定挂在每一笔之后,前一笔的判定查的是当时的完整账面,后一笔进来再查一次,两笔都有出场机会。
问:它一爪你两刀,账怎么走?
答:头账跑前面——两刀之后头二地一,差着一口就不平,你得等它补一爪才对平,节奏它说了算一半。
问:对平的翻倍能攒着不打吗?
答:能——许可挂在下一刀上不限时,掐着等怪的破绽再兑现,账平的糖不催命。
问:翻倍兑现后两本账清零吗?
答:清——对平即清账,新一轮从头记,这也是对账纹每一轮都要重新培养默契的原因。
问:它站着不动不配合怎么办?
答:等——地账不动对平就不来,这份倍数是逼你陪它过招的,挂机打不出对平纹的价值。
六、调参指南与商业服怎么用
第四笔是判定的时序:判等必须在两笔之后是这套纹的命门——那场"永远差一"的报错就是判定插了队,时序错一拍,机制全哑。第三笔是翻倍的份量:二十四对十二是整倍的对价——倍数太低对账不如散砍,太高变成节奏玩法的垄断者,翻倍刚好是"值得陪它对拍"的位置。第二笔是清账的规矩:兑现即清是账本的卫生——不清账的版本两本账越涨越厚,对平变成恒定状态,翻倍成了挂件。第一笔是双账的可读:头账挂它头顶、地账挂你脚边——两边读数一眼可对,账面看不见的对账是玄学不是机制。常见坑三个:判等插在两笔中间的时序报错;翻倍兑现后忘清账导致倍率常驻;地账把持续伤害的跳数也记了进来账目虚高。
商业服里对账纹是"钱庄派"的票号:别人的增伤靠堆,他的增伤靠对——商城里双账的样式做成品级,木账板、铜账板、鎏金账板,那两本分别挂在两边的账目就是对账纹的票据。运营落地还有两笔:一段是对拍教学——教一句"它一爪你一刀,拍子齐了倍率来",流派第一课是忍手;一段是对平榜——按对账期的对平总次数排名,拍子对得最齐的人有碑。变体做成三账对:头账地账之外添一本气账——从两方到三方,钱庄派的账本越记越厚。这一篇的演示和整套模块照抄能跑,改的就是 CONST 那张表。
写完留一句给做节奏系的同学:对账纹卖的是"倍数是俩人凑的"——那两本各自涨着又互相对望的账目和对平一拍的金光,是把敌方出手算进自己伤害公式的第一本合账。
全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →
接手二开的兄弟几乎都撞过同一堵墙:玩家嫌走路"一格一格像机器人",老板拍板要"丝滑移动",改服务端速度?不对。改客户端动画帧…
【游戏功能】 先看一个熟场面:法师的火球特效挂在怪的脚后跟上,明明技能说明写着"焚烧其面",火星子却在地上打滚。群里有位策划…
【游戏功能】 上周有个开服的老板在群里发了一段录屏:他的战士明明刀刀都砍中了,观众却一片"这刀挥空了吧"。他原话是"判定日志…
【游戏功能】 先说结论放在开头:怪的皮一会儿绿一会儿红,不是美术换了几套贴图,是染色系统在怪身上盖了一层"色镜"。开服群里有…
前两天群里有个架设的朋友问了个需求:中毒的人要变绿、每两秒掉一次血、毒还能叠五层,问是不是要在服务端把整套状态机重写。我说你…
【游戏功能】 先抛一个坑:五口钟一模一样大,为什么一口比一口疼?先后次序动不得吗?倒过来敲会怎样?这篇把编钟纹整套写法拆开:…