【游戏功能】
影刺的全机制就一句话:化影绕到它身后,从背刺出的那一刀双倍二十四——正面十二、背后二十四,它一转身就变白板。这篇的核心代码照引擎技能脚本的全规格写:配置表、绕后步构件、朝向判定、定时器、调试按钮。
一、效果演示:一步绕后,双倍的开场
演示场点「影刺!」:玩家化作紫影绕到怪身后五十四步处落定——怪的朝向还没转过来,刀刀双倍二十四的金字连蹦。怪转身的第一帧双倍熄灭、变回白板十二。演示里盯两处:绕后步的紫色残影和怪脚下亮起的判定环——环亮双倍在、环灭双倍熄。
fx-shadowstab
二、底层原理:一个朝向判定加一次侧向位移
模块的机关是一对搭档。朝向判定:怪的朝向字段和玩家的相对位置做叉乘式的比对——怪面朝右、玩家在怪的左侧,即"在背后";判定每帧跑,转身的第一帧双倍就失效。侧向位移:绕后步不是传送到背后,是从当前位置划一条弧线插到怪的另一侧——弧线插值让绕后有"绕"的动作,瞬移的版本是换位不是绕后。双倍的写在攻击结算出口:正面刀十二、背后刀二十四,同一个出口按判定结果分两档。
绕后步的落点为什么要选五十四步而不是贴身?落点太近,怪的转身动画还没播完判定环就亮了——玩家看见的是"绕过去了但没吃到双倍",其实是判定带的边缘余量在作怪;落点太远,下一刀的射程够不着,绕后绕出了个空刀。五十四步是射程之内、判定带中心、转身残影三者的交集,这个数字定住了,绕后步的手感就立住了。再者,绕后的残影不是装饰——残影的密度就是位移速度的视觉翻译,残影越密玩家越觉得"这一步快得值",残影稀了双倍的金字都显得没底气。
三、核心代码:完整模块(上·骨架)
-- @file ShadowStab.lua
-- 影刺 —— 化影绕后,从背刺出的一刀双倍
local ShadowStab = {}
local CONST = {
BEHIND_BAND = 70,
CRIT_AMP = 2.0,
BASE_DMG = 12,
STEP_LIFE = 0.3,
STEP_CD = 4.0,
STEP_OFFSET = 54,
COLOR_STAB = "#8a7ab8",
COLOR_DEEP = "#2a1a4a",
COLOR_GHOST = "#e0d8f0",
ZORDER_STEP = 133,
ZORDER_FX = 135,
AUTOINC_BASE = 980000,
}
local _stepT = 0
local _stepFrom = 0
local _stepTo = 0
local _cdLeft = 0
local _scheduler = nil
local _autoInc = 0
local function GenID(prefix)
_autoInc = _autoInc + 1
return string.format("%s_%d", prefix or "SST",
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 CreateBehindRing(x)
local node = GUI:Layout_Create(GUI:Attach_SceneF(),
GenID("Ring"), x, 6, 0, 0, false)
GUI:setLocalZOrder(node, CONST.ZORDER_STEP)
for i = 1, 22 do
local a1 = (i - 1) / 22 * 6.28
local a2 = i / 22 * 6.28
GUI:DrawLine_Create(node, string.format("r_%d", i), 0, 0, 2.5,
m_cos(a1) * 34, m_sin(a1) * 12,
m_cos(a2) * 34, m_sin(a2) * 12,
CONST.COLOR_STAB, 210)
end
return node
end
function ShadowStab.Step()
if _cdLeft > 0 or _stepT > 0 then return end
local tp = GetActorPos(SL:GetValue("MARK_TARGET_ID"))
local mp = GetActorPos(SL:GetValue("USER_ID"))
if not tp or not mp then return end
_cdLeft = CONST.STEP_CD
_stepT = CONST.STEP_LIFE
_stepFrom = mp.x
_stepTo = tp.x + (mp.x > tp.x and CONST.STEP_OFFSET
or -CONST.STEP_OFFSET)
end
四、核心代码:完整模块(下·定时器与背刺结算)
-- 朝向判定
local function IsBehind(myX, foeX, foeDir)
if foeDir == 2 and myX < foeX - 10 then return true end
if foeDir == 6 and myX > foeX + 10 then return true end
return false
end
-- 定时器
if not _scheduler then
_scheduler = SL:Schedule(function(dt)
_cdLeft = math.max(0, _cdLeft - dt)
if _stepT > 0 then
_stepT = _stepT - dt
local k = 1 - math.max(0, _stepT) / CONST.STEP_LIFE
local mp = GetActorPos(SL:GetValue("USER_ID"))
if mp then
SL:FlyActorTo(_stepFrom + (_stepTo - _stepFrom) * k)
SL:DropGhost()
end
if _stepT <= 0 then _stepT = 0 end
return
end
_atkT = (_atkT or 1.0) - dt
if _atkT <= 0 then
_atkT = behind and 0.9 or 1.3
local myID = SL:GetValue("USER_ID")
local mp = GetActorPos(myID)
local tid = SL:GetValue("MARK_TARGET_ID")
local tp = tid and GetActorPos(tid)
if mp and tp and IsBehind(mp.x, tp.x,
SL:GetValue("ACTOR_DIR", tid)) then
local vd = CONST.BASE_DMG * CONST.CRIT_AMP
SL:ActorHurt(tid, vd)
SL:TipAbove(tid, "-" .. vd)
SL:ScreenShake(3, 0.16)
else
SL:ActorHurt(tid, CONST.BASE_DMG)
end
end
end, 0.02)
end
return ShadowStab
五、机制问答:三个高频追问
问:绕后步的途中被撞了怎么办?
答:位移全程吃碰撞——弧线插值每帧都做过场校验,撞上硬直就停在撞点,判定环照常亮,只是落点偏了,双倍看的是最终站位不是起跑点。
问:双倍和暴击能叠加吗?
答:位置收益和暴击走两条结算线——先算位置的双倍,再掷暴击的倍率,两倍的两倍就是四倍,背刺暴击是这套技能的天花板时刻,也是它卖点的上限。
问:怪背靠墙站着还能绕吗?
答:墙会挡住弧线的插值路径——绕后步撞墙就落在墙前,双倍照样判定,只是刀从墙的方向劈过去,画面上有点滑稽但账是对的。
问:绕后能连续用吗?
答:四秒冷却就是答案——连续绕后是连招不是无脑,第一绕拿双倍、第二绕调位置,把位移当输出用的刺客才是好刺客。
六、调参指南与商业服怎么用
调参三笔账。双倍对正面十二是位置税的定价——背刺的双倍要压在正面输出的一倍以上、两倍半以下,一倍半玩家懒得绕,两倍半正面刀成了白给。绕后步四秒对怪转身零点五秒是抢得到的窗口——转身快的怪需要更快的绕后步,转身慢的怪背刺白给,怪和技的匹配就是难度。判定带七十步对绕后落点五十四步是落点必在带内的保证——落点在判定带外的版本,绕过去了刀却是白板。常见坑三个:朝向判定的余量没留,贴身绕后判定抖成闪灯;绕后步的弧线穿过怪的模型,穿模的绕后比正面拼刀还脏;背后双倍的数字颜色和暴击一样红,玩家分不清是位置收益还是运气暴击。
第四笔是残影的衰减:残影存续零点三四秒、每帧透明度递减——残影拖得太长,绕后的轨迹糊成一片,太短又看不见"绕"的弧线,弧线可视化是位置收益可读性的全部。
商业服里影刺是"刺客职业"的身份证明:位置收益直接写进职业技能,刺客的输出一半靠手一半靠脑——站位的脑子就是刺客的卖相。商城里绕后步的残影皮肤卖得最好——紫影、青影、黑影,绕后的一瞬就是职业的海报。变体做成背刺教条:连续背刺三次触发割喉终结——位置的连击把绕后从一次位移升成一套流程。这一篇的演示和整套模块照抄能跑,改的就是 CONST 那张表。
运营落地还有两笔:一段是新手指引——影刺的绕后要在教学关里手把手教一次,位置收益的概念对新手不直观,第一次双倍的金字就是最好的教材;一段是回放系统——背刺的双倍数字要在回放里标出"背后"的角标,不然观众看不懂刺客为什么一刀打掉半管血。
写完留一句给做位置系的同学:背刺卖的是身后的价值——它那一圈背后判定环,就是你的加成区、它的失明区。
全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →
【游戏功能】 排查一个报错走到深夜:玩家申诉"人物瞬移",录像里人也确实是凭空跳了半张地图——坐标链上多出来一次没有来由的写…
【游戏功能】 后山出过一单笑话:一个远程怪卡在断桥那头射了全队十分钟,走不过去、勾不着、弹道够不到——最后是位玩钩子的老哥一…
【游戏功能】 M.at = M.at 2 —— 就这一行,让一只盯了三天的速攻怪从"碰不得"变成"随便打"。怪的可怕从来不在…
【游戏功能】 为什么连着打同一个怪,一刀会比一刀疼?叠劲的答案是:劲是攒出来的——起手八点,每接一刀加四点,叠到六层刀刀二十…
【游戏功能】 群里报过一个怪现象:同一位玩家打同一个怪,有时一刀十三有时一刀十,面板攻击力没变过——排查了半天才发现,十三的…
【游戏功能】 线上出过一单事故:同战力两个人对砍,先手的那位反而输了——事后翻账才发现,赢家的每一刀都比面板数值高出一截,高…