【游戏功能】
一道咒飞过来,硬吃是四秒里一秒十的钝疼——有没有第三条路?纸人替灾给的就是第三条路:贴一个纸人在身后,八秒里头一道飞来的咒半路拐弯,转嫁到纸人身上,纸人烧掉、咒就断,你毫发无伤。这篇的核心代码照引擎技能脚本的全规格写:配置表、纸人构件、转嫁钩子、定时器、调试按钮。
一、效果演示:一个纸人,一道断掉的咒
演示场里大怪每五秒下一道咒:中咒者一秒十疼四秒,紫雾缠身。点「贴纸人!」:一个纸白的小纸人浮到玩家肩后,头顶挂出"纸人 八秒"——八秒里大怪的第一道咒飞到半途突然拐弯,一头扎进纸人:纸人卷成火团烧成灰,咒的紫光在灰烬里断成几截落地,你身上干干净净。紫光在灰烬里断成几截落地,你身上干干净净——转嫁最讲究的就是"干净"二字,玩家的血条和状态栏都读不到一点咒的痕迹。纸人化灰后咒恢复实价——下一道咒再中就得实打实疼四秒,除非再贴一张。演示里先裸吃一道咒看看钝疼的滋味,再贴纸人看转嫁的利落——第三条路的答案写在两段血条的差值里。
fx-paperdoll
二、底层原理:一个替身位加一次转嫁结算
模块的机关是一对搭档。替身位:贴纸人的八秒里玩家身后多一个"替灾位"——它不吃伤害只吃异常,而且只吃一道,吃满即化灰。转嫁钩子:怪的咒在命中判定前先查替灾位——纸人在场,咒的目标改写到纸人、纸人执行一次"燃烧出表"、咒的剩余效果整段截断。转嫁和减免的分野是这套机制的性格:减免是伤害打折照常落账,转嫁是账本易主——咒的扣数跳在纸人头上,玩家的血条纹丝不动。纸人的一次性写在化灰里:替完即走,不存在一个纸人替八道咒的常驻护符。
三、核心代码:完整模块(上·骨架)
--------------------------------------------------------------------------------
-- @file PaperDoll.lua
-- @brief 纸人替灾 —— 贴一个纸人,下一道咒它替你挨
-- 客户端表现模块:配置表 / 纸人构件 / 转嫁钩子 / 定时器
--------------------------------------------------------------------------------
local PaperDoll = {}
--------------------------------------------------------------------------------
-- 配置与常量
--------------------------------------------------------------------------------
local CONST = {
DOLL_LIFE = 8.0, -- 纸人贴八秒
DOLL_CD = 6.0, -- 贴纸冷却
CURSE_GAP = 5.0, -- 咒五秒一道
CURSE_LIFE = 4.0, -- 中咒疼四秒
CURSE_DPS = 10, -- 一秒十疼
-- 颜色
COLOR_PAPER = "#f0e8d8", -- 纸白
COLOR_DEEP = "#7a5a2b", -- 深褐
COLOR_CURSE = "#a371f7", -- 灾紫
ZORDER_GROUND = 118,
ZORDER_DOLL = 132,
ZORDER_EFFECT = 135,
AUTOINC_BASE = 941000,
}
--------------------------------------------------------------------------------
-- 模块内部状态
--------------------------------------------------------------------------------
local _dollT = 0 -- 纸人余时
local _cdLeft = 0
local _curseT = 0 -- 中咒余时
local _curseTick = 0 -- 咒的跳秒
local _curseGap = CONST.CURSE_GAP
local _scheduler = nil
local _autoInc = 0
local m_rand = math.random
--------------------------------------------------------------------------------
-- 辅助函数
--------------------------------------------------------------------------------
local function GenID(prefix)
_autoInc = _autoInc + 1
return string.format("%s_%d", prefix or "PPD", CONST.AUTOINC_BASE + _autoInc)
end
local function GetMyPos()
local x = SL:GetValue("ACTOR_POSITION_X", SL:GetValue("USER_ID"))
local y = SL:GetValue("ACTOR_POSITION_Y", SL:GetValue("USER_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 CreateDollNode()
local mp = GetMyPos()
if not mp then return end
local node = GUI:Layout_Create(GUI:Attach_SceneF(), GenID("Doll"),
mp.x + 16, mp.y - 62, 0, 0, false)
GUI:setLocalZOrder(node, CONST.ZORDER_DOLL)
GUI:DrawLine_Create(node, "head", 0, 0, 5, 0, -8, 0, -8, CONST.COLOR_PAPER, 240)
GUI:DrawLine_Create(node, "body", 0, 0, 8, 0, -3, 0, 11, CONST.COLOR_PAPER, 240)
GUI:DrawLine_Create(node, "arm_l", 0, 0, 2, -4, 0, -8, 8, CONST.COLOR_PAPER, 240)
GUI:DrawLine_Create(node, "arm_r", 0, 0, 2, 4, 0, 8, 8, CONST.COLOR_PAPER, 240)
return node
end
骨架的两处立规。替灾位是单例——纸人只有一张,第二张的请求在入口拦下,双纸人轮流替灾的玩法从根上不允许。纸人构件用六笔线画一个火柴纸人——纸人的质感来自"简",画得太精细反而像召唤兽,简笔的纸人一眼就是替死的。简笔的纸人一眼就是替死的。纸人的位置挂在玩家肩后偏上——替灾的一瞬紫咒拐弯扎向肩后的画面,是全模块最值钱的一帧。
四、核心代码:完整模块(下·定时器与转嫁钩子)
--------------------------------------------------------------------------------
-- 贴纸人
--------------------------------------------------------------------------------
function PaperDoll.Cast()
if _cdLeft > 0 or _dollT > 0 then return end
_cdLeft = CONST.DOLL_CD
_dollT = CONST.DOLL_LIFE
CreateDollNode()
ShowTip("纸人贴上了——八秒里头一道咒它替你挨")
end
--------------------------------------------------------------------------------
-- 转嫁钩子:咒的命中判定前查替灾位
--------------------------------------------------------------------------------
local function OnCurseIncoming()
if _dollT > 0 then
_dollT = 0
SL:PlayDollBurn()
SL:TipAboveMe("纸人替灾!")
SL:ScreenShake(2.5, 0.18)
return true
end
return false
end
--------------------------------------------------------------------------------
-- 中咒结算
--------------------------------------------------------------------------------
local function Curse_Apply()
_curseT = CONST.CURSE_LIFE
_curseTick = 0
SL:TipAboveMe("中咒!")
end
--------------------------------------------------------------------------------
-- 定时器:纸人寿、咒的节拍与跳秒
--------------------------------------------------------------------------------
if not _scheduler then
_scheduler = SL:Schedule(function(dt)
_cdLeft = math.max(0, _cdLeft - dt)
if _dollT > 0 then
_dollT = _dollT - dt
if _dollT <= 0 then
ShowTip("纸人自己化灰了——这一场它没白贴")
end
end
if _curseT > 0 then
_curseT = _curseT - dt
_curseTick = _curseTick + dt
if _curseTick >= 1.0 then
_curseTick = _curseTick - 1.0
SL:PlayerHurt(CONST.CURSE_DPS)
if _curseT <= 0 then
ShowTip("咒劲散了")
end
end
return
end
_curseGap = _curseGap - dt
if _curseGap <= 0 then
_curseGap = CONST.CURSE_GAP
if not OnCurseIncoming() then
Curse_Apply()
end
end
end, 0.02)
end
SL:RegisterLUAEvent(LUA_EVENT_SCENE_CLEAR, "PPD_Clear", function()
_dollT, _curseT, _curseGap = 0, 0, CONST.CURSE_GAP
end)
SL:ScheduleOnce(function()
ShowTip("技能已加载: 纸人替灾 (调试按钮触发)")
end, 1.0)
return PaperDoll
下半场的分流在定时器的咒节拍里:咒到点的第一件事是查替灾位——纸人在,咒的流程整段截断、纸人燃烧出表;纸人不在,才走到 Curse_Apply 的中咒结算。中咒的跳秒独立计时、一秒一跳十点,跳完四秒咒劲自散——咒和中咒后的跳秒写进同一个分支的两段,中间用 return 隔开,中咒期怪再下咒也不叠加,一本咒账一条命。场景清空把纸人、咒、节拍三样全复原,下一场从干净的账本开始。
五、调参指南与商业服怎么用
调参三笔账。纸人八秒对咒周期五秒是"必接一道咒"的配置——纸人寿短于咒周期,贴了也白贴;长于两个周期又变成咒咒都替,一次性的性格就散了。咒的一秒十疼四秒是四十点的钝疼——疼到玩家愿意花一个技能位带纸人,又不至于两道咒就致命。贴纸冷却六秒对纸人八秒有两秒重叠——重叠期纸人常驻,冷却改十秒就是纯手艺活。贴纸冷却六秒对纸人八秒有两秒重叠——重叠期纸人常驻,冷却改十秒就是纯手艺活。替灾成功后的那一秒硬直也是节奏的一部分——纸人烧完玩家愣半拍,再拔腿走位,戏剧性全在这半拍里。常见坑三个:纸人替了咒但纸人的化灰特效慢半拍,玩家以为咒还会追过来;中咒期贴纸人,纸人白贴一道已经到账的咒;替灾位和免伤类效果互相冲突的结算顺序没写清。
商业服里纸人替灾是"咒术对抗"的入场券:咒术师职业的强度全靠诅咒压场,纸人一出场,咒术的每道咒都要先过纸人这一关,职业制衡的链子扣上了。商城里纸人外观是变现最快的品类——纸人从素纸到金箔,替灾的那一瞬烧的是玩家的排面。纸人从素纸到金箔,替灾的那一瞬烧的是玩家的排面。转嫁的咒色也可以随纸人品级换——素纸替白咒、朱纸替紫咒,咒的品阶和纸的品阶在半空对上号,对抗的仪式感全在这一眼。变体做成纸人多灾:金箔纸人替两道咒,替一道烧一层——耐咒度和品阶明码标价。这一篇的演示和整套模块照抄能跑,改的就是 CONST 那张表。
写完留一句给做替身系的同学:替灾卖的是"断"字——咒拐弯扎进纸人的那一瞬,玩家的血条学会了事不关己。
全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →
【游戏功能】 怪的仇恨为什么永远追着你?因为它看得见你。迷魂香把"看得见"这三个字没收了:一炉香落在它脚下,烟圈六秒——圈里…
【游戏功能】 连击值攒着有什么用?多数战斗的答案是攒个伤害加成——气势给了第二个答案:攒的是一支军队的士气。每一刀涨十二点、…
【游戏功能】 一道割裂挂上去,一秒一跳——它站着跳四,追你的时候崩成八:伤口一动就崩,跑得越快掉得越凶。崩血把"放风筝"从走…
【游戏功能】 突进出去了,回不回得来?多数突进的答案是"不回"——人留在怪堆里听天由命。燕回式给突进装了归途:穿身而过去时一…
【游戏功能】 读条变红的那一秒,全世界都在等一个决定。破招式把这一秒做成整场战斗的心跳:怪交替出红劈和蓝刺,红劈读条时按下破…
【游戏功能】 出招的顺序算不算伤害?大多数战斗里不算——三招乱按和按谱出,账面一个样。连招谱把顺序变成了伤害本身:「劈→撩→…