CHUAN2 DEV ENGINE
996 正版授权研发中心 · 360 授权合作教学中心 · 抖音传奇直播合作授权 · 快手推广运营商授权
OFFICIAL LICENSED ACADEMY 查验官方授权证书 →
// 威海旷世互娱教学基地 · 技术文章
进阶实战游戏功能996引擎

偷影:偷走它的影子,没了影子的怪刀都虚

2026-10-01 06:03 作者:996 技术组 996引擎Lua教程传奇脚本进阶实战游戏功能996引擎

【游戏功能】

if _shadowT > 0 then spd = noShadow and 12 or 24 end——一行腿速减半的分支,藏着偷影全部的诗意:把它的影子偷到你脚下,没了影子的怪刀软一半、腿慢一半,你的刀加两成——影子牵着走,它发虚你发壮。这篇的核心代码照引擎技能脚本的全规格写:配置表、影子构件、三态影子状态机、定时器、调试按钮。

一、效果演示:一道影子,爬过半场

演示场点「偷影!」:怪脚下的深色影子被连根拽出——影子贴着地面爬过半场,一根细线牵着,一路掉着灰屑,最后铺在你的脚下。从这一刻起怪变了:脚下只剩一圈虚线描的空壳,出手慢了一倍、刀软一半——每口从十四掉到七,连走路都像在水里蹚;你脚下踩着它的影子,普攻加两成——十二变十四。六秒后影子自己爬回去,怪缓过神来,第一爪就是报复。第一爪就是报复——报复那一下是实价的,玩家散影前的最后一件事该是退半步。演示里看三处:影子爬行时拖着的灰屑、怪脚下那圈"无影"的虚线空壳、影子爬回时越走越快的步伐——三处都是这套机制的表情。三处都是这套机制的表情,少了哪一处,偷影就少三分味道。

demo
 fx-shadowsteal

二、底层原理:一台三态影子状态机加两份属性改写

模块的机关是一台三态状态机。自有态:影子长在怪脚下,一切照旧。爬行态:偷影的瞬间影子脱离怪身、向玩家爬行——爬行的影子是独立的地面构件,爬速固定,爬到玩家脚下切换。偷走态:影子铺在玩家脚下六秒,怪的攻速腿速各砍一半、玩家的攻击加两成;影子在谁脚下,两份改写就落在谁头上。六秒一到影子自动爬回,怪的属性复原。属性改写只在偷走态生效是全模块的边界:爬行途中影子已经是"你的",怪身上的削弱却要等影子落地才挂——影子爬的这半场路,是怪最后的体面。影子爬的这半场路,是怪最后的体面。偷影的落点也讲究:影子铺在玩家脚下而不是悬在半空——影子是地上的事,贴地爬行的每一寸都算数。

三、核心代码:完整模块(上·骨架)

lua
--------------------------------------------------------------------------------
-- @file        ShadowSteal.lua
-- @brief       偷影 —— 偷走它的影子,没了影子的怪刀都虚
--              客户端表现模块:配置表 / 影子构件 / 三态状态机 / 定时器
--------------------------------------------------------------------------------

local ShadowSteal = {}

--------------------------------------------------------------------------------
-- 配置与常量
--------------------------------------------------------------------------------
local CONST = {
    SHADOW_LIFE   = 6.0,        -- 偷影六秒
    SHADOW_CD     = 12.0,       -- 冷却十二秒
    TRAVEL_SPEED  = 3.0,        -- 影子爬行插值
    FOE_CUT       = 0.5,        -- 无影的它刀腿各半
    MY_AMP        = 1.2,        -- 你加两成

    -- 颜色
    COLOR_SHADOW  = "#7a8fa8",  -- 影青
    COLOR_DEEP    = "#3a4050",  -- 影灰
    COLOR_GHOST   = "#c8d0e0",  -- 影白

    ZORDER_GROUND = 118,
    ZORDER_SHADOW = 117,
    ZORDER_EFFECT = 135,

    AUTOINC_BASE  = 943000,
}

--------------------------------------------------------------------------------
-- 模块内部状态
--------------------------------------------------------------------------------
local _state     = "own"         -- own / travel / stolen
local _shadowX   = 0             -- 爬行态影子的横坐标
local _shadowT   = 0             -- 偷走态余时
local _cdLeft    = 0
local _scheduler = nil
local _autoInc   = 0

local m_cos = math.cos
local m_sin = math.sin

--------------------------------------------------------------------------------
-- 辅助函数
--------------------------------------------------------------------------------
local function GenID(prefix)
    _autoInc = _autoInc + 1
    return string.format("%s_%d", prefix or "SST", CONST.AUTOINC_BASE + _autoInc)
end

local function GetActorPos(actorID)
    if not actorID then return nil end
    local x = SL:GetValue("ACTOR_POSITION_X", actorID)
    local y = SL:GetValue("ACTOR_POSITION_Y", actorID)
    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 CreateShadowNode(x)
    local node = GUI:Layout_Create(GUI:Attach_SceneF(), GenID("Shd"), x, 6, 0, 0, false)
    GUI:setLocalZOrder(node, CONST.ZORDER_SHADOW)
    for i = 1, 18 do
        local a1 = (i - 1) / 18 * 6.28
        local a2 = i / 18 * 6.28
        GUI:DrawLine_Create(node, string.format("s_%d", i), 0, 0, 4,
            m_cos(a1) * 26, m_sin(a1) * 8, m_cos(a2) * 26, m_sin(a2) * 8,
            CONST.COLOR_DEEP, 210)
    end
    return node
end

骨架的三处立规。状态字段用字符串三态不用两个布尔——三态互斥,两个布尔能组合出四个非法态。影子的层级压到地面层之下——影子是地里的事,压在单位脚底下才不穿帮。影子构件十八段折线画扁椭圆——影子是扁的,纵轴压到四分之一,画成竖椭圆就成了一滩水。

四、核心代码:完整模块(下·定时器与三态状态机)

lua
--------------------------------------------------------------------------------
-- 偷影入口
--------------------------------------------------------------------------------
function ShadowSteal.Cast(targetX)
    if _cdLeft > 0 or _state ~= "own" then return end
    _cdLeft = CONST.SHADOW_CD
    _state = "travel"
    _shadowX = targetX
    ShowTip("影子拽出来了——看着它爬到你脚下")
end

--------------------------------------------------------------------------------
-- 属性改写:偷走态的两本账
--------------------------------------------------------------------------------
local function FoeFactor()
    if _state == "stolen" then return CONST.FOE_CUT end
    return 1.0
end

local function MyFactor()
    if _state == "stolen" then return CONST.MY_AMP end
    return 1.0
end

--------------------------------------------------------------------------------
-- 定时器:三态状态机
--------------------------------------------------------------------------------
if not _scheduler then
    _scheduler = SL:Schedule(function(dt)
        _cdLeft = math.max(0, _cdLeft - dt)
        local mp = GetActorPos(SL:GetValue("USER_ID"))
        local tp = GetActorPos(SL:GetValue("MARK_TARGET_ID"))
        if _state == "travel" then
            if not mp then return end
            _shadowX = _shadowX + (mp.x - _shadowX) * math.min(1, CONST.TRAVEL_SPEED * dt)
            SL:MoveNode(SL:GetShadowNode(), _shadowX, 6)
            if math.abs(_shadowX - mp.x) < 8 then
                _state = "stolen"
                _shadowT = CONST.SHADOW_LIFE
                SL:TipAbove(SL:GetValue("MARK_TARGET_ID"), "发虚!")
                ShowTip("影子到手——它刀软一半腿慢一半,你加两成")
            end
        elseif _state == "stolen" then
            _shadowT = _shadowT - dt
            SL:MoveNode(SL:GetShadowNode(), mp and mp.x or _shadowX, 6)
            if _shadowT <= 0 then
                _state = "own"
                ShowTip("影子爬回去了——它缓过劲了")
            end
        end
        if tp then
            SL:SetActorSpeedAmp(SL:GetValue("MARK_TARGET_ID"),
                _state == "stolen" and CONST.FOE_CUT or 1.0)
        end
        SL:SetNextAttackAmp(MyFactor())
    end, 0.02)
end

SL:RegisterLUAEvent(LUA_EVENT_SCENE_CLEAR, "SST_Clear", function()
    _state = "own"
    SL:SetNextAttackAmp(1.0)
end)

SL:ScheduleOnce(function()
    ShowTip("技能已加载: 偷影 (调试按钮触发)")
end, 1.0)

return ShadowSteal

下半场三态各管一段。爬行态的影子用插值系数三点零追玩家——影子爬得比人慢半拍,这半拍的爬行就是机制的演出高潮;追上即切偷走态、属性改写同帧挂上。偷走态每帧把怪的腿速系数压到零点五、把玩家的下一刀乘一点二——两份改写都走统一的系数出口,散影时系数复原回一,一帧都不多压。场景清空把状态机推回自有态——影子回去了,加成清了,下一场从"各自有影"起步。

五、调参指南与商业服怎么用

调参三笔账。无影的刀腿各半对六秒是"白给窗口"的尺寸——六秒里怪的威胁只剩四分之一,玩家的爆发技能全部压进这六秒;窗口拉到十秒,头目战变成站桩表演。爬行插值三点零是演出的黄金速——影子爬太快要不到"仪式感",太慢玩家等得发慌,半场爬两秒上下正好。你的加成两成对它的削弱五成是不对称设计——削它比你加成更狠,机制的账更偏向"偷影是削弱技",玩家的加成是顺手赚的。常见坑三个:爬行途中怪死亡,影子爬到一半悬在半路——爬行态也要处理目标死亡;偷走态怪的影子空壳没有视觉,玩家分不清偷没偷上;玩家死亡影子瞬移回家,虚影闪一下。

商业服里偷影是"影流"门派的镇派:影流职业的强度全在这道影上——偷影的成功率、持续、削幅做成影流修行的三重课业,门派贵的理由写在影子爬行的速度里。攻城战里它是士气机制的反面:头目没了影子,全队加两成的账写在每个人的刀上。变体做成影子反偷:怪也可能偷玩家的影子——被偷影的玩家屏幕边缘发灰,夺回影子的打法成了新的攻防题。变体做成影子反偷:怪也可能偷玩家的影子——被偷影的玩家屏幕边缘发灰,夺回影子的打法成了新的攻防题。影子的归属权还能做成收集线:偷过十种怪的影子点亮影鉴,收藏玩法从影子里长出来。这一篇的演示和整套模块照抄能跑,改的就是 CONST 那张表。

写完留一句给做影系的同学:偷影卖的是"名正言顺的虚弱"——它脚下那圈空壳虚线,是全游戏最体面的削弱提示。

作者履历与出处

本文由 996 技术组基于 996 引擎官方知识库与浮生梦老师课程体系整理。团队长期从事传奇类引擎 Lua 后端逻辑、客户端界面与商业版本交付,内容以官方知识库与真实项目为出处,按版本持续修订。

← 返回文章地图返回研学路径

幂尔框架 · 实战干货 · 接口调用

LATEST ARTICLES

全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →

进阶实战游戏功能

迷魂香:一炉香点着,圈里的怪掉头打转

【游戏功能】 怪的仇恨为什么永远追着你?因为它看得见你。迷魂香把"看得见"这三个字没收了:一炉香落在它脚下,烟圈六秒——圈里…

2026-10-01 06:32 996 技术组
进阶实战游戏功能

气势:连击涨势 挨打掉势 提气回血五十

【游戏功能】 连击值攒着有什么用?多数战斗的答案是攒个伤害加成——气势给了第二个答案:攒的是一支军队的士气。每一刀涨十二点、…

2026-10-01 06:32 996 技术组
进阶实战游戏功能

崩血:伤口一动就崩,跑得越快掉血越凶

【游戏功能】 一道割裂挂上去,一秒一跳——它站着跳四,追你的时候崩成八:伤口一动就崩,跑得越快掉得越凶。崩血把"放风筝"从走…

2026-10-01 06:32 996 技术组
进阶实战游戏功能

燕回式:突进穿它一遭,原路飞回起手点

【游戏功能】 突进出去了,回不回得来?多数突进的答案是"不回"——人留在怪堆里听天由命。燕回式给突进装了归途:穿身而过去时一…

2026-10-01 06:32 996 技术组
进阶实战游戏功能

破招式:它抡重刀你抢半拍,招克招

【游戏功能】 读条变红的那一秒,全世界都在等一个决定。破招式把这一秒做成整场战斗的心跳:怪交替出红劈和蓝刺,红劈读条时按下破…

2026-10-01 06:32 996 技术组
进阶实战游戏功能

连招谱:三招按谱出,谱尾一击翻倍

【游戏功能】 出招的顺序算不算伤害?大多数战斗里不算——三招乱按和按谱出,账面一个样。连招谱把顺序变成了伤害本身:「劈→撩→…

2026-10-01 06:32 996 技术组