背包是玩家操作密度最高的界面:拖拽换位、跨页挪动、拖出即丢弃,每个手势都要顺手。背包网格的拖拽实现要点是命中检测、拖影跟随与落点的两种语义——落在格子上是交换,落在页签上是翻页携带。
---背包网格:40 格逐格创建
function BagUI.build(page)
for i = 1, 40 do
local idx = (page - 1) * 40 + i
local box = GUI:ItemBox_Create(BagUI.node, "cell_" .. idx,
10 + ((i - 1) % 8) * 46, 10 + math.floor((i - 1) / 8) * 46)
GUI:addOnClickEvent(box, function()
BagUI.onCellTap(idx)
end)
BagUI.cells[idx] = box
end
end
---点击选中与拖拽起手的区分
function BagUI.onCellTap(idx)
if BagUI.dragFrom and BagUI.dragFrom ~= idx then
BagUI.swap(BagUI.dragFrom, idx)
else
BagUI.dragFrom = idx
SL:ShowSystemTips("已选中,再点另一格交换")
end
end
40 格按 8 列 5 行排布,GUI:ItemBox_Create 逐格创建物品格子控件。拖拽的手势在触屏上不好判定,点选交换的两段式操作是等价替代:点第一格选中,点第二格完成交换。拖影与点选并存,端上游走拖拽、移动端点选,同一套交换语义。
---跨页交换:拖到页签即翻页携带
function BagUI.swap(fromIdx, toIdx)
local fromPage = BagUI.pageOf(fromIdx)
local toPage = BagUI.pageOf(toIdx)
if fromPage ~= toPage then
SL:ShowSystemTips("跨页请先翻页再整理")
return
end
SL:SendNetMsg(MSGID.BAG_SWAP, fromIdx, toIdx, 0, "")
BagUI.render(fromIdx, BagUI.itemOf(fromIdx))
BagUI.render(toIdx, BagUI.itemOf(toIdx))
end
交换请求发给服务器裁决,客户端先本地换显再按服务器回包校正,拖拽的跟手感与数据的一致性两头兼顾。非法落点(丢弃区、锁定格)在客户端预先拦截,SL:ShowSystemTips 给出原因提示。装备上身的快捷操作走同一套交换通道:把裁决之杖从背包格拖到装备位,本质是一次特殊的目标格交换。
交换请求的客户端预演与服务器裁决的不一致率监控,超过 1% 说明预演规则与服务器不同步;拖拽误触率的埋点统计,误触进丢弃区的操作弹二次确认。
格子坐标曾经按 6 列排布写死,换 8 列皮肤后整屏错位,行列数进皮肤配置。跨页交换曾经直接执行,服务器因页签校验拒绝后客户端显示错乱,跨页的预拦截统一收口。点选态没有超时释放,选中一小时后误触另一格完成了一次无意识交换,选中态 10 秒自动释放。
网格的行列数与格子尺寸从皮肤配置读取,主题换肤不动逻辑。交换的快捷键支持:选中后按方向键移动物品,键盘玩家的整理效率翻倍。物品的 Tooltip 在长按 300 毫秒时弹出,与拖拽起手的时间阈值错开。
本文由 996 技术组基于 996 引擎官方知识库与浮生梦老师课程体系整理。团队长期从事传奇类引擎 Lua 后端逻辑、客户端界面与商业版本交付,内容以官方知识库与真实项目为出处,按版本持续修订。
全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →
实战应用:用在哪里 跨服远征分先锋、主力、后勤三队独立推进,三线全通合围BOSS。不同战力成员都有参与感。 策划要点与配置 …
实战应用:用在哪里 副本限时挑战加入超时血量惩罚:超时后BOSS攻击递增。上线后BOSS攻击叠到十倍秒杀全队。 事故还原与补…
实战应用:用在哪里 混沌麒麟召唤是全服高光时刻:暗幕聚合、裂缝展开、麒麟着陆三段演出各1.3秒。 三段式入场演出编排 围观镜…
实战应用:用在哪里 任务对话一闪而过玩家想回顾。回看接口把对话按节点存档,面板翻阅全部对话记录。 对话存档与查询渲染 当前章…
实战应用:用在哪里 服务器承载六十张地图,空闲地图白耗资源。按需激活,末人离开后六十秒休眠。 激活与休眠触发 休眠回收 验证…
实战应用:用在哪里 坐骑资质洗炼随机重滚五条属性,锁定满意的条目不再重滚,锁定越多消耗越大。 洗炼与锁定 锁定消耗递增 验证…