下载 App

地图编辑器地面交互与视觉优化

07/27综合

horizontal linehorizontal line

一、问题链

用户截图反馈了三个递进的问题:
问题 1:点击地面类型(如食堂地砖),弹窗不关闭,挡住画布无法操作
         ↓ 修复 v0.10.94
问题 2:地面贴图太大,一块地砖比小人还宽,比例失调
         ↓ 修复 v0.10.96(改配置值)
问题 3:改了配置值后刷新仍然太大——旧存档的 tileSize=256 优先级高于新 config
         ↓ 修复 v0.10.97(反转渲染优先级)
horizontal linehorizontal line

二、关键代码

1. 地面选择后自动关闭弹窗(v0.10.94)

文件scripts/页面/地图编辑模式.luaSelectPaletteItem 函数
修改前:只有"木地板"会关闭弹窗,其余 7 种地面类型弹窗一直挡着画布。
lua
-- ❌ 旧代码:仅木地板特判关闭弹窗 if item.floorStyle then editorState_.selectedFloorStyle = item.floorStyle if item.floorStyle == "木地板" then editorState_.sidebarCategory = nil -- 只有木地板关闭 end end
修改后:所有地面类型统一关闭弹窗 + 给出操作引导。
lua
-- ✅ 新代码:所有地面类型统一关闭弹窗 if item.floorStyle then editorState_.selectedFloorStyle = item.floorStyle editorState_.sidebarCategory = nil -- ★ 统一关闭 editorState_.status = "已选择" .. item.text .. "。点击房间铺设地面,或在空白处拖拽框选地面区域。" RequestRebuildUI(context) return -- ★ 提前退出,不走下面的通用逻辑 end
经验:弹窗的 sidebarCategory 是唯一的开关变量,设为 nil 即关闭。新增地面类型时不需要逐个加特判。
horizontal linehorizontal line

2. tileSize 配置值缩放(v0.10.96)

三处同源配置必须同步改,否则编辑器和运行时显示不一致。
(a)编辑器目录scripts/页面/地图编辑/编辑器目录.lua
lua
MapEditorCatalog.FLOOR_STYLE_CONFIGS = { ["木地板"] = { texture = "image/地面/木地板_无缝.png", tileSize = 40 }, -- 原 128 ["草地"] = { texture = "image/地面/campus_background.png", tileSize = 64 }, -- 原 256 ["水泥地"] = { texture = "image/地面/campus_canteen_floor.png", tileSize = 40 }, -- 原 256 ["教室地砖"] = { texture = "image/地面/campus_classroom_floor.png", tileSize = 40 }, -- 原 256 ["走廊地砖"] = { texture = "image/地面/campus_classroom_floor.png", tileSize = 40 }, ["卫生间瓷砖"] = { texture = "image/地面/campus_canteen_floor.png", tileSize = 40 }, ["食堂地砖"] = { texture = "image/地面/campus_canteen_floor.png", tileSize = 40 }, ["医务室地砖"] = { texture = "image/地面/campus_canteen_floor.png", tileSize = 40 }, }
(b)运行时地图scripts/页面/校园地图.lua
lua
local FLOOR_STYLE_TEXTURES = { ["木地板"] = { texture = "image/地面/木地板_无缝.png", tileSize = 40 }, ["草地"] = { texture = SCHOOL_BACKGROUND_IMAGE, tileSize = 64 }, ["水泥地"] = { texture = "image/地面/campus_canteen_floor.png", tileSize = 40 }, -- ... 其余同编辑器目录,全部 40 }
(c)功能空间注册表scripts/数据/地图/功能空间类型注册表.lua
lua
-- 每个房间类型的 floorTileSize 默认值 { type = "教室", floorTileSize = 40, ... }, -- 原 256 { type = "厕所", floorTileSize = 40, ... }, { type = "食堂", floorTileSize = 40, ... }, { type = "操场", floorTileSize = 64, ... }, -- ★ 草地用 64,不是 40
(d)编辑器 fallbackscripts/页面/地图编辑模式.lua
lua
local floorTileSize = floorStyleCfg.tileSize or roomTypeConfig.floorTileSize or 40 -- ★ 原 256
tileSize 计算依据
源图512×512 内可见元素tileSize=40 时每元素像素对比小人 ~15px
深色木地板12 横板40/12 ≈ 3.3px小人的 1/5
浅色木地板8 竖板40/8 = 5px小人的 1/3
灰色地砖8×8 方格40/8 = 5px小人的 1/3
草地花丛4×4 簇64/4 = 16px≈ 小人身高
horizontal linehorizontal line

3. 渲染优先级反转 — config 覆盖旧存档(v0.10.97)

根因:v0.10.96 只改了配置值,但渲染代码用 saved_value or config_value 取 tileSize。旧存档保存了 tileSize=256,优先级高于新 config 值 40,所以改了配置也不生效。
修复 4 处,全部改为 config only
(a)编辑器房间渲染scripts/页面/地图编辑模式.lua
lua
-- ❌ 旧:room.floorTileSize 优先(旧存档=256,覆盖 config=40) local floorTileSize = room.floorTileSize or roomTypeConfig.floorTileSize or 40 -- ✅ 新:config 优先 local floorStyleCfg = GetFloorStyleConfig(room.floorStyle) local floorTileSize = floorStyleCfg.tileSize or roomTypeConfig.floorTileSize or 40
(b)编辑器地面区域scripts/页面/地图编辑/地面区域编辑.lua
lua
-- ❌ 旧 tileSize = area.tileSize or styleConfig.tileSize, -- ✅ 新:直接用 config,忽略存档 tileSize = styleConfig.tileSize,
(c)运行时房间scripts/页面/校园地图.lua
lua
-- ❌ 旧 tileSize = room.floorTileSize or floorStyle.tileSize, -- ✅ 新 tileSize = floorStyle.tileSize,
(d)运行时地面区域scripts/页面/校园地图.lua
lua
-- ❌ 旧 tileSize = area.tileSize or floorTexture.tileSize, -- ✅ 新 tileSize = floorTexture.tileSize,
horizontal linehorizontal line

三、经验提炼

编号教训适用场景
E1弹窗选择项应统一关闭弹窗,不要对个别项做特判。新类型加入时不需要额外维护所有"选择后进入操作模式"的弹窗交互
E2tileSize 计算先看源图像素和内容密度,再用"目标单元素像素 = tileSize / 源图可见元素数"反推任何 TiledImage/纹理平铺场景
E3视觉参数(tileSize 等)应以 config 为唯一真相源,渲染代码不应读存档缓存值。存档里的值只用于数据迁移,不用于渲染任何"config 改了但旧数据不生效"的问题
E4多处同源配置必须同步修改(编辑器目录 + 运行时地图 + 注册表 + fallback),漏改一处就会出现编辑器和运行时不一致所有跨模块共享的配置常量

四、改动文件清单

文件v0.10.94v0.10.96v0.10.97
页面/地图编辑模式.luaSelectPaletteItem 关闭弹窗fallback 256→40房间 tileSize config 优先
页面/地图编辑/编辑器目录.luaFLOOR_STYLE_CONFIGS 全部改值
页面/地图编辑/地面区域编辑.luaCreateAreaWidget config 优先
页面/校园地图.luaFLOOR_STYLE_TEXTURES 全部改值房间+地面区域 config 优先
数据/地图/功能空间类型注册表.luafloorTileSize 全部改值
穿透层修复
经验一:CSS transform 穿透层修复模式 问题本质 当容器使用 CSS transform: translateX/Y/scale 平移/缩放子树时,即使父容器有 overflow = "hidden",引擎的命中检测可能不裁剪越界区域。如果 transform 后的子树有更高的 zIndex,它会在视觉范围外拦截其他兄弟节点的指针事件。 受影响的场景 地图编辑器(右键平移/滚轮缩放后)
官方
4 赞
地图编辑器仿真 tick 重建抑制
UI 重建频率 = 事件分发的可靠性上限。 只要有一帧 SetRoot 销毁了正在处理 pointer 事件的控件,跨重建边界的 Down/Up 对就会被吞。高频仿真 tick 必须在 UI 边界按页面过滤。 关键代码(scripts/main.lua HandleUpdate) 四步走:先原地处理人员 → 聚合所有仿真 changed → 地图页强制压制 → 只放行显式/登录态变化。 -- ma
官方
4 赞
槽位变更只走原子方法
经验 下标 = 视觉格子,空槽是合法状态。定长 9 槽,inventory[i]=nil 即第 i 格空着,中间允许空。任何"把物品往前挪/压缩/重排"的操作都会让"你看到的格子"和"数组真实下标"脱节 → 物品消失。渲染直映 inventory[i],数据层绝不重排。 稀疏表禁用 #。带 nil 洞的表 #inv 是未定义的(可能=0 直接读成空包,或=洞前边界)。所有遍历上界一律 Player
官方
4 赞
地面样式配置归一化
1. 唯一真相源 scripts/数据/地图/地面样式配置.lua local FloorStyleConfig = {} -- ★ 所有地面样式集中定义在这里 FloorStyleConfig.STYLES = { ["木地板"] = { texture = "image/地面/木地板_无缝.png", tileSize = 40 }, ["草地"] = { texture = "imag
官方
4 赞
自动寻路赠送
核心功能 携带模式(点击物品跟鼠标)下: ≤8格:点击小人直接赠送(金色边框) >8格:点击远距离小人 → 自动寻路走向目标 → 到达8格内自动赠送 取消:玩家按方向键/WASD/摇杆手动移动 → 立即取消,恢复物品 关键经验(3条踩坑教训) 经验1:类型标识不是中文,是英文枚举值 地图编辑器放置的角色 type/job 字段是英文标识(teacher_3、doctor、cleaner_2、tea
官方
1 赞
拾取 / 丢弃物品
拾取的坑是「点击被遮挡」,丢弃的坑是「坐标反解会偏」。两者解法都是绕开复杂机制、用最直接的方式。 问题 根因 解法 走到物品旁点不动、捡不起来 物品命中层和主角标记同层、都无 zIndex,数组顺序靠后的主角标记盖在上面,点击命中的是主角而非物品 给可交互物品显式 zIndex = 20 拖拽丢东西飞到远处 用 ScreenToWorld 把鼠标像素反解成世界坐标当落点,依赖 zoom/offse
官方
4 赞
右键拖拽平移
一、问题本质 不是平移公式写错,而是 UrhoX UI 库指针事件派发的两个不对称陷阱叠加: 陷阱 现象 根因文件 OnPointerMove 不向父冒泡 右键按下 isPanning_=true,但 move 事件永远到不了 mapView urhox-libs/UI/Core/Widget.lua(OnPointerDown/Up 有 parent 冒泡,OnPointerMove 没有) H
官方
4 赞
修复"地图编辑器刷新数据丢失"
问题诊断过程 用户报告:编辑器建好房间 → 保存 → 刷新页面 → 进编辑器 → 数据全没了。 关键线索:用户发现"校园日"模式刷新后能看到房间,但一进编辑器就没了。 这直接指向了编辑器页面自身的初始化逻辑,而非持久化链路。 根因 地图编辑模式.lua 的 EnsureBlankEditorLayout() 设计意图是"首次打开编辑器提供空白画布",用模块级布尔 editorLayoutClear
官方
4 赞
以鼠标为锚点缩放
核心数学原理 缩放前后,鼠标指向的那个世界坐标点必须保持在同一屏幕位置。 已知:旧缩放 oldZoom、新缩放 newZoom、鼠标锚点屏幕坐标 (ax, ay)、当前偏移 (panX, panY) 步骤1:算出旧缩放下鼠标指向的世界坐标 wx = (ax - panX) / oldZoom wy = (ay - panY) / oldZoom 步骤2:新缩放后反解新偏移,让 wx/wy
官方
1 赞
图片加载三层优化设计
目标场景:地图编辑器"物品/墙体/地面/房间/人员"调色板弹窗的图片首帧显示 文档目的:沉淀"图片为什么慢、怎么治、发布后玩家体验如何、未来加资源时 preload_groups 怎么取舍"的完整结论,避免重复踩坑。 一句话结论 WASM 下图片"慢"不是单一问题,而是下载 / 解码 / 上传 GPU 三件事全堆在"玩家点弹窗那一刻"做导致的。优化的本质是把这三件事提前到启动期做(让玩家点的时候图
官方
1 赞