小地图是玩家定位的第一信息源:角色位置、队友标记、BOSS 与传送点的分布全压在右上一角。小地图的渲染核心是世界坐标到缩略图坐标的换算、视野框的绘制与标记的动态增删,解密源码里 gameStateWorld 的地图层提供了现成的参照。
---世界坐标转小地图坐标:比例 1:10
local MAPW, MAPH = 1000, 800
local MiniMap = { layer = nil, scale = 10 }
function MiniMap.toMini(wx, wy)
local mx = wx / MiniMap.scale
local my = MAPH / MiniMap.scale - wy / MiniMap.scale
return mx, my
end
function MiniMap.drawSelf(actor)
local mx, my = MiniMap.toMini(actor.x, actor.y)
if not MiniMap.selfMark then
MiniMap.selfMark = GUI:Text_Create(MiniMap.layer, "me", 0, 0, 12, "#FFD700", "▲")
end
GUI:Text_setPosition(MiniMap.selfMark, mx, my)
end
世界坐标除以缩放比例 10 落进 100 乘 80 的缩略区域,纵轴取反向匹配屏幕习惯——世界坐标向上增大而屏幕坐标向下增大,这步换反了标记就集体倒挂。自身标记创建一次后只改位置,避免每帧重建控件。
---注册地图标记消息:队友与 BOSS 位置
SL:RegisterLuaNetMsg("MAPMARK", function(data)
local marks = SL:JsonDecode(data)
if not marks or #marks > 50 then return end
for _, m in ipairs(marks) do
local mx, my = MiniMap.toMini(m.x, m.y)
MiniMap.put(m.kind, m.id, mx, my)
end
end)
-- 200 毫秒刷新一次视野框
SL:Schedule(0.2, function() MiniMap.refreshViewBox() end)
标记数据走前端网络注册通道,服务端每 200 毫秒推一帧队友与 BOSS 的聚合位置,单帧标记数上限 50,超限的低优先级标记丢弃。视野框按当前镜头的中心与尺寸绘制,玩家拖动镜头时视野框随之滑动,与世界的对应关系保持一致。解密源码的 actorManager 里同屏角色的遍历顺序可作对照,标记的层级在怪物之上、界面之下。
标记与真实位置的偏差抽样对比,偏差超过 1 个缩略格即为换算回归;刷新的帧耗时监控,超过 3 毫秒即优化控件复用。
纵轴方向曾经没取反,全服玩家的标记都在地图对角,两行代码的修复排查了一下午。标记控件曾经每帧重建,百人同屏时创建销毁的风暴让帧率腰斩,改为对象池复用后归零。队伍解散后队友标记残留,靠数据侧的清理消息兜底,界面层不做超时推断。
缩放比例与地图尺寸从配置读取,缩放支持滚轮调节 5 到 20 档位。标记按类型分层:BOSS 红色置顶、队友蓝色、传送点灰色,颜色的语义全服统一。小地图的点击即寻路:点击缩略图任意点,换算回世界坐标发起自动寻路,点击的命中半径放宽到 2 个缩略格。
本文由 996 技术组基于 996 引擎官方知识库与浮生梦老师课程体系整理。团队长期从事传奇类引擎 Lua 后端逻辑、客户端界面与商业版本交付,内容以官方知识库与真实项目为出处,按版本持续修订。
全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →
实战应用:用在哪里 师门的公共物资散落在各成员背包里,打仗时才发现没药没符。师门仓库给师门一个共享物资池:成员捐献药品、符纸…
实战应用:用在哪里 师门任务的药材全靠成员自己采,供给不稳定还常被市场价卡脖子。师门药园给师门一块自留地:成员认领地块种植药…
实战应用:用在哪里 锁妖塔是每周最受期待的限时地图:封印每七天松动一次,开门后两小时内妖物掉落翻倍,时间一过封印重合。定时开…
实战应用:用在哪里 师门掌门长期连任,门派活动没人组织,新人没有上升通道。掌门挑战玩法给掌门之位装上轮换机制:每两周开放一次…
实战应用:用在哪里 行会驻地有一片空地,升级什么全凭帮主心情。行会建筑升级接口把驻地建筑体系化:聚义厅、兵器库、药庐、演武场…
实战应用:用在哪里 行会公告只有一行纯文本,写不下攻城安排。富文本公告编辑器支持分段落、插表情、标重点色,编辑区所见即所得,…