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

滚轮翻看:背包列表跟着滚轮走的顺滑滚动

2026-09-28 00:54 作者:996 技术组 996引擎Lua教程传奇脚本进阶实战游戏功能996引擎

【游戏功能】
一、一次本可避免的差评

PC 版上线第六天,应用商店冒出一条一星评论:"背包都不能滚轮翻,什么年代了。"复现一看,背包、仓库、好友列表全都是拖拽滚动,鼠标滚轮在面板上直接穿过去滚动了背后的地图视角。移动端起家的工程惯性——触屏没有滚轮,ScrollView 默认就不接管它。但对键鼠玩家,滚轮就是翻列表的第一直觉,这个缺口不补,所有长列表都在持续制造差评。

二、机制原理:接管滚轮的三层结构

滚轮接管在引擎里分三层:捕获层,监听鼠标滚轮事件拿到增量;换算层,把增量按列表内容高度折算成滚动百分比的步进;表现层,把百分比变化写回 ScrollView 并触发渲染更新。LuaExtend 里最漂亮的一手是绑定时机——不给每个列表手动挂监听,而是在 UI 根节点创建时递归扫描整棵子树,凡是描述为 ListView 或 ScrollView 的节点、且是纵向滚动的,统一注入滚轮支持。新界面只要走了标准创建流程,滚轮自动可用,零遗漏。

下面这个演示把整条链路搬进来了:开关「滚轮接管」对比事故现场,滚轮或按钮翻动列表,观察插值出来的顺滑滚动。

demo
wheel-scroll

三、正确写法:递归扫描与百分比注入

lua
-- UI 根节点创建时: 递归给纵向列表注入滚轮支持
local function checkChildren(children)
    for _, child in pairs(children) do
        local desc = child.getDescription and child:getDescription()
        if desc == "ListView" or desc == "ScrollView" then
            if child:getDirection() == 1 then       -- 纵向才接管
                child:addMouseScrollPercent()
            end
        end
        checkChildren(child:getChildren())
    end
end
checkChildren(rootNode:getChildren())

-- 滚轮增量 → 滚动百分比步进
function ScrollView:addMouseScrollPercent(callback)
    local listener = cc.EventListenerMouse:create()
    local percentStep = 8                            -- 每档滚动 8% 距离
    listener:onMouseScroll(function(event)
        local sy = event:getScrollY()
        local cur = self:getScrolledPercentY()
        local next = math.max(0, math.min(100, cur - sy * percentStep))
        self.scrollToPercentY(next, 0.08, false)     -- 0.08s 缓动到位
        if callback then callback(next) end
    end)
    cc.Director:getInstance():getEventDispatcher()
        :addEventListenerWithSceneGraphPriority(listener, self)
end

四、顺滑的三个细节

  1. 百分比换算用内容高度归一,长列表短列表一档的手感一致;步进取 6~10 之间最接近原生应用。2. scrollToPercentY 带缓动时间,一档滚动不是瞬移而是一小段插值动画,这是"顺滑感"的直接来源;滚动偏移用指数插值逼近目标值,帧率无关。3. 横向列表(direction 为 0)不要接管,否则横向翻页和纵向滚轮打架;判定写在扫描里,而不是靠人记得。

五、心法:输入适配是表现的一部分

键鼠玩家的滚轮、触屏玩家的惯性滑动、手柄玩家的摇杆翻页,本质是同一件事:把设备输入翻译成列表的百分比步进。前端框架层的职责就是在创建链路上把这类翻译统一注入,让业务层完全无感。判断一个客户端工程是否成熟,看它敢不敢把新设备的新输入方式接到旧的列表上——接得上,说明输入、换算、表现三层早就分好了家。

作者履历与出处

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

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

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

LATEST ARTICLES

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

进阶实战游戏功能

Lua+string.len:字符串长度的字节本质

【语法算法】 闭包工厂的本质就这一行: 外层函数接收配置,返回一个闭包——闭包捕获配置,后续调用使用捕获的配置——闭包工厂的…

2026-09-29 16:47 996 技术组
进阶实战游戏功能

Lua+闭包工厂:函数返回函数的工厂本质

【语法算法】 闭包工厂的本质就这一行: 外层函数接收配置,返回一个闭包——闭包捕获配置,后续调用使用捕获的配置——闭包工厂的…

2026-09-29 16:47 996 技术组
进阶实战游戏功能

Lua+泛型for的四种形态:从简单到完整的进化本质

【语法算法】 泛型 for 的四种形态就这两行: 泛型 for 的四种形态覆盖了 Lua 所有的遍历需求——从无序遍历到有序…

2026-09-29 16:46 996 技术组
进阶实战游戏功能

Lua+string.find的起始偏移:模式搜索的范围本质

【语法算法】 string.find 的起始偏移就这一行: 第三个参数 init 是搜索的起始偏移——从字符串的第 init…

2026-09-29 16:46 996 技术组
进阶实战游戏功能

Lua+CPU时间与墙钟时间:两种计时的分界本质

【语法算法】 CPU 时间和墙钟时间的分界就这两行: os.clock 返回 CPU 时间——程序实际占用处理器的秒数——o…

2026-09-29 16:46 996 技术组
进阶实战游戏功能

Lua+元方法__unm:一元负号的自定义本质

【语法算法】 元方法 __unm 的触发就这一行: 对带 __unm 的表做一元负号操作 -t 时,Lua 调用 __unm…

2026-09-29 16:46 996 技术组