lua-游戏红点提示系统抽象设计

news/2025/2/27 4:47:14/

文章目录

  • 前言
  • 一、定义红点节点类型
  • 二、节点注册与管理
    • 三、状态更新与冒泡机制
  • 四、示例配置与使用
  • 五、结构示意图
  • 六、关键机制说明
  • 总结


前言

游戏开发中,红点提示系统可以通过树形结构和策略模式进行抽象,实现高扩展性。以下是基于Lua的实现方案:


一、定义红点节点类型

节点分为两种类型:

  • 叶子节点:直接绑定条件函数(如检查新道具)
  • 组合节点:自动聚合子节点状态(任一子节点激活则激活)
lua">-- ========================
-- 红点系统核心管理器
-- ========================
local RedPointManager = {-- 所有注册的红点节点,以节点ID为键nodes = {},       -- 没有父节点的根节点集合(例如HUD入口)rootNodes = {},   -- 事件监听器(扩展功能:事件触发自动更新)eventListeners = {} 
}-- ========================
-- 节点评估策略模块
-- ========================
-- 叶子节点评估方法:直接执行条件函数
local function evaluateLeaf(node)-- 当且仅当条件函数返回true时激活return node.condition and node.condition()
end-- 组合节点评估方法:检查任意子节点是否激活
local function evaluateComposite(node)for _, child in ipairs(node.children) doif child.isActive thenreturn true -- 任一子节点激活则组合节点激活endendreturn false
end

二、节点注册与管理

lua">-- ========================
-- 节点注册与管理模块
-- ========================
--- 注册一个红点节点
--- @param nodeId string 唯一节点标识(例如"WeaponTab")
--- @param parentNodeId string|nil 父节点ID(nil表示根节点)
--- @param nodeType "leaf"|"composite" 节点类型
--- @param condition function|nil 仅叶子节点需要的条件函数
function RedPointManager:RegisterNode(nodeId, parentNodeId, nodeType, condition)-- 创建节点数据结构local node = {id = nodeId,             -- 节点唯一标识parent = parentNodeId and self.nodes[parentNodeId], -- 父节点引用children = {},            -- 子节点列表(仅组合节点使用)isActive = false,         -- 当前激活状态evaluation = nodeType == "leaf" and evaluateLeaf or evaluateComposite, -- 评估策略condition = condition,    -- 条件函数(仅叶子节点)uiCallback = nil          -- UI刷新回调}-- 构建父子节点关系if node.parent then-- 将当前节点添加到父节点的子节点列表table.insert(node.parent.children, node)else-- 没有父节点时加入根节点列表table.insert(self.rootNodes, node)end-- 将节点注册到全局管理器self.nodes[nodeId] = nodereturn node
end--- 为指定节点注册UI刷新回调
--- @param nodeId string 目标节点ID
--- @param callback function 回调函数(参数:isActive)
function RedPointManager:RegisterUICallback(nodeId, callback)local node = self.nodes[nodeId]if node thennode.uiCallback = callback -- 绑定UI更新逻辑end
end

三、状态更新与冒泡机制

lua">-- ========================
-- 状态更新模块
-- ========================
--- 标记某个节点需要重新评估状态
--- @param nodeId string 需要更新的节点ID
function RedPointManager:MarkDirty(nodeId)local node = self.nodes[nodeId]if node thenself:_EvaluateNode(node) -- 立即触发评估end
end-- 内部方法:递归评估节点状态
function RedPointManager:_EvaluateNode(node)-- 执行节点对应的评估策略(叶子节点/组合节点)local newActive = node.evaluation(node)-- 仅当状态变化时触发后续操作if newActive ~= node.isActive thennode.isActive = newActive -- 更新节点状态-- 执行UI刷新回调(通知前端更新红点显示)if node.uiCallback thennode.uiCallback(node.isActive)end-- 冒泡机制:状态变化时向上更新父节点if node.parent thenself:_EvaluateNode(node.parent) -- 递归评估父节点endend
end

四、示例配置与使用

lua">-- ========================
-- 示例用法模块
-- ========================
-- 初始化红点树结构
RedPointManager:RegisterNode("HUDEntry", nil, "composite") -- 根节点
RedPointManager:RegisterNode("PropPanel", "HUDEntry", "composite") -- 二级节点
RedPointManager:RegisterNode("WeaponTab", "PropPanel", "leaf", function()-- 叶子节点的具体条件判断:玩家是否有新武器return Player.HasNewWeapons()
end)-- 绑定UI元素的红点显示逻辑
RedPointManager:RegisterUICallback("HUDEntry", function(isActive)-- 当HUD入口红点状态变化时,调用HUD系统接口HudView.SetRedDot("MainEntry", isActive)
end)RedPointManager:RegisterUICallback("WeaponTab", function(isActive)-- 武器标签红点状态变化时,更新道具界面PropView.SetWeaponTabRedDot(isActive)
end)-- ========================
-- 业务逻辑触发示例
-- ========================
-- 当玩家获得新武器时
function Player.OnNewWeaponAdded()-- 直接标记叶子节点需要重新评估RedPointManager:MarkDirty("WeaponTab")
end-- ========================
-- 扩展功能:事件驱动更新
-- ========================
--- 注册事件监听(例如:道具变化、邮件到达等)
--- @param eventType string 事件类型
--- @param nodeId string 关联的节点ID
function RedPointManager:AddEventListener(eventType, nodeId)self.eventListeners[eventType] = self.eventListeners[eventType] or {}table.insert(self.eventListeners[eventType], nodeId)
end-- 全局游戏事件处理器
function OnGameEvent(eventType, ...)local nodes = RedPointManager.eventListeners[eventType]if nodes thenfor _, nodeId in ipairs(nodes) doRedPointManager:MarkDirty(nodeId) -- 自动触发相关节点更新endend
end-- 示例:将武器标签与新武器事件绑定
RedPointManager:AddEventListener("NEW_WEAPON", "WeaponTab")

五、结构示意图

lua">HUDEntry(组合节点)
├─ PropPanel(组合节点)
│  ├─ WeaponTab(叶子节点,条件=有新武器)
│  └─ ArmorTab(叶子节点,条件=有新防具)
└─ MailPanel(组合节点)└─ SystemMail(叶子节点,条件=未读邮件)

该设计通过分层抽象,实现以下优势:

  1. 低耦合:界面层仅关注回调,逻辑层管理状态
  2. 易扩展:新增红点只需注册节点+条件
  3. 高效更新:事件驱动+冒泡机制减少无效计算
  4. 灵活策略:支持自定义条件与聚合逻辑

六、关键机制说明

  1. 树形结构管理
    • 根节点(如HUD入口)→组合节点(如道具面板)→叶子节点(如武器标签)
    • 父节点状态自动由子节点决定,无需手动维护
  2. 状态更新流程
lua">graph TD
A[玩家获得新武器] --> B(标记WeaponTab为脏)
B --> C{评估WeaponTab状态}
C -->|状态变化| D[更新武器标签UI]
D --> E{存在父节点?}
E -->|是| F[递归评估PropPanel]
F --> G{状态变化?}
G -->|是| H[更新道具面板父节点]
H --> I[继续冒泡到HUDEntry]

总结

该设计通过清晰的层级划分和事件驱动机制,使红点系统具备:
✅ 新增功能只需添加节点+条件
✅ 状态变更自动传播
✅ 界面与逻辑完全解耦
✅ 支持复杂嵌套规则(如:主界面红点=任务红点 OR 邮件红点)


http://www.ppmy.cn/news/1575175.html

相关文章

R 语言科研绘图第 27 期 --- 密度图-分组

在发表科研论文的过程中,科研绘图是必不可少的,一张好看的图形会是文章很大的加分项。 为了便于使用,本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中,获取方式: R 语言科研绘图模板 --- sciRplothttps://mp.…

【论文精读】VLM-AD:通过视觉-语言模型监督实现端到端自动驾驶

论文地址: VLM-AD: End-to-End Autonomous Driving through Vision-Language Model Supervision 摘要 人类驾驶员依赖常识推理来应对复杂多变的真实世界驾驶场景。现有的端到端(E2E)自动驾驶(AD)模型通常被优化以模仿…

Nmap网络安全审计

🍅 点击文末小卡片 ,免费获取网络安全全套资料,资料在手,涨薪更快 Nmap网络安全审计 什么是Nmap Nmap是由Gordon Lyon设计并实现的,于1997开始发布。最初设计Nmap的目的只是希望打造一款强大的端口扫描工具。但是随着…

【Http和Https区别】

概念: 一、Http协议 HTTP(超文本传输协议)是一种用于传输超媒体文档(如HTML)的应用层协议,主要用于Web浏览器和服务器之间的通信。http也是客户端和服务器之间请求与响应的标准协议,客户端通常…

Git版本控制系统---本地操作(万字详解!)

目录 git基本配置 认识工作区、暂存区、版本库 添加文件--情况一: 添加文件-情况二: 修改文件: 版本回退: git基本配置 1.初始化本地仓库,注意:一定要在一个目录下进行,一般都是新建一个文件夹,在文件…

斐波那契数列模型:在动态规划的丝绸之路上追寻斐波那契的足迹(上)

文章目录 引言递归与动态规划的对比递归解法的初探动态规划的优雅与高效自顶向下的记忆化搜索自底向上的迭代法 性能分析与比较小结 引言 斐波那契数列,这一数列如同一条无形的丝线,穿越千年时光,悄然延续其魅力。其定义简单而优美&#xff…

DeepSeek 全面分析报告

引言 DeepSeek 是一款由中国人工智能初创公司 DeepSeek 开发的大型语言模型 (LLM),于 2025 年 1 月发布,迅速成为全球人工智能领域的一匹黑马。DeepSeek 不仅在性能上可与 OpenAI、Google 等巨头的模型相媲美,而且其训练成本和运行效率都显著…

数据库课设---酒店管理系统(MySQL、VBNet)

目录 一.? ?知识技术 二.? ?需求分析 2.1? ?功能需求 2.2? ?数据需求 ?三.? ?数据流图与数据字典 3.1? ?数据流图 3.1.1? ?业务流图 3.1.2? ?数据流图 3.1.3? ?关系图 3.2? ?数据字典 四.? ?数据库设计? 4.1? ?概念模型设计 4.2? ?逻…