下载 App

竞拍系统

05/158 浏览
现在我已经完全了解了整个竞拍链路。来梳理改造方案:
当前问题:ServerAuction 是"即时成交"模式——出价后立即扣款、直接转移所有权。用户希望改为"出价竞拍"模式:出价扣款,记录最高出价,显示当前最高出价者和金额。
改造计划:
服务端:记录每栋建筑的最高出价(内存 + 广播),出价时扣款,如果被超过则退回前一个最高出价者的钱,超过才成交转所有权
广播:AUCTION_STATUS 广播当前最高出价信息(userId + amount + nickname 用 userId 代替,客户端用 BuildingOwnerHelper 去查昵称)
客户端:三个弹窗显示当前最高出价信息
竞拍系统的完整改造已全部完成并构建通过。以下是本轮实现的内容总结:
服务端 (ServerAuction.lua) — 之前已完成:
竞价模式:玩家出价时立即扣除现金,记录到 auctionRecords
超价退款:有人出更高价时,自动退还前一位最高出价者的现金
广播机制:每次竞价变动后向所有在线玩家广播最高出价信息
客户端三个弹窗 (BankModal / TavernModal / Marketplace) — 本轮完成:
添加了 OnBidResult 回调:显示竞拍操作结果(成功/失败消息)
添加了 OnAuctionStatus 回调:实时更新"最高出价: X 元 (玩家昵称)"
通过 BuildingOwnerHelper.FetchNickname 异步解析玩家 ID 为昵称
main.lua — 本轮完成:
OnBidResult 和 OnAuctionStatus 回调统一转发到三个弹窗
竞拍广播同时触发地图重绘(gameMapData.dirty = true)
可以进入游戏测试竞拍功能了。打开任意无主建筑弹窗,输入出价金额后点击竞拍,应该能看到现金被扣除,并显示当前最高出价者信息。
24 小时竞拍超时机制 - 改动汇总
服务端 (ServerAuction.lua)
竞拍不再即时转移所有权,改为挂起模式
每次出价记录 lastBidTime 和 deadline(= 出价时间 + 24h)
新增 ServerAuction.Update(dt) —— 每 30 秒扫描一次到期竞拍
到期后调用 finalizeAuction() 自动将所有权转给最高出价者,持久化到云端并广播
服务端入口 (Server.lua)
新增 SubscribeToEvent("Update", "HandleServerUpdate"),驱动竞拍定时检查
客户端三个弹窗 (BankModal / TavernModal / Marketplace)
updateBidStatus() 新增 deadline 参数
收到竞拍广播时,根据 deadline - os.time() 计算剩余时间,显示格式:最高出价: 500 元 (玩家昵称) | 剩余 23:45:30
竞拍结束后显示 | 已截止
数据流
出价 → 服务端扣款 → auctionRecords[deadline] → 广播 deadline 给所有客户端
                                                 ↓
                                          客户端显示倒计时
                                                 ↓
                         24h 无人加价 → finalizeAuction → 转移所有权
确认问题根源:
ServerAuction 读写 player_stats 的 stats.asset(该字段 = cash + deposit,且仅在银行操作后才同步)
ServerBank 真实现金存在 bank_account 的 acct.cash(唯一信源)
玩家如果没执行过银行操作,player_stats.asset 可能为 0,导致竞拍提示"当前 0"
现在修复 ServerAuction.lua,改为读写 bank_account.cash,并在扣款/退款后同步 player_stats。
修复内容总结:
问题根因:竞拍系统(ServerAuction)读写的是 player_stats.asset(派生字段,= cash + deposit,仅在银行操作后才同步),而玩家真实现金存储在 bank_account.cash。新玩家或未执行过银行操作的玩家,player_stats.asset 为 0,导致竞拍报"现金不足(当前 0)"。
修复内容(ServerAuction.lua):
HandleBidBuilding 扣款:从 serverCloud:Get(userId, "stats") → 改为 serverCloud:Get(userId, S.BANK_ACCOUNT_KEY),读取 acct.cash 判断余额、扣款后写回 bank_account
refundPlayer 退款:同样改为读写 bank_account.cash
新增 syncStatsAfterAuction:扣款/退款后同步 player_stats.asset = cash + deposit,并推送 STATS_LOADED 给客户端,保持 UI 显示与实际数据一致
现在竞拍系统与钱庄共用同一数据源 bank_account,信道已打通。
地图编辑器仿真 tick 重建抑制
UI 重建频率 = 事件分发的可靠性上限。 只要有一帧 SetRoot 销毁了正在处理 pointer 事件的控件,跨重建边界的 Down/Up 对就会被吞。高频仿真 tick 必须在 UI 边界按页面过滤。 关键代码(scripts/main.lua HandleUpdate) 四步走:先原地处理人员 → 聚合所有仿真 changed → 地图页强制压制 → 只放行显式/登录态变化。 -- ma
官方
4 赞
穿透层修复
经验一:CSS transform 穿透层修复模式 问题本质 当容器使用 CSS transform: translateX/Y/scale 平移/缩放子树时,即使父容器有 overflow = "hidden",引擎的命中检测可能不裁剪越界区域。如果 transform 后的子树有更高的 zIndex,它会在视觉范围外拦截其他兄弟节点的指针事件。 受影响的场景 地图编辑器(右键平移/滚轮缩放后)
官方
4 赞
【日常更新】支持2人、3人、4人对战截图
【日常更新】支持2人、3人、4人对战
优化了排行榜显示玩家昵称
3 赞
以鼠标为锚点缩放
核心数学原理 缩放前后,鼠标指向的那个世界坐标点必须保持在同一屏幕位置。 已知:旧缩放 oldZoom、新缩放 newZoom、鼠标锚点屏幕坐标 (ax, ay)、当前偏移 (panX, panY) 步骤1:算出旧缩放下鼠标指向的世界坐标 wx = (ax - panX) / oldZoom wy = (ay - panY) / oldZoom 步骤2:新缩放后反解新偏移,让 wx/wy
官方
1 赞
编辑器实体 zIndex 层级
问题 编辑器中墙段被房间面板覆盖不可见。原因:给房间设 zIndex=1 会创建 stacking context,其内部带背景色/TiledImage 的 floorLayer 作为 paint layer 在合成时盖过了同层级 zIndex=2 的墙段——差距太小不够可靠。 解决:底层不设 zIndex,上层用明显间距 错误做法(zIndex 间距太小 + 给底层也设 zIndex): --
官方
1 赞
右键拖拽平移
一、问题本质 不是平移公式写错,而是 UrhoX UI 库指针事件派发的两个不对称陷阱叠加: 陷阱 现象 根因文件 OnPointerMove 不向父冒泡 右键按下 isPanning_=true,但 move 事件永远到不了 mapView urhox-libs/UI/Core/Widget.lua(OnPointerDown/Up 有 parent 冒泡,OnPointerMove 没有) H
官方
4 赞
碰撞方案
核心教训 1. 格子像素必须匹配精灵尺寸 5px格子+36px精灵=7.2:1比例,任何碰撞方案(AABB/空气墙/单点/格中心)都无法同时满足"不穿墙+四面间距一致+不跳格"。对齐环世界32px后,36px精灵≈1.1格,问题根本解决。 2. 连续渲染 + 格级碰撞的分层设计 渲染用连续坐标 x*S-18(平滑不跳),碰撞用格级检测(不穿墙),二者解耦。 3. 精灵大于格子时,单点检测必然不对称
官方
1 赞
精灵平滑移动、墙碰撞体积
一、 渲染层用连续坐标(scripts/页面/校园地图.lua,三处统一): -- NPC 定位(第408-410行) local contLeft = (character.x or 0) * 5 - 18 - charLeft local contTop = (character.y or 0) * 5 - 36 - charTop -- 主角定位(第504-506行) local con
官方
1 赞
修复"地图编辑器刷新数据丢失"
问题诊断过程 用户报告:编辑器建好房间 → 保存 → 刷新页面 → 进编辑器 → 数据全没了。 关键线索:用户发现"校园日"模式刷新后能看到房间,但一进编辑器就没了。 这直接指向了编辑器页面自身的初始化逻辑,而非持久化链路。 根因 地图编辑模式.lua 的 EnsureBlankEditorLayout() 设计意图是"首次打开编辑器提供空白画布",用模块级布尔 editorLayoutClear
官方
4 赞
自动寻路赠送
核心功能 携带模式(点击物品跟鼠标)下: ≤8格:点击小人直接赠送(金色边框) >8格:点击远距离小人 → 自动寻路走向目标 → 到达8格内自动赠送 取消:玩家按方向键/WASD/摇杆手动移动 → 立即取消,恢复物品 关键经验(3条踩坑教训) 经验1:类型标识不是中文,是英文枚举值 地图编辑器放置的角色 type/job 字段是英文标识(teacher_3、doctor、cleaner_2、tea
官方
1 赞