【游戏功能】
明明攻击力一样,为什么有人三刀能顶别人五刀?血契的答案是:那三刀里掺着他自己的血——开契的一瞬扣六十点血,换接下来三刀各加五成,血是本钱,刀是利息。这篇把整套模块拆开:配置表、血契构件、充能扣血、定时器、调试按钮,一段一段照抄能跑。
一、效果演示:扣血三刀,刀刀见狠
演示场玩家的头顶有一条绿色的血条——这就是本钱。点「血契!」:血条当场少一截,头顶亮起三枚红色的契印——接下来的三刀,伤害数字从灰色的十变成红色的十五。三刀打完契印熄灭,提示"想再狠再开一次"。演示里试两条路:满血开契连砍三刀,和残血舍不得开——同样的时间,开契的人多打出一截伤害,差距就是那六十点血的价值。挨怪的刀血条也会掉,掉到见底提示会拦着不让开契——本钱输光了,利息免谈。
fx-bloodpact
二、底层原理:一次充能扣费加一份三层充能
模块的机关是一对搭档。充能扣费:开契那一帧先验血量——血量低过七十直接驳回,够了就扣六十、发三枚契印,扣血走的是真实结算,不吃减伤也不回退。三层充能:契印按刀消耗,每一刀的结算出口查一次契印余数——有印,伤害乘一点五、掉一枚;没印,灰字照旧。充能不计时、只认刀数:开契的人可以慢慢挑那三刀的时机,留给最该狠的场面。
为什么扣的是当前血量而不是上限百分比?扣上限的版本残血照样敢开,扣当前血量的版本残血开契就是自杀——本钱必须从活肉上割,这才是血契的味道。
三、核心代码:完整模块(上·骨架)
-- @file BloodPact.lua
-- 血契 —— 割自己一刀换三刀狠的,血债血偿
local BloodPact = {}
local CONST = {
PACT_COST = 60,
PACT_CHARGES = 3,
PACT_AMP = 1.5,
PACT_CD = 6.0,
MIN_HP_GUARD = 70,
COLOR_PACT = "#c23a4a",
COLOR_DEEP = "#4e1218",
COLOR_GHOST = "#f0a8b0",
ZORDER_SIGIL = 133,
ZORDER_FX = 135,
AUTOINC_BASE = 992000,
}
local _charges = 0
local _cdLeft = 0
local _sigilFx = nil
local _scheduler = nil
local _autoInc = 0
local function GenID(prefix)
_autoInc = _autoInc + 1
return string.format("%s_%d", prefix or "BPC",
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 CreateSigilFx()
local myID = SL:GetValue("USER_ID")
local mp = GetActorPos(myID)
if not mp then return nil end
local node = GUI:Layout_Create(GUI:Attach_SceneF(),
GenID("Sigil"), mp.x, mp.y - 122, 0, 0, false)
GUI:setLocalZOrder(node, CONST.ZORDER_SIGIL)
for i = 1, CONST.PACT_CHARGES do
GUI:DrawRect_Create(node, "sg_" .. i,
(i - 1) * 14 - 18, 0, 10, 6,
CONST.COLOR_PACT, 220)
end
return node
end
function BloodPact.Cast()
if _cdLeft > 0 or _charges > 0 then return end
local myID = SL:GetValue("USER_ID")
local hp = SL:GetValue("ACTOR_HP", myID)
if not hp or hp <= CONST.MIN_HP_GUARD then
ShowTip("血见底了——血契不敢再开")
return
end
_cdLeft = CONST.PACT_CD
_charges = CONST.PACT_CHARGES
SL:ActorHurt(myID, CONST.PACT_COST)
SafeRemove(_sigilFx)
_sigilFx = CreateSigilFx()
SL:PlayPactFx(myID)
ShowTip("契成了——三刀加五成,血本无归算我输")
end
四、核心代码:完整模块(下·定时器与充能出口)
-- 出刀出口:查契印、掉契印
local function OnMeleeOut(tid, dmg)
if _charges <= 0 then return dmg end
_charges = _charges - 1
local out = math.floor(dmg * CONST.PACT_AMP)
SL:TipAbove(tid, "-" .. out)
SL:PlaySigilBreakFx(tid)
if _charges <= 0 then
SafeRemove(_sigilFx)
ShowTip("三刀用完——契散了,想再狠再开一次")
end
return out
end
SL:RegisterLUAEvent(LUA_EVENT_MELEE_HIT, "BPC_Amp", function(tid)
local base = SL:GetValue("HIT_DAMAGE", tid)
return OnMeleeOut(tid, base or 10)
end)
-- 定时器:冷却推进与契印跟脚
if not _scheduler then
_scheduler = SL:Schedule(function(dt)
_cdLeft = math.max(0, _cdLeft - dt)
if _charges > 0 and _sigilFx then
local myID = SL:GetValue("USER_ID")
local mp = GetActorPos(myID)
if mp then
GUI:setPosition(_sigilFx, mp.x, mp.y - 122)
end
end
end, 0.02)
end
SL:ScheduleOnce(function()
SL:BindDebugButton("血契", function()
BloodPact.Cast()
end)
ShowTip("技能已加载: 血契 (调试按钮触发)")
end, 1.0)
function BloodPact.Unload()
if _scheduler then SL:Unschedule(_scheduler) end
SL:UnregisterLUAEvent(LUA_EVENT_MELEE_HIT, "BPC_Amp")
SafeRemove(_sigilFx)
end
return BloodPact
五、机制问答
问:开契那一刀算三刀之一吗?
答:不算——扣血的瞬间只发契不结刀,下一刀才掉第一枚印,开契的人永远比契多一刀的余裕。
问:被控制打断契还在吗?
答:在——契印认刀数不认时间,晕住的三秒印照样挂着,醒来的第一刀还是加成的,这也是它比时限增益可靠的原因。
问:加成和暴击谁先乘?
答:先契后暴——契的一点五乘进基础伤,暴击倍率再乘上去,契中暴的两层乘法就是这套技能的上限时刻。
问:残血开契被怪补一刀怎么办?
答:怪补刀是博弈的一部分——扣六十之后血线的深浅自己掂量,血契从不承诺安全,只承诺值回票价。
问:血契的三刀能吃到蓄势重刀吗?
答:能——契印认刀不认形,蓄满的双倍刀照样掉一枚印,双倍乘一点五的最疼一笔就是这两套机制的握手。
六、调参指南与商业服怎么用
第四笔是血价的档位:六十点对三百上限是两成血换五成伤——血价太贱开契成了免费开关,太贵残血局里没人敢按,两成是"肉疼但值得"的档。第三笔是守门线:七十的守门比六十的扣价高十点——这十点是留给怪一刀的余量,守门线若与扣价持平,开契的下一秒就能被补刀送走。第二笔是充能的深度:三枚印对普攻周期一点四秒是四秒多的火力窗——印太多契变常驻,印太少攒不起气势。第一笔是契印的可视化:三枚印的熄灭要一格一格来,最后一格熄灭时契印整体碎开——玩家读格子就知道还剩几刀狠的,比头顶数字有仪式感。常见坑三个:扣血吃减伤,开契扣的血忽多忽少;契印跟着目标走,换怪印也跟着飞;守门线只查一次,契开着血掉穿底也不拦着挨打。
商业服里血契是"搏命流派"的投名状:敢割自己的人才配谈输出——商城里契印的样式做成品级,朱印、金印、血玉印,三枚印亮起来就是搏命者的军令状。运营落地还有两笔:一段是血线提示的分层——血量四成以下再点血契弹二次确认,防手滑就是防工单;一段是搏命榜——按血契期间的总伤排名,敢开的人有榜可上。变体做成血契连环:三刀打完若全部暴击,返还一半血价——会玩的人连血都能赚回来,上限留给最秀的手。这一篇的演示和整套模块照抄能跑,改的就是 CONST 那张表。
另外血价的视觉要给足——扣血的那一截从血条里溅出来飘到契印上,钱花在哪儿看得见,玩家才觉得值。
一句话记牢:契印亮的每一刀都是借来的狠,还账的日子就是三刀打完的那一拍。
契约的规矩也从一开始就讲清:只认刀数不认时限,急不得也拖不得。
写完留一句给做充能系的同学:血契卖的是"血就是弹药"——头顶那三枚红印是押上去的本钱,打出去的每一刀,都是连本带利的讨还。
全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →
【游戏功能】 老师傅打拳为什么总说"打点不打力"?同样的劲,落在点上是一倍,落在点上之外是零。罩门把这句拳谚做成了机制:怪身…
【游戏功能】 把一只活怪按进土里是什么体验?地葬的答案分两段:按下去的两秒它整个没入土中,拳脚全废、眼界全无;弹出来的那一下…
【游戏功能】 坦克的盾为什么总在最需要的时候碎?因为盾是自己的血换的——开盾掉血、盾碎再掉血,两笔账全记在自己头上。汲取换了…
【游戏功能】 挨打还要挨出学问来?蓄雷的答案是:挨的打先别急着疼,记在账上——蓄两秒,两秒里它打多少记多少,人一根汗毛不掉;…
【游戏功能】 毒抗装为什么永远卖不动?因为毒从来只有挨打的份——中了毒等它自己跳完,血掉了就是掉了,毒抗只能少掉,不能讨回来…
【游戏功能】 后排追过一单怪事:同一个坦位的玩家,挨刀的掉血忽多忽少,最多的一次只掉了四点——装备没换、状态没变,唯一的区别…