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

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

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

【游戏功能】

怪的仇恨为什么永远追着你?因为它看得见你。迷魂香把"看得见"这三个字没收了:一炉香落在它脚下,烟圈六秒——圈里的怪当场迷失方向,转着磨磨乱走乱拍,你在圈外一刀一刀点它,它连你在哪都分不清。这篇的核心代码照引擎技能脚本的全规格写:配置表、香烟构件、迷向状态机、定时器、调试按钮。

一、效果演示:一炉香,一场没有方向的仗

演示场点「焚香!」:一尊小香炉落在怪脚下,一圈绿烟的边界慢慢转——怪踩进烟圈的瞬间头顶蹦出三个问号,行动全乱:半秒一换方向地乱走,抬爪乱拍空气,走两步撞回圈心。你站在烟圈外,普攻一刀一刀点它——它够不着你,因为你在它的世界里不存在。六秒香烬,烟散的那一帧它猛地回神,第一个动作就是朝你冲——散香前的最后两秒是玩家收尾的窗口。演示里可以看两处:它在烟里的转向没有一次是朝你的,烟散的第一眼它必找你——迷与醒之间隔的就是那圈烟沿。迷与醒之间隔的就是那圈烟沿。烟圈的飘法也有讲究——绿烟一缕一缕从炉口斜着往上飘,烟的慵懒就是香的性格。

demo
 fx-incense

二、底层原理:一份迷向标记加一套乱走状态机

模块的机关是一对搭档。迷向标记:怪在烟圈内时挂上 confused,挂上即与玩家的仇恨解绑——寻路目标清空、出手目标清空,怪的每个行动都改从乱数表里抽:半秒抽一次方向、半秒抽一次抬爪。烟圈判定每帧跑:进圈挂标、出圈摘标——摘标的那一帧仇恨重建,怪直奔玩家的旧账新账一起算。乱走状态机与仇恨解绑的意义在"彻底"两个字:迷向的怪还保留一半目标信息的版本,玩家站着不动它迟早又摸过来——迷向要迷得干净,转磨磨才转得理直气壮。

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

lua
--------------------------------------------------------------------------------
-- @file        Incense.lua
-- @brief       迷魂香 —— 一炉香点着,圈里的怪掉头打转
--              客户端表现模块:配置表 / 香炉构件 / 迷向状态机 / 定时器
--------------------------------------------------------------------------------

local Incense = {}

--------------------------------------------------------------------------------
-- 配置与常量
--------------------------------------------------------------------------------
local CONST = {
    SMOKE_LIFE    = 6.0,        -- 烟圈六秒
    SMOKE_CD      = 10.0,       -- 焚香冷却
    SMOKE_R       = 90,         -- 烟圈半径九十
    WANDER_GAP    = 0.5,        -- 半秒抽一次行动
    WANDER_SPEED  = 20,         -- 乱走的步速

    -- 颜色
    COLOR_SMOKE   = "#b8c89a",  -- 香绿
    COLOR_DEEP    = "#5a6a3a",  -- 深绿
    COLOR_GHOST   = "#e0ecd0",  -- 香白

    ZORDER_GROUND = 118,
    ZORDER_SMOKE  = 127,
    ZORDER_EFFECT = 135,

    AUTOINC_BASE  = 949000,
}

--------------------------------------------------------------------------------
-- 模块内部状态
--------------------------------------------------------------------------------
local _smokeT     = 0              -- 烟圈余时
local _smokeX     = 0              -- 炉心横坐标
local _cdLeft     = 0
local _wanderT    = 0              -- 乱走抽签计时
local _wanderDir  = 1              -- 乱走方向
local _confused   = false          -- 迷向标记
local _scheduler  = nil
local _autoInc    = 0

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

--------------------------------------------------------------------------------
-- 辅助函数
--------------------------------------------------------------------------------
local function GenID(prefix)
    _autoInc = _autoInc + 1
    return string.format("%s_%d", prefix or "INC", 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 CreateBurnerNode(x, y)
    local node = GUI:Layout_Create(GUI:Attach_SceneF(), GenID("Burner"), x, y, 0, 0, false)
    GUI:setLocalZOrder(node, CONST.ZORDER_SMOKE)
    GUI:DrawLine_Create(node, "pot", 0, 0, 16, -8, 0, 8, -12, CONST.COLOR_DEEP, 240)
    GUI:DrawLine_Create(node, "lid", 0, 0, 10, -5, -12, 5, -16, CONST.COLOR_GHOST, 240)
    return node
end

骨架的三处立规。烟圈的判定用横坐标对炉心——纵深方向的宽容和荡魂波的带状判定同理,圈是圆柱的投影不是纸片。_confused 是怪的属性标记不是烟圈的属性——烟圈只在"进圈挂标、出圈摘标"两件事上说话,怪的行为怎么乱是怪自己的状态机的事。香炉构件炉身加炉盖两件套——炉是香的根,炉不在烟就没有来处。

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

lua
--------------------------------------------------------------------------------
-- 焚香与迷向
--------------------------------------------------------------------------------
function Incense.Cast(x)
    if _cdLeft > 0 or _smokeT > 0 then return end
    _cdLeft = CONST.SMOKE_CD
    _smokeT = CONST.SMOKE_LIFE
    _smokeX = x
    CreateBurnerNode(x, 0)
    ShowTip("香点着了——烟圈六秒,它在里面转磨磨")
end

--------------------------------------------------------------------------------
-- 定时器:烟圈、迷向与乱走
--------------------------------------------------------------------------------
if not _scheduler then
    _scheduler = SL:Schedule(function(dt)
        _cdLeft = math.max(0, _cdLeft - dt)
        if _smokeT <= 0 then return end
        _smokeT = _smokeT - dt
        if _smokeT <= 0 then
            _confused = false
            ShowTip("香烬了——它回过神,第一眼就找你")
            return
        end
        local tid = SL:GetValue("MARK_TARGET_ID")
        local tp = tid and GetActorPos(tid)
        if not tp then return end
        local inSmoke = math.abs(tp.x - _smokeX) <= CONST.SMOKE_R
        if inSmoke and not _confused then
            _confused = true
            SL:ClearHate(tid)                 -- 仇恨解绑,方向清零
            SL:TipAbove(tid, "迷目")
        elseif not inSmoke and _confused then
            _confused = false
            ShowTip("它走出烟了——下一炉跟上")
        end
        if _confused then
            _wanderT = _wanderT - dt
            if _wanderT <= 0 then
                _wanderT = CONST.WANDER_GAP
                _wanderDir = m_rand() > 0.5 and 1 or -1
                SL:WanderStep(tid, _wanderDir * CONST.WANDER_SPEED * 0.5)
            end
        end
    end, 0.02)
end

SL:RegisterLUAEvent(LUA_EVENT_SCENE_CLEAR, "INC_Clear", function()
    _smokeT = 0
    _confused = false
end)

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

return Incense

下半场的迷向是一条三步链:进圈挂标、挂标解绑、解绑后乱走——三步的顺序不能动,先乱走后解绑的版本怪会一边迷向一边继续追人,圈的威严全无。出圈的摘标只做一件事:摘标不追击——追击交给怪自己的仇恨重建,香圈的角色到"解绑"为止。乱走的半步距离 WanderStep 每次半秒二十步——步子太大走出烟圈、太小原地打摆,二十步的磨磨转刚刚好。

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

调参三笔账。烟圈九十步对怪的攻距三十步——怪在圈里够不着圈外的你,圈的宽度就是安全感的宽度;圈缩到四十步,怪站在烟里也能拍到你,迷向就白迷了。烟圈六秒对散香后的仇恨重建是收尾的窗口——六秒里前四秒转磨磨、后两秒收尾,节奏刚好;八秒的烟圈会让收尾变成磨洋工。乱走的半秒抽签是迷向的"醉态"——抽签间隔加长到一秒,怪的乱走变成匀速平移,醉态尽失。常见坑三个:迷向只清了移动目标没清出手目标,怪在圈里乱走却朝玩家的方向放招;烟圈的粒子在香烬后还飘,无香之烟满屏乱窜;散烟的第一帧没有醒目提示,玩家不知道随时会被反扑。

商业服里迷魂香是"控场流派"的气质单品:香的品级从线香到盘香到檀香,烟圈的纹样一圈比一圈讲究,控场职业的排面第一次不靠伤害撑。控场职业的排面第一次不靠伤害撑。迷向的怪连仇恨的重建都要慢半拍——散烟后它愣一下才想起你,这一愣是控场玩家的奖赏。这一愣是控场玩家的奖赏。香炉的余烬也要留两秒——炉还立着烬还亮着,玩家知道下一炉该落在哪。副本里它是救场技的顶配:全队被追时一炉香落地,追兵原地转磨磨,全队从烟边绕行的画面就是最好的副本宣传片。变体做成香阵叠加:两炉香圈的交叠区产生"深睡",迷向升级成定身——香与香的几何又是一层玩法。香与香的几何又是一层玩法。烟圈的内圈还可以做深浅两段——外圈迷向、内圈降攻,圈的层次多一层,站位的学问厚一页。这一篇的演示和整套模块照抄能跑,改的就是 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 技术组