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

轮岗守纹:两只怪轮着出手,总有一只在歇

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

【游戏功能】

先抛一个坑:两只怪为什么要一齐扑上来?真实的打斗里两个打手不会同时抡拳——总得有人虚位、有人进手,一齐扑上是武行的大忌。可战场上的怪不懂这个,两只一齐出手、一齐走位、一齐压过来,玩家在夹缝里连招都按不出来。轮岗纹的答案是把武行的规矩借过来:排岗——同一拍只许一只出手,另一只在旁边歇着,三秒一轮换。这篇把整套模块拆开:配置表、排岗表、轮休判定、换岗演出、定时器、调试按钮,一段一段照抄能跑。

一、效果演示:两只怪轮着出手,总有一只在歇

演示场两只怪照常一齐扑上来。点「轮岗!」:一圈青色的纹排开——十秒排岗期。这一拍起,怪群被编了岗:左边那只出手,头顶亮"岗"字;右边那只当场站定,头顶浮"休"字——爪子抬到一半也得放下。三秒一到换岗:出手的去歇着,歇着的接岗出手。十秒里两班倒,玩家的挨打密度直接砍半。演示里试两笔账:排岗期的挨打节奏和没排岗的一齐扑——同样的两只怪,一齐来是左右开弓,排了岗是单手慢拳。轮岗纹教的是分而治之:打不过一齐上的,就让它俩排队上。

demo
 fx-shiftduty

二、底层原理:一张排岗表加一次轮休判定

模块的机关是一对搭档。排岗表:开纹那一拍把视野里的怪挨个编号入册——同一拍只允许一岗出手,在册的每只怪都领到自己的班次。轮休判定:轮到歇岗的那只被暂时按住——爪子抬不起来、脚步挪不动,整只怪像被点了睡穴,三秒后换岗钟响才放出来。和眩晕类控制的分野在"轮休是排班不是点穴":眩晕把怪定死不看同伴,轮休是按岗表的规矩轮流来——你歇的时候它在打,你打的时候它歇着,怪群的总出手被岗表切成了单行道。

岗表为什么三秒一换?换得太勤怪群变成快闪轮打,玩家还是两头挨;换得太慢排岗退化成单挑另一只罚站,三秒刚好是"接岗的有威胁、歇岗的看得见"的节奏。

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

lua
-- @file ShiftDuty.lua
-- 轮岗纹 —— 两只怪轮着出手,总有一只在歇

local ShiftDuty = {}

local CONST = {
    CREST_LIFE    = 10.0,
    CREST_CD      = 4.0,
    TURN_LIFE     = 3.0,

    COLOR_DUTY    = "#588878",
    COLOR_DEEP    = "#1e3a2e",
    COLOR_GHOST   = "#b0d8c0",

    ZORDER_DUTY   = 133,
    ZORDER_FX     = 135,
    AUTOINC_BASE  = 1102000,
}

local _crestT    = 0
local _cdLeft    = 0
local _turnT     = 0
local _dutyID    = 0
local _restID    = 0
local _crestFx   = nil
local _scheduler = nil
local _autoInc   = 0

local function GenID(prefix)
    _autoInc = _autoInc + 1
    return string.format("%s_%d", prefix or "SFD",
        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

function ShiftDuty.OnDuty(tid)
    return _crestT > 0 and tid == _dutyID
end

function ShiftDuty.OnRest(tid)
    return _crestT > 0 and tid == _restID
end

四、核心代码:完整模块(下·轮休判定与换岗钟)

lua
-- 轮休判定:歇岗的那一只整只按住
SL:RegisterLUAEvent(LUA_EVENT_ACTION_CHECK, "SFD_Rest", function(tid)
    if ShiftDuty.OnRest(tid) then
        return false
    end
    return true
end)

-- 换岗钟:三秒一响,出手的去歇,歇着的接岗
local function ShiftTurn()
    if not SL:GetValue("ACTOR_ALIVE", _restID) then
        ShowTip("歇岗的那只倒了——岗白排了")
        return
    end
    _dutyID, _restID = _restID, _dutyID
    SL:TipAbove(_dutyID, "岗")
    SL:TipAbove(_restID, "休")
    SL:PlayShiftFx(_dutyID)
end

function ShiftDuty.Cast()
    if _cdLeft > 0 or _crestT > 0 then return end
    local tid = SL:GetValue("MARK_TARGET_ID")
    if not tid then return end
    local other = SL:FindNearMonster(tid, 300)
    if not other then
        ShowTip("就一只怪——排什么岗")
        return
    end
    _cdLeft = CONST.CREST_CD
    _crestT = CONST.CREST_LIFE
    _turnT = CONST.TURN_LIFE
    _dutyID = tid
    _restID = other
    SL:TipAbove(tid, "岗")
    SL:TipAbove(other, "休")
    SafeRemove(_crestFx)
    _crestFx = GUI:Layout_Create(GUI:Attach_SceneF(),
        GenID("Duty"), 0, 0, 0, 0, false)
    GUI:setLocalZOrder(_crestFx, CONST.ZORDER_DUTY)
    SL:PlayDutyUpFx(tid)
    ShowTip("排岗了——一只出手一只歇,三秒一轮")
end

-- 定时器:纹成倒计时与换岗钟驱动
if not _scheduler then
    _scheduler = SL:Schedule(function(dt)
        _cdLeft = math.max(0, _cdLeft - dt)
        if _crestT > 0 then
            _crestT = _crestT - dt
            _turnT = _turnT - dt
            if _turnT <= 0 then
                _turnT = CONST.TURN_LIFE
                ShiftTurn()
            end
            local a = GetActorPos(_dutyID)
            local b = GetActorPos(_restID)
            if _crestFx and a and b then
                GUI:setPosition(_crestFx,
                    (a.x + b.x) / 2, (a.y + b.y) / 2 - 140)
            end
            if _crestT <= 0 then
                SafeRemove(_crestFx)
                ShowTip("岗撤了——两只一齐扑上来了")
            end
        end
    end, 0.02)
end

SL:ScheduleOnce(function()
    SL:BindDebugButton("轮岗", function()
        ShiftDuty.Cast()
    end)
    ShowTip("技能已加载: 轮岗纹 (调试按钮触发)")
end, 1.0)

function ShiftDuty.Unload()
    if _scheduler then SL:Unschedule(_scheduler) end
    SL:UnregisterLUAEvent(LUA_EVENT_ACTION_CHECK, "SFD_Rest")
    SafeRemove(_crestFx)
    _crestT = 0
end

return ShiftDuty

五、机制问答

问:歇岗的那只死了怎么办?
答:岗白排——换岗钟找不到接岗的,岗表当场作废,两只变一只的局排岗没有意义。

问:排岗期能引第三只怪进来吗?
答:进不了册——岗表只认开纹那一刻在册的两只,第三只是编外人员,照常出手,排岗前先清场。

问:换岗的瞬间两只都在出手怎么办?
答:打完这拍再换——换岗认的是下一次出手的许可,在途的那一爪不受岗表管辖,不会出现爪挥一半被收回。

问:歇岗的怪会走位吗?
答:不会——轮休是整只按住,脚步爪子一起停,它站的位置就是歇岗前的位置,三秒后从原地接岗。

问:排岗对头目有效吗?
答:无效——大体型的怪不吃岗表,说明栏写明"头目免排",能排的只有成对的小怪。

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

第四笔是换岗的钟点:三秒一换对怪的出手间隔是"接岗即有威胁"的节奏——换得太快成快闪轮打,太慢另一只罚站太久,三秒是岗表的心跳。第三笔是轮休的深度:整只按住是满轮休——只按爪子不按脚步的半轮休版本,歇岗的怪贴着你转悠照样闹心,要歇就歇全的。第二笔是入册的口径:开纹那一刻在场的两只入册——半路进来的编外怪是排岗的漏,也是玩家利用的口子,口径要写死在说明里。第一笔是岗牌的可见:出手头顶"岗"、歇着头顶"休"——两块牌就是岗表的告示,玩家看牌就知道下一拍谁出手,预判有了落点。常见坑三个:歇岗判定漏了移动导致歇岗的怪照样贴脸;换岗钟在怪死亡后空转;岗牌跟画在怪被击退后飘到了半空。

商业服里轮岗纹是"武行班"的规矩:别人怕围殴,他给围殴的怪排班——商城里岗牌的样式做成品级,木牌、铜牌、武行金牌,那一对挂在怪头顶的岗休字牌就是武行班的班表。运营落地还有两笔:一段是排班教学——教一句"两只一起上不可怕,可怕的是你不会排班",流派第一课是立规矩;一段是排岗榜——按排岗期少挨的刀数排名,规矩立得最正的人有碑。变体做成三班倒:三只怪轮着出手——从两班倒到三班倒,武行班的班表越排越严。这一篇的演示和整套模块照抄能跑,改的就是 CONST 那张表。

写完留一句给做群控系的同学:轮岗纹卖的是"让它们排队"——那对挂在头顶的岗休字牌和三秒一响的换岗钟,是把围殴改写成轮流单挑的第一张班表。

作者履历与出处

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

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

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

LATEST ARTICLES

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

进阶实战游戏功能

走一格为什么是半秒?拆开996引擎走路状态机

接手二开的兄弟几乎都撞过同一堵墙:玩家嫌走路"一格一格像机器人",老板拍板要"丝滑移动",改服务端速度?不对。改客户端动画帧…

2026-10-03 05:31 996 技术组
进阶实战游戏功能

特效总挂在脚后跟上?挂点表选对一行顶十行

【游戏功能】 先看一个熟场面:法师的火球特效挂在怪的脚后跟上,明明技能说明写着"焚烧其面",火星子却在地上打滚。群里有位策划…

2026-10-03 05:30 996 技术组
进阶实战游戏功能

刀刀都判命中,玩家为什么喊挥空?命中表现差的那一拍

【游戏功能】 上周有个开服的老板在群里发了一段录屏:他的战士明明刀刀都砍中了,观众却一片"这刀挥空了吧"。他原话是"判定日志…

2026-10-03 05:30 996 技术组
进阶实战游戏功能

怪的皮一会儿绿一会儿红?状态染色的色号表就三列

【游戏功能】 先说结论放在开头:怪的皮一会儿绿一会儿红,不是美术换了几套贴图,是染色系统在怪身上盖了一层"色镜"。开服群里有…

2026-10-03 05:30 996 技术组
进阶实战游戏功能

996引擎Buff系统解剖:中毒变绿、冰冻发白是怎么挂上去的

前两天群里有个架设的朋友问了个需求:中毒的人要变绿、每两秒掉一次血、毒还能叠五层,问是不是要在服务端把整套状态机重写。我说你…

2026-10-03 05:25 996 技术组
进阶实战游戏功能

编钟纹:五口钟排着敲,一口更比一口疼

【游戏功能】 先抛一个坑:五口钟一模一样大,为什么一口比一口疼?先后次序动不得吗?倒过来敲会怎样?这篇把编钟纹整套写法拆开:…

2026-10-03 05:01 996 技术组