【游戏功能】
接住对手的刀是什么概念?不是挡开,是含着——刀锋停在齿间,力道全数收进嘴里,然后连本带利地吐回去。吞刀把这份狂气做成了两段式:掐着它出刀的时机张口,接住的那一瞬你手里就攥着它的十四点,再点一次,二十一点连本带利砸回它脸上。这篇把整套模块拆开:配置表、吞口构件、接刀判定、吐刀出口、定时器、调试按钮,一段一段照抄能跑。
一、效果演示:张口等刀,吐回去更狠
演示场的怪出刀很勤。点「吞刀!」:玩家身前张开一圈红色的吞口,一秒的窗口挂在头顶。掐在它刀落的那一拍——刀被含住了:不掉血、不闪红,玩家身后悬出一把红色的小刀图标,提示"含刀·点按钮吐回去"。再点一次按钮:含着的刀被一口吐回去,二十一点的紫红大字砸在怪脸上——比它自己那一刀狠一半。要是口张着它没出刀,一秒后空口而归,提示"再等下一刀"。演示里试两件事:掐拍的准头和吐刀的时机——含着不吐,就是悬在它头顶的威胁。吞刀玩的是胆量:敢把脸凑到刀口前的人,才配谈反击。
fx-bladecatch
二、底层原理:一个接刀窗口加一次含刀寄存
模块的机关是一对搭档。接刀窗口:吞口张开的一秒里,怪的近战命中被截胡——伤害一分不掉进血条,整笔攻击连刀带力寄存进"含刀"状态,窗口一秒,掐拍的压力全在这一秒里。含刀寄存:含着的刀不设保质期也不限容量,一次只含一把——寄存期间玩家的普通攻击照常,含刀是另一只手的活。吐刀出口:含刀状态下再点一次按钮,寄存的伤害乘一点五整笔砸回去。和格挡反击的分野在"含"字上:格挡是把刀弹开,回手是回手;吞刀是把刀收进自己身上,什么时候还、还多少,主动权彻底换手。
为什么只含一把?含多把的版本玩家可以把三口刀攒成一套连吐,吞刀从赌时机变成囤货——一把的容量逼着玩家接了就吐或者等更好的那一刀,贪,是要用冷却付账的。
三、核心代码:完整模块(上·骨架)
-- @file BladeCatch.lua
-- 吞刀 —— 把它的刀含在嘴里,连本带利吐回去
local BladeCatch = {}
local CONST = {
CATCH_WINDOW = 1.0,
CATCH_CD = 5.0,
SPIT_AMP = 1.5,
COLOR_BLADE = "#c04868",
COLOR_DEEP = "#4e1220",
COLOR_GHOST = "#f0b0c0",
ZORDER_MOUTH = 133,
ZORDER_FX = 135,
AUTOINC_BASE = 1003000,
}
local _catchT = 0
local _stored = 0
local _cdLeft = 0
local _mouthFx = nil
local _scheduler = nil
local _autoInc = 0
local function GenID(prefix)
_autoInc = _autoInc + 1
return string.format("%s_%d", prefix or "BCT",
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 ShowMouthFx()
local myID = SL:GetValue("USER_ID")
SafeRemove(_mouthFx)
_mouthFx = GUI:Layout_Create(GUI:Attach_SceneF(),
GenID("Mouth"), 0, 0, 0, 0, false)
GUI:setLocalZOrder(_mouthFx, CONST.ZORDER_MOUTH)
local mp = GetActorPos(myID)
if mp then GUI:setPosition(_mouthFx, mp.x, mp.y - 56) end
end
function BladeCatch.OpenMouth()
if _stored > 0 then
BladeCatch.Spit()
return
end
if _cdLeft > 0 or _catchT > 0 then return end
_cdLeft = CONST.CATCH_CD
_catchT = CONST.CATCH_WINDOW
ShowMouthFx()
SL:PlayMouthOpenFx()
ShowTip("口张开了——一秒内它的刀尽管来")
end
四、核心代码:完整模块(下·定时器与接吐结算)
-- 接刀判定:窗口内的近战整笔寄存
SL:RegisterLUAEvent(LUA_EVENT_MELEE_HIT, "BCT_Catch", function(tid, dmg)
if _catchT > 0 and dmg and dmg > 0 then
_catchT = 0
_stored = dmg
SafeRemove(_mouthFx)
SL:PlayCatchFx()
SL:TipAboveMe("接住了!")
ShowTip("刀含住了——再点一下,连本带利吐回去")
return 0
end
return dmg
end)
-- 吐刀出口
function BladeCatch.Spit()
if _stored <= 0 then return end
local tid = SL:GetValue("MARK_TARGET_ID")
local tp = GetActorPos(tid)
if not tp then return end
local out = math.floor(_stored * CONST.SPIT_AMP)
_stored = 0
SL:ActorHurt(tid, out)
SL:TipAbove(tid, "吐-" .. out)
SL:PlaySpitFx(tid)
SL:ScreenShake(3, 0.2)
ShowTip("连本带利吐回去——" .. out .. "点入账")
end
-- 定时器:窗口推进与空口提示
if not _scheduler then
_scheduler = SL:Schedule(function(dt)
_cdLeft = math.max(0, _cdLeft - dt)
if _catchT > 0 then
_catchT = _catchT - dt
if _catchT <= 0 then
SafeRemove(_mouthFx)
ShowTip("口合上了——空口而归,再等下一刀")
end
end
end, 0.02)
end
SL:ScheduleOnce(function()
SL:BindDebugButton("吞刀", function()
BladeCatch.OpenMouth()
end)
ShowTip("技能已加载: 吞刀 (调试按钮触发)")
end, 1.0)
function BladeCatch.Unload()
if _scheduler then SL:Unschedule(_scheduler) end
SafeRemove(_mouthFx)
_stored = 0
end
return BladeCatch
五、机制问答
问:吞口能接住远程箭吗?
答:不能——吞的是近身的刀,箭从远处来,口够不着,说明栏写明"仅限近战",别让弓手玩家白按。
问:含着刀被控制了怎么办?
答:刀不掉——寄存跟着人不跟着状态,晕住的三秒刀照样含着,醒来那一口照吐,控制破不了吞刀的账。
问:能含住暴击刀吗?
答:能,连暴击倍率一起含——吐回去的一点五倍乘在含住的总额上,接住一把暴击刀再吐出去,是对面最不愿看的一幕。
问:窗口里它不出刀,白开了吗?
答:白开——空口也要吃掉五秒冷却,掐拍的失误就是代价,吞刀的赌局从张口那一帧就开始算钱。
问:吐刀的目标能换吗?
答:不能——含的是它的刀,吐也只能吐回它脸上,谁的刀还谁,吞刀的账目干净得有原则。
六、调参指南与商业服怎么用
第四笔是吐刀的倍率:一点五倍是"反击比挨打疼"的底线档——等倍吐回去不叫反击叫还礼,两倍以上的版本出刀怪集体改行,一点五刚好让接刀的人笑、出刀的人疼。第三笔是窗口的紧度:一秒对怪两点二秒的出招周期是"必有一次刀可接"的宽限——窗口缩到零点五秒就是纯手速考核,放到两秒张口就能白嫖。第二笔是寄存的规则:一把为限、不限时长——容量管住囤货,时长管出博弈,含着不吐本身就是悬在怪头上的刀。第一笔是含刀的可视化:接住的瞬间身后悬出那把红色小刀——含没含住一眼可读,吐刀的时机才有的商量,图标就是存折。常见坑三个:接刀判定挂在闪避后,被闪避的空刀也算接住;吐刀期间再按吞口,两段状态打架;寄存值不设上限,接住千点大刀吐出去直接破榜。
商业服里吞刀是"狂刀流派"的门胆:敢含刀的人才配讲反击——商城里吞口的样式做成品级,血口、兽口、龙口,张口那一瞬的红光就是狂刀的獠牙。运营落地还有两笔:一段是时机教学——教学关只教"看它抬手再张口",一句话讲完流派的全部门槛;一段是含刀榜——按吐回的最大单笔伤害排名,接住暴击刀的传说有了登记处。变体做成快吐:接住后零点六秒不吐自动回敬——手慢的玩家也有保底反击,手快的依旧可以憋大招。这一篇的演示和整套模块照抄能跑,改的就是 CONST 那张表。
写完留一句给做反击系的同学:吞刀卖的是"你的刀归我了"——那把含在嘴里的红刀,是它亲手递上来的把柄,吐出去的那一口,连本带利。
全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →
【游戏功能】 先消费后还款这事儿,战场上也行得通?赊账的答案是行得通,但有利息:点一下赊账,下一刀双倍——多出来的那十点伤害…
【游戏功能】 为什么棒球里全垒打最值钱?因为球在天上的那一秒,全场的眼睛都仰着头。全垒把这份仰头搬进了打架:一记挑空把小怪送…
【游戏功能】 后台埋点抓到一个怪数据:某位玩家的承伤记录里,被远程命中数是零——不是躲得快,是他挨的每一箭都"消失了"。翻录…
【游戏功能】 P.x, C.x = C.x, P.x —— 一行换位,借刀的全部机关就藏在这一笔里:玩家和小怪换个位置,怪的…
【游戏功能】 打群架的最高境界是什么?是一个人打,让对面自己人打自己人。搬兵把这句话演成了动作:抓住一只小怪举过头顶,抡圆了…
【游戏功能】 同样的装备,为什么老玩家打得越来越疼?新手第一刀十点,第一百刀还是十点;老玩家第一刀十点,第一百刀已经十四——…