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

分裂箭:一支裂三支,扇面三路齐发

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

【游戏功能】

单体射击的瓶颈是"只有一路"。分裂箭把一路变三路:主箭半途裂成三支扇面,左中右各十二——打在一只身上三十六集中输出,打在三只身上各十二分兵扫场。这篇的核心代码照引擎技能脚本的全规格写:配置表、主箭构件、分裂分叉、定时器、调试按钮。

一、效果演示:一支出去,三支回来

演示场点「分裂箭!」:主箭搭弦射出——半场的中间点箭身一亮"分裂!",一支变三支:左箭偏上、中箭直走、右箭偏下,扇面铺开。三支各十二齐扎在大怪身上——三十六的集中账。演示里看三支箭的扇面张角:中间那支笔直、两翼各偏十五度——扇面的宽度就是覆盖的范围,三路齐发对单体的爆发和对群体的覆盖是同一个技能的两副面孔。扇面的宽度就是覆盖的范围,分裂的中点取两座的中点——裂点离怪越近扇面越窄、三支越容易全中,裂点离怪越远扇面越散。三路齐发对单体的爆发和对群体的覆盖是同一个技能的两副面孔——中箭直走的二十五如果全中是集中输出,三支散开就是覆盖输出,打一只还是打三只看站位。扇面的三支箭各自独立命中——中箭笔直打脸、两翼各扎侧腰,三支全中的账面是集中三十六,只中一支是分散十二。

demo
 fx-splitarrow

二、底层原理:一支主箭加一次分叉

模块的机关是两段。主箭段:单支箭从玩家出手直线飞——飞到两座中点触发分叉。分叉段:主箭出表、三支子箭入表——子箭各带横速相同纵速不同的速度向量,中箭笔直、两翼各偏一个纵速。分裂点的判定写 "主箭横坐标过中点即裂"——裂点的位置由两座间的中点决定,站位远近改变的是裂点距怪的距离,扇面的张角不变。子箭的命中各自独立结算——三支全中是集中三十六,只中一支是分散十二,命中数玩家自己控制。

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

lua
--------------------------------------------------------------------------------
-- @file        SplitArrow.lua
-- @brief       分裂箭 —— 一支裂三支,扇面三路齐发
--              客户端表现模块:配置表 / 箭矢构件 / 分叉状态机 / 定时器
--------------------------------------------------------------------------------

local SplitArrow = {}

--------------------------------------------------------------------------------
-- 配置与常量
--------------------------------------------------------------------------------
local CONST = {
    SPLIT_CD      = 3.5,        -- 分裂箭冷却
    ARROW_SPEED   = 320,        -- 箭速三百二
    SUB_DMG       = 12,         -- 子箭十二
    FAN_SPREAD    = 90,         -- 两翼纵速差九十
    AUTO_DMG      = 10,         -- 平射十

    -- 颜色
    COLOR_ARROW   = "#d8c078",  -- 分裂金
    COLOR_DEEP    = "#6b5a2b",  -- 深金
    COLOR_GHOST   = "#f5eed8",  -- 箭白

    ZORDER_GROUND = 118,
    ZORDER_ARROW  = 133,
    ZORDER_EFFECT = 135,

    AUTOINC_BASE  = 965000,
}

--------------------------------------------------------------------------------
-- 模块内部状态
--------------------------------------------------------------------------------
local _arrows     = {}             -- 箭表
local _cdLeft     = 0
local _autoT      = 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 "SPA", 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 CreateArrowNode(isMain)
    local node = GUI:Layout_Create(GUI:Attach_SceneF(), GenID(isMain and "Main" or "Sub"),
        0, 0, 0, 0, false)
    GUI:setLocalZOrder(node, CONST.ZORDER_ARROW)
    local col = isMain and CONST.COLOR_ARROW or CONST.COLOR_GHOST
    GUI:DrawLine_Create(node, "shaft", 0, 0, 2, -10, 0, 10, 0, col, 240)
    GUI:DrawLine_Create(node, "head", 0, 0, 3, 10, 0, 5, -3, col, 240)
    GUI:DrawLine_Create(node, "head2", 0, 0, 3, 10, 0, 5, 3, col, 240)
    return node
end

骨架的三处立规。箭表的主箭和子箭共用一张表——主箭裂的时候从表里删自己、往表里塞三支子箭,进出同一张表分叉才不会漏箭。箭矢构件的箭头用两笔斜线画——三角箭头加一笔箭杆就是箭,画得太复杂飞行时看不清。分裂的中点取两座的中点——裂点距离怪三十步左右,三支子箭刚好在怪的碰撞盒上散开。

四、核心代码:完整模块(下·定时器与分裂分叉)

lua
--------------------------------------------------------------------------------
-- 分裂箭入口
--------------------------------------------------------------------------------
function SplitArrow.Cast()
    if _cdLeft > 0 then return end
    _cdLeft = CONST.SPLIT_CD
    local mp = GetActorPos(SL:GetValue("USER_ID"))
    local tp = GetActorPos(SL:GetValue("MARK_TARGET_ID"))
    if not mp or not tp then return end
    local midX = (mp.x + tp.x) / 2
    table.insert(_arrows, { x = mp.x + 16, y = mp.y - 58,
        vx = CONST.ARROW_SPEED, vy = 0, main = true, mid = midX,
        node = CreateArrowNode(true) })
    ShowTip("主箭出去了——半途裂三支")
end

--------------------------------------------------------------------------------
-- 定时器:主箭推进、分叉与子箭结算
--------------------------------------------------------------------------------
if not _scheduler then
    _scheduler = SL:Schedule(function(dt)
        _cdLeft = math.max(0, _cdLeft - dt)
        for i = #_arrows, 1, -1 do
            local a = _arrows[i]
            a.x = a.x + a.vx * dt
            a.y = a.y + a.vy * dt
            if a.main and a.x >= a.mid then
                SafeRemove(a.node)
                table.remove(_arrows, i)
                for s = -1, 1 do
                    table.insert(_arrows, { x = a.mid, y = a.y,
                        vx = CONST.ARROW_SPEED, vy = s * CONST.FAN_SPREAD,
                        main = false, node = CreateArrowNode(false) })
                end
                SL:TipAboveAt(a.mid, "分裂!")
            elseif not a.main then
                local tid = SL:GetValue("MARK_TARGET_ID")
                local tp = tid and GetActorPos(tid)
                if tp and math.abs(a.x - tp.x) < 18 and math.abs(a.y - (tp.y - 50)) < 50 then
                    SL:ActorHurt(tid, CONST.SUB_DMG)
                    SL:TipAbove(tid, "-" .. CONST.SUB_DMG)
                    SafeRemove(a.node)
                    table.remove(_arrows, i)
                end
            end
            if a.x > 700 then
                SafeRemove(a.node)
                table.remove(_arrows, i)
            end
        end
    end, 0.02)
end

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

return SplitArrow

下半场的分叉是全模块的开关:主箭横坐标过中点的判定一行——过了就自删、塞三支子箭、弹分裂提示,三步一口气。子箭的命中走独立的碰撞盒——纵速不同导致三支箭的飞行轨迹各不相同,各自的碰撞各自查。出界的子箭走横坐标超限的分支清理——三支箭各飞各的,哪支出界哪支删,不因为其他两支还在飞而留着。

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

调参三笔账。子箭十二对三支全中三十六——集中产值为平射的一点二倍,倍率太低玩家只用平射,太高平射被淘汰;一点二倍是"值得按但不强制"的甜区。扇面纵速差九十对半场宽度是三路的覆盖范围——纵速差太大三支箭散出屏外,太小三支箭叠成一团。扇面纵速差九十对半场宽度是三路的覆盖范围——纵速差太大三支箭散出屏外,太小三支箭叠成一团。分裂箭的音效也要分主箭和子箭——主箭一声弦响、子箭三声破空,听声就知道裂了几支。分裂中点取两座中点——中点近怪则三支同时扎到,中点远怪则扇面散开只中一支,裂点的远近就是集中与分散的旋钮。常见坑三个:分叉的瞬间主箭没删干净,主箭继续飞变成四支;子箭的纵速只加了正号,扇面只往上半开;分裂的提示和音效共用主箭的,主箭和子箭分不清。

商业服里分裂箭是"弓手流派"的第一课:单体平射和分裂扇面两种模式教会弓手"什么时候该分散",弓手的操作深度从第一支分裂箭开始。弓手的操作深度从第一支分裂箭开始。分裂箭的冷却三点五秒对平射一点四秒留两秒的回档——分裂箭是重拳、平射是轻拍,轻重交替才是弓手的完整循环。分裂箭是"弓手流派"的第一课:单体平射和分裂扇面两种模式教会弓手"什么时候该分散",弓手的操作深度从第一支分裂箭开始。分裂箭的箭羽音效也要分主箭和子箭——主箭一声闷、子箭三声脆,听声就知道箭裂了。商城里分裂箭的箭羽做成品级——白羽、凤羽、龙羽,三支扇面齐发的那一帧就是箭羽的海报帧。变体做成五路分裂:五支扇面覆盖更大但单支伤害砍半——覆盖与集中之间多了一档选择。这一篇的演示和整套模块照抄能跑,改的就是 CONST 那张表。

写完留一句给做投射系的同学:分裂箭卖的是"一支变三支的展开感"——扇面张开的那个瞬间,玩家的输出从一条线变成了一张网。

作者履历与出处

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

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

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

LATEST ARTICLES

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

进阶实战游戏功能

影锁:影锁绑你绑它,锁期拼刀

【游戏功能】 控制技能的镜像问题是:锁住了怪,自己是不是也闲着?影锁把这道两难摆上台面:影锁四秒,它动不了、你也动不了——它…

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

震魂:震魂入体叠加出招自损

【游戏功能】 打断为什么只有"清读条"一种?震魂偏要反过来——不清招、不断势,打在它读条半途的那一劲顺着招震进腑——中劲十秒…

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

蜂王:喂小怪蜂王进化,三阶蜂王蜇翻全场

【游戏功能】 蜂群为什么总是一只一只出?蜂王偏要让它们进化:放一只蜂王出来,杀掉小怪喂它——喂三只升一阶,三阶蜂王的毒刺一秒…

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

血刃:每刀扣血换吸血,血刀双刃

【游戏功能】 技能为什么总是不扣自己的血?血刃偏要反着来:开着血刃的每一刀先扣自己二血、命中回三血——净赚一但要打得中,空刀…

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

破军旗:旗立三秒圈内加攻,旗倒攻散

【游戏功能】 bn.t = bn.t - dt ——一行旗面倒计时的代码,撑起了破军旗全部的紧迫感:旗立三秒、圈内加攻三成,…

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

淬毒刃:淬毒三刀叠一层,一层毒过一秒六

【游戏功能】 淬毒为什么要一毒到底?淬毒刃偏要一层一层叠:一刀淬一层毒、毒层一秒六地烂,六层封顶之后一刀下去毒伤三十六——叠…

2026-10-01 10:00 996 技术组