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

蓄雷:挨的打先记账,两秒后一声雷还清

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

【游戏功能】

挨打还要挨出学问来?蓄雷的答案是:挨的打先别急着疼,记在账上——蓄两秒,两秒里它打多少记多少,人一根汗毛不掉;两秒一到,账上的六成化作一声雷,连本带利砸回去。这篇把整套模块拆开:配置表、蓄雷构件、记账结算、定时器、调试按钮,一段一段照抄能跑。

一、效果演示:挨的打记账,一声雷还清

演示场的怪出手密集,一点五秒一拍——正好喂账。点「蓄雷!」:玩家周身亮起紫色的雷纹,头顶转起两秒的蓄环——蓄环转动的两秒里,怪的每一刀都被紫环吸走:不掉血、不闪红,头顶只蹦"账十四""账二十八"。蓄满的一瞬:紫环炸开,一道雷顺着它自己的刀路劈回去——四十二点的账折成雷伤,二十六点的紫字砸它脸上。演示里试两件事:怪打得越勤雷越疼,怪手软的那两秒雷就哑——蓄雷的账本永远诚实地记着它的输出。蓄雷玩的是借力:它的每一刀都是往你账本里存钱。

demo
 fx-stormstore

二、底层原理:一条免伤账道加一次清账落雷

模块的机关是一对搭档。免伤账道:蓄雷的两秒里玩家挂一条"记账免伤"链——命中的伤害全额转进账本,血条不动,账本透明地长,头顶的"账"字就是账本的读数。清账落雷:蓄满那一拍账本乘零点六整笔放出——雷伤认的是两秒里它真正出的力,它不出力雷就哑,账本不做假账。和铜墙那类减伤的分野在"减伤是折扣、蓄雷是转账":铜墙把刀打折,蓄雷把刀存起来换一种方式花——一个守,一个借力打力,账目的方向完全相反。

落雷为什么是六成不是十成?十成的版本蓄雷是完美反弹,攻守一体无懈可击,怪的刀全替玩家打工;六成留四成的过路费,蓄雷是赚差价的买卖不是无本生意——差价就是平衡的手续费。

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

lua
-- @file StormStore.lua
-- 蓄雷 —— 挨的打先记账,两秒后一声雷还清

local StormStore = {}

local CONST = {
    STORE_LIFE    = 2.0,
    STORE_CD      = 7.0,
    BOLT_RATE     = 0.6,

    COLOR_BOLT    = "#b088e8",
    COLOR_DEEP    = "#3e1a5e",
    COLOR_GHOST   = "#e4d0fa",

    ZORDER_STORE  = 131,
    ZORDER_FX     = 135,
    AUTOINC_BASE  = 1006000,
}

local _storeT    = 0
local _book      = 0
local _cdLeft    = 0
local _storeFx   = nil
local _scheduler = nil
local _autoInc   = 0

local function GenID(prefix)
    _autoInc = _autoInc + 1
    return string.format("%s_%d", prefix or "SRS",
        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 StormStore.Cast()
    if _cdLeft > 0 or _storeT > 0 then return end
    local myID = SL:GetValue("USER_ID")
    if not myID then return end
    _cdLeft = CONST.STORE_CD
    _storeT = CONST.STORE_LIFE
    _book = 0
    SafeRemove(_storeFx)
    _storeFx = GUI:Layout_Create(GUI:Attach_SceneF(),
        GenID("Store"), 0, 0, 0, 0, false)
    GUI:setLocalZOrder(_storeFx, CONST.ZORDER_STORE)
    SL:PlayStoreUpFx(myID)
    SL:TipAboveMe("蓄雷!")
    ShowTip("蓄雷开始——两秒里它打多少记多少,人不掉血")
end

四、核心代码:完整模块(下·定时器与清账落雷)

lua
-- 记账免伤链:蓄雷期伤害全额入账
SL:RegisterLUAEvent(LUA_EVENT_BEFORE_HURT, "SRS_Book", function(tid, dmg)
    if _storeT > 0 and tid == SL:GetValue("USER_ID") and dmg > 0 then
        _book = _book + dmg
        SL:TipAboveMe("账" .. _book)
        SL:PlayStoreAbsorbFx()
        return 0
    end
    return dmg
end)

-- 清账落雷
local function DropBolt()
    local out = math.floor(_book * CONST.BOLT_RATE)
    local tid = SL:GetValue("MARK_TARGET_ID")
    local tp = GetActorPos(tid)
    _book = 0
    SafeRemove(_storeFx)
    _storeFx = nil
    if out <= 0 or not tp then
        ShowTip("两秒空账——它一掌没出,雷哑了")
        return
    end
    SL:ActorHurt(tid, out)
    SL:TipAbove(tid, "雷-" .. out)
    SL:PlayBoltStrikeFx(tid)
    SL:ScreenShake(3.4, 0.22)
    ShowTip("一声雷还清——" .. out .. "点砸它脸上")
end

-- 定时器:蓄环推进与落雷触发
if not _scheduler then
    _scheduler = SL:Schedule(function(dt)
        _cdLeft = math.max(0, _cdLeft - dt)
        if _storeT > 0 then
            _storeT = _storeT - dt
            local myID = SL:GetValue("USER_ID")
            local mp = GetActorPos(myID)
            if _storeFx and mp then
                GUI:setPosition(_storeFx, mp.x, mp.y - 40)
            end
            if _storeT <= 0 then DropBolt() end
        end
    end, 0.02)
end

SL:ScheduleOnce(function()
    SL:BindDebugButton("蓄雷", function()
        StormStore.Cast()
    end)
    ShowTip("技能已加载: 蓄雷 (调试按钮触发)")
end, 1.0)

function StormStore.Unload()
    if _scheduler then SL:Unschedule(_scheduler) end
    SL:UnregisterLUAEvent(LUA_EVENT_BEFORE_HURT, "SRS_Book")
    SafeRemove(_storeFx)
end

return StormStore

五、机制问答

问:蓄雷期自己能出手吗?
答:不能——蓄雷是双手引雷的姿势,攻击打断蓄环,想打人先忍两秒,这是蓄雷的全部成本。

问:账本封顶吗?
答:不封——它两秒里砸多狠雷就有多疼,高频怪的密集输出就是雷的弹药库,封顶的版本遇强则弱,反了天理。

问:两秒里怪没出手呢?
答:雷哑——空账放空炮,只演一圈散掉的雷纹,蓄雷从不平白无故送伤害,账本不做假账。

问:雷的落点认人还是认位置?
答:认人——账是谁记的就劈谁,跑出半场雷照样追,蓄雷的追债没有距离的概念。

问:蓄雷能和铜墙一起开吗?
答:不能——免伤链互斥,记账和打折只能选一条,两套都开的版本坦克从防御工事变成武器库。

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

第四笔是落雷的比例:六成是"借力要付手续费"的档——比例抬到八成,高频怪变成玩家的充电桩;压到四成,忍两秒不值一回。第三笔是蓄期的长度:两秒对怪一点五秒的出手是"必吃一到两刀"的窗口——蓄期太短账薄雷轻,太长玩家站桩的乏味压过爽感。第二笔是空账的演出:哑雷也要响——散掉的雷纹加一句"它一掌没出",空账有演出,玩家才肯再赌下一轮。第一笔是账本的可读性:每笔入账的"账"字叠加而不是刷新——数字一路长上去,雷还没落,爽感先涨了一半,账本的膨胀就是蓄雷的进度条。常见坑三个:持续伤害进了账本,毒跳的零碎伤害把雷喂成炮;蓄雷期被打断账本不清,醒来一雷劈的是两秒前的账;落雷的击杀归属挂了怪自己,战绩页闹乌龙。

商业服里蓄雷是"引雷流派"的看家咒:把对方的输出念成自己的咒语——商城里雷纹的样式做成品级,紫雷、金雷、龙雷,账本数字翻上去的那两秒就是引雷玩家的仪式。运营落地还有两笔:一段是高频怪图鉴——哪种怪喂雷最肥写进页脚,引雷玩家按图选怪;一段是雷榜——按单声落雷的最大伤害排名,被怪喂出来的传说有据可查。变体做成余雷:落雷后的三秒里再挨的打按三成自动回敬——雷过了还有静电,黏人的后半段。这一篇的演示和整套模块照抄能跑,改的就是 CONST 那张表。

雷的规矩也简单:它出多重的手,你就还多响的雷,两清。

账本翻页的声音,就是雷落地的预告。

引雷的最后一步永远是把眼睛闭上,听账。

写完留一句给做转化系的同学:蓄雷卖的是"你的刀就是我的雷"——头顶那本越翻越厚的账,是它亲手替你写好的判决书,两秒一到,按账执行。

作者履历与出处

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

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

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

LATEST ARTICLES

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

进阶实战游戏功能

赊账:这一刀双倍先赊着,三秒后连本带息还

【游戏功能】 先消费后还款这事儿,战场上也行得通?赊账的答案是行得通,但有利息:点一下赊账,下一刀双倍——多出来的那十点伤害…

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

全垒:把小怪挑上天,一记扣杀双倍入账

【游戏功能】 为什么棒球里全垒打最值钱?因为球在天上的那一秒,全场的眼睛都仰着头。全垒把这份仰头搬进了打架:一记挑空把小怪送…

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

迟箭:把它的箭慢放成蜗牛,箭雨里都能散步

【游戏功能】 后台埋点抓到一个怪数据:某位玩家的承伤记录里,被远程命中数是零——不是躲得快,是他挨的每一箭都"消失了"。翻录…

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

借刀:站到它队友身后,借它自己的刀劈它

【游戏功能】 P.x, C.x = C.x, P.x —— 一行换位,借刀的全部机关就藏在这一笔里:玩家和小怪换个位置,怪的…

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

搬兵:抓一只小的抡起来,砸得大的直哆嗦

【游戏功能】 打群架的最高境界是什么?是一个人打,让对面自己人打自己人。搬兵把这句话演成了动作:抓住一只小怪举过头顶,抡圆了…

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

越战:开战越久劲越足,三十秒练出一口气

【游戏功能】 同样的装备,为什么老玩家打得越来越疼?新手第一刀十点,第一百刀还是十点;老玩家第一刀十点,第一百刀已经十四——…

2026-10-01 12:59 996 技术组