【游戏功能】
线上事故引入:早上比武场又添笑柄——玩家放出影子替身,怪一爪拍下来,影子和玩家同时挨了:仇恨没挂到影子身上,替身成了摆设,两本挨打的账各走各的。挡刀类玩法的全部机关就在"怪的爪子落在谁身上"这一句。这篇把分身挡纹整套写法重写成篇:放影挡道、爪爪改道、三爪即散、散后再放,一段一段照抄能跑。
一、效果演示
演示场侠客身边可以放影子。点「放影!」:一具半透明的影子挡在半道上,三十点蓝条挂在头顶——怪的爪子从此全落在影子上,一爪十二点,三爪打散。影子在的这几拍你在后面安心落刀;影子散了,下一爪就轮到你自己。十秒聚一次影,什么时候放、放在哪波爪前,挡刀的算计全在这几拍里。
flowchart TD
A[点放影] --> B{影子还站着吗}
B -- 站着 --> C[劝你省着用]
B -- 没站 --> D[影子出窍挡道]
D --> E[怪的爪子来了]
E --> F{影子还在吗}
F -- 在 --> G[爪落影子 扣蓝条]
F -- 散了 --> H[爪落你身上]
G --> I{三爪用完了吗}
I -- 没有 --> E
I -- 用完 --> H
H --> J[十秒后再放]
fx-crest-decoy
二、底层原理
分身系统的机关是"爪子改道"——影子立起来之后,怪的攻击落点从人改到影子:挡刀的全部机关就在改道这一步。那场同挨事故的病根是仇恨没搬家:影子立在道上,怪的账还记在玩家头上,两本挨打的账各走各的。正解是受击的口子先查影子——影子在场,爪子进影子的账;影子散了,爪子才轮到玩家。改道要改在源头,散了才知道疼。
三爪即散的额度给了影子一件"消耗品"的身份:挡刀不是无限的护身符,是三拍的喘息窗口——窗口里你是自由的刀,窗口外你重新裸奔。放影的时机因此有了算计:放在怪起爪之前是白挡,放在连爪将至之前是救命。十秒一聚的冷却把影子的稀缺做足。幂尔框架这边改道收在受击口的第一行,影子的血条独立一本,散与在的判定挂同一处,谁也分不了家。
这套玩法的代码量不到八十行,难的不是放影子而是改道改在源头——仇恨不搬家,影子立得再直也是摆设。
再看影子为什么限定三爪不做成按时间消散——时间影子玩家掐着秒用,影子散在怪爪抬到一半的时刻最冤;爪数影子数得清,第三爪散的时候怪的第二爪已经落空,玩家收刀的节奏跟得上影子谢幕的节奏。额度用次数不用秒数,和点穴的窗口同一个道理:挡在攻击链上的消耗品,跟着攻击的拍子走,不跟着钟走。
三、核心代码:完整模块(上·骨架)
-- @file CrestDecoy.lua
-- 分身挡纹 —— 影子替你挨三爪
local CrestDecoy = {}
local CONST = {
DECOY_HP = 30,
CLAW_DMG = 12,
SUMMON_CD = 10,
AUTOINC_BASE = 1203100,
}
local _on = false
local _hp = 0
local _cd = 0
local _autoInc = 0
local function ShowTip(msg)
if msg and msg ~= "" then SL:ShowSystemTips(msg) end
end
local function GenID()
_autoInc = _autoInc + 1
return CONST.AUTOINC_BASE + _autoInc
end
function CrestDecoy.Standing() return _on end
-- 放影
function CrestDecoy.Summon()
if _on then
ShowTip("影子还站着——别浪费")
return
end
if _cd > 0 then
ShowTip("影还聚不起来——再等" .. math.ceil(_cd) .. "秒")
return
end
_on = true
_hp = CONST.DECOY_HP
_cd = CONST.SUMMON_CD
ShowTip("影子出窍——三爪之内它替你扛")
end
四、核心代码:完整模块(下·推进与卸载)
-- 受击口第一行: 影子在场爪子改道
function CrestDecoy.Intercept()
if not _on then return false end
_hp = _hp - CONST.CLAW_DMG
if _hp <= 0 then
_on = false
ShowTip("影子打散了——下一爪轮到你")
else
ShowTip("影子替你挨了一爪——还剩" .. _hp)
end
return true
end
if not _ticker then
_ticker = SL:Schedule(function(dt)
if _cd > 0 then _cd = _cd - dt end
end, 0.05)
end
SL:ScheduleOnce(function()
SL:BindDebugButton("放影!", function()
CrestDecoy.Summon()
end)
ShowTip("技能已加载: 分身挡纹")
end, 1.0)
function CrestDecoy.Unload()
if _ticker then SL:Unschedule(_ticker) end
_on = false
end
return CrestDecoy
五、机制问答
问:影子和玩家同挨一爪的病根在哪?
答:仇恨没搬家——正解是受击口第一行先查影子,改道改在源头。
问:影子为什么限三爪不定时间?
答:挡在攻击链上的消耗品跟着爪子的拍子走——第三爪散的时候,玩家的收刀节奏跟得上。
问:放影的时机怎么算才不白放?
答:放在连爪将至之前是救命——怪起爪前放是白挡,算计全在拍子里。
问:影子散了的下一爪为什么疼得格外真?
答:窗口外的裸奔才是常态——三拍的自由衬出挡刀的价值。
问:十秒一聚的冷却做足了什么?
答:影子的稀缺——挡刀不是护身符,是省着用的喘息窗口。
六、调参与实战怎么用
参数层面三个量——影子血量、怪的爪力、聚影冷却。三十点扛三爪是"看得到倒计时"的线:两爪太短五爪忘了数。实战里这套爪子改道的骨架能搬去替身草人、嘲讽傀儡、护驾分身,全是放影、改道、额度即散一条线。常见坑两个:仇恨不搬家影子成摆设;额度用秒数,散在爪半途最冤。
补充一个设计层面的思考——把玩家的行为还给玩家的机制最耐用:镜像还你的刀路、剥甲记你的刀数、影子扛你的失误,这一类机制的数值不用精调就自带公平——你做得怎样,它还得多狠,账面全在自己手里。设计者只需要把"读什么、还什么"的口子开正,剩下的交给玩家自己较劲。
补充一个维护层面的思考——影响下一局的状态要有封底和封顶:世代减益薄到底线就止、悬赏层层叠到上限就封,无限生长的跨局状态是数值雪崩的种子。封顶封底的两条线画在设计稿上,账本翻多少页都翻不出格子。
补充一个工程层面的思考——延迟兑现的账要带对象戳:谁的账、记在哪一局、跟着哪只怪,戳对了换局换怪都对得上,戳错了就是上轮那种对象两头各认各的事故。延迟越长的账,对象戳越要打在显眼处——半年后翻这段代码的人,靠的就是这几个戳。
写完留一句给做替身系的同学:玩家放的是影子也是三拍的喘息——改道改在源头,额度跟着爪走,挡刀才挡得明明白白。
全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →
接手二开的兄弟几乎都撞过同一堵墙:玩家嫌走路"一格一格像机器人",老板拍板要"丝滑移动",改服务端速度?不对。改客户端动画帧…
【游戏功能】 先看一个熟场面:法师的火球特效挂在怪的脚后跟上,明明技能说明写着"焚烧其面",火星子却在地上打滚。群里有位策划…
【游戏功能】 上周有个开服的老板在群里发了一段录屏:他的战士明明刀刀都砍中了,观众却一片"这刀挥空了吧"。他原话是"判定日志…
【游戏功能】 先说结论放在开头:怪的皮一会儿绿一会儿红,不是美术换了几套贴图,是染色系统在怪身上盖了一层"色镜"。开服群里有…
前两天群里有个架设的朋友问了个需求:中毒的人要变绿、每两秒掉一次血、毒还能叠五层,问是不是要在服务端把整套状态机重写。我说你…
【游戏功能】 先抛一个坑:五口钟一模一样大,为什么一口比一口疼?先后次序动不得吗?倒过来敲会怎样?这篇把编钟纹整套写法拆开:…