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

Lua淡入淡出:透明度的排队渐变

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

【语法算法】

接着抛坑:淡入没播完又来一个淡出,会怎样?答不好的界面都会出事——同一个面板的透明度被两个渐变同时抢,一个往上一个往下,数字来回打架,面板就在半透明里抽搐。淡入淡出的答案是排队:渐变一笔一笔来,一笔走完再走下一笔,谁也不抢谁的透明度。这篇把整套写法拆开:配置表、渐变队列、单步推进、边界钉死、定时器、调试按钮,一段一段照抄能跑。

一、效果演示:透明度的排队渐变

演示场三块面板:甲亮着,乙丙暗着。点「淡入下一块」:第一块暗面板入队——队里排在前面还有几个的提示当场播报;轮到它时,透明度从零滑到一,滑完才轮下一笔。点「淡出最上」:最亮的面板入队淡出——透明度滑回零。连点几个操作也不怕:队列一笔一笔消化,谁也不抢谁的账。演示里试一笔账:排队渐变的三个操作和并行渐变的三个操作——并行的透明度会打架,排队的每一拍都清清楚楚。淡入淡出教的是排队:透明度只有一份,渐变必须串行走单行道——一份资产一个写手,账本学的基本功搬进界面照样好使,这也是队列存在的全部理由,理由只有一条但顶得上一百次调试,调试省下来的时间够把界面再抛一遍光——抛过光的界面自己会说话,说到人人爱听。

mermaid
flowchart TD
A[渐变请求入队] --> B{当前有渐变在跑}
B -- 是 --> C[排队等着]
B -- 否 --> D[队首出列 开渐变]
D --> E[透明度按方向逐拍推进]
E --> F{到边界了吗}
F -- 否 --> E
F -- 是 --> G[钉死在边界 取下一笔]
G --> B
demo
 fx-fadequeue

二、底层原理:一条渐变队列加一次单步推进

模块的机关是一对搭档。渐变队列:每一笔淡入淡出的请求进队排队——队列认先来后到,一笔渐变没走完,后面的笔全在队里候着。单步推进:队首的渐变逐拍推进透明度——淡入往一走、淡出往零走,到边界钉死边界,钉死之后取下一笔。和并行渐变的分野在"透明度只有一份主权":并行渐变是多笔同时改一个透明度,改完谁说了算听谁的;排队渐变同一拍只有一笔在改,透明度的账本永远只有一个写手,打架从根上就不存在。

为什么淡入淡出非要排队不能并行?同一个面板的透明度是单份资产——两笔渐变改它就是两笔写同一个变量,抢到的说了算,面板抽搐;排队把写手串成单行道,抽搐从根上绝迹——单行道是笨办法,也是唯一的好办法。

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

lua
-- @file FadeQueue.lua
-- 淡入淡出 —— 透明度的排队渐变

local FadeQueue = {}

local CONST = {
    FADE_SPEED    = 1.6,
    PANEL_COUNT   = 3,

    AUTOINC_BASE  = 1160000,
}

local _panels    = {}
local _queue     = {}
local _cur       = -1
local _scheduler = nil
local _autoInc   = 0

local function GenID(prefix)
    _autoInc = _autoInc + 1
    return string.format("%s_%d", prefix or "FDQ",
        CONST.AUTOINC_BASE + _autoInc)
end

local function ShowTip(msg)
    if msg and msg ~= "" then SL:ShowSystemTips(msg) end
end

function FadeQueue.Enqueue(idx, dir)
    _queue[#_queue + 1] = { idx = idx, dir = dir }
    ShowTip("渐变排队——前面还有" .. #_queue .. "笔")
end

function FadeQueue.QueueLen()
    return #_queue
end

四、核心代码:完整模块(下·单步推进与边界钉死)

lua
-- 单步推进:队首出列开渐变,到边界取下一笔
if not _scheduler then
    _scheduler = SL:Schedule(function(dt)
        if _cur < 0 and #_queue > 0 then
            _cur = table.remove(_queue, 1)
        end
        if _cur < 0 then return end
        local panel = _panels[_cur.idx]
        if not panel then
            _cur = -1
            return
        end
        panel.alpha = panel.alpha
            + _cur.dir * CONST.FADE_SPEED * dt
        if panel.alpha <= 0 then
            panel.alpha = 0
            _cur = -1
        elseif panel.alpha >= 1 then
            panel.alpha = 1
            _cur = -1
        end
    end, 0.02)
end

function FadeQueue.EnqueueFadeIn(nextDim)
    for i = 1, CONST.PANEL_COUNT do
        local idx = (nextDim + i - 1) % CONST.PANEL_COUNT + 1
        if _panels[idx].alpha < 1 then
            FadeQueue.Enqueue(idx, 1)
            return
        end
    end
    ShowTip("全都亮着——没得淡入")
end

SL:ScheduleOnce(function()
    SL:BindDebugButton("淡入下一块", function()
        FadeQueue.EnqueueFadeIn(0)
    end)
    ShowTip("技能已加载: 淡入淡出 (调试按钮触发)")
end, 1.0)

function FadeQueue.Unload()
    if _scheduler then SL:Unschedule(_scheduler) end
    _queue = {}
    _cur = -1
end

return FadeQueue

五、机制问答

问:淡出淡入能交叉排队吗?
答:能——队列不管方向只管次序,淡出后紧跟淡入也是一笔一笔走,交叉的账最考验排队。

问:排队的时候界面会卡吗?
答:不卡——排队的是渐变不是界面,没轮到的面板保持当前透明度站好,界面照常响应。

问:一笔渐变能中途取消吗?
答:能——取消的笔从队列摘除,正在跑的那笔走完边界钉死,取消不毁边界。

问:透明度的推进速度能变速吗?
答:能——速率是每一笔的属性,急账快滚慢账缓推,队列里各笔各速互不干扰。

问:淡出的面板还能再淡入吗?
答:能——淡出钉在零的面板是待命状态,再入队一笔淡入就从零滑回一,暗着不等于销毁。

六、调参与实战怎么用

第四笔是边界的钉死:到零钉零到一钉一是渐变的信用——不钉死的版本浮点差半格,下一笔的起点就带着毛边,钉死是排队渐变的账面清白。第三笔是队列的消费:一拍只走一笔是排队的铁律——并行消费的版本透明度打架面板抽搐,那场抽搐的教训换来这条铁律。第二笔是速率的独立:每笔渐变自带速率——入场快出场慢是常见的搭配,速率入笔时带上,队列里快慢自便。第一笔是排队的播报:队里还有几笔要实时报——玩家点的每一笔都看得见自己排第几,排队的烦躁全靠播报压着。常见坑三个:并行渐变抢透明度的抽搐;取消的笔没有从队列摘除空跑一遍;淡出的面板叠着新的淡入导致同面板两笔在队。

实战里排队渐变是所有"一次只演一笔"的通用件:面板的进出、提示的轮换、教学高亮的接力,全是"队列加单步"的同一副骨架。组里的约定是:同一个属性的渐变一律排队不许并行——写手串成单行道,抽搐就绝了根。这篇的模块照抄能跑,改的就是 CONST 那张表。

写完留一句给做渐变系的同学:淡入淡出卖的是"一笔一笔来"——那三块排队轮换的面板和永远只有一个写手的透明度,是把渐变从抢账变成排队的一支笔——笔只有一支,账才能记得清清楚楚明明白白,一笔一画都是体面。

作者履历与出处

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

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

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

LATEST ARTICLES

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

进阶实战游戏功能

Lua自动炮台:架一个自动索敌开火

【语法算法】 上一版的炮台索敌逻辑有个隐蔽报错:炮台永远打同一个怪——即使那只怪已经死了,索敌的游标也不挪窝。追到底索敌的游…

2026-10-02 04:50 996 技术组
进阶实战游戏功能

Lua元素转换:火伤转冰伤附带减速

【语法算法】 先抛一个坑:打不完的火系怪怎么办?火抗怪火打不动,换冰系技能要切装备要换面板——切完黄花菜都凉了。元素转换的答…

2026-10-02 04:50 996 技术组
进阶实战游戏功能

Lua连锁引燃:一个着火引燃下一个

【语法算法】 上个月的事故复盘会上有个数字被念了三遍:四成——策划写的是"同伴陪疼四成",代码落下去成了"陪疼四十点",两只…

2026-10-02 04:50 996 技术组
进阶实战游戏功能

Lua弹射地垫:踩上去弹飞到空中

【语法算法】 单行代码拆解:弹射初速=-420——弹射的全部动力就这一行的负初速。负号朝上、四百二十是弹射的初速大小——踩上…

2026-10-02 04:50 996 技术组
进阶实战游戏功能

Lua时间减缓:流速减半的局部时差

【语法算法】 上一版的减速类模块全按"乘以零点五"来写,帧率无关的版本照搬了这套写法——结果高帧率机上减速效果好,低帧率机上…

2026-10-02 04:50 996 技术组
进阶实战游戏功能

Lua引力球:丢出去把怪吸过来

【语法算法】 先抛一个坑:怎么把散在四处的怪聚到一起打?逐个拉是笨办法,一个范围技又只能打一片——引力球的答案是一个会动的吸…

2026-10-02 04:50 996 技术组