真实项目游戏系统实战记录:羁绊派系计数系统(一)
最近正在开发一个PC游戏的羁绊计数系统和《金铲铲之战》的羁绊计数逻辑相似。玩家获得特定派系羁绊达一定数量时对应派系羁绊效果激活反之失效。本文是该系统的第一部分本文谈这些系统的功能需求基础系统骨架系统逻辑流程处理计数变化并将变化通知到业务脚本相关实战代码文章目录1. 基础支持计数的储存和变化检测2. 计数变化状态的更新计数效果的开启和关闭小结这个系统要实现这些功能计数效果的激活、失活计数文本状态的更新激活的为亮色未激活的为暗色计数效果的阈值节点动态更新派系图标的显示实际已获得的计数数量显示鼠标悬浮Tips文本显示以上效果对每个玩家各自独立运行这个系统所处的上下文环境多人游戏单局制实时战斗基于这些条件我们逐步整理思路。1. 基础支持计数的储存和变化检测首先根据已有的需求我们确定这个系统是一个客户端系统只需要全程在客户端进行处理。同时这个系统是每个玩家数据各自独立的因此该系统必须持有玩家状态的引用。计数存到哪里我们要开发一个能对比计数变化并动态反应的系统自然涉及到计数数据的储存。数据变化时要确保系统能识别到变化。我们需要两处数据储存位置玩家状态数据未经过处理的计数状态外部的脚本和游戏内的互动均直接操作玩家状态数据。系统内部状态数据已经经过变化处理的计数状态。计数变化的更新方式我们必须能够在游戏过程中动态检测流派计数的实时状态这天然地有两种方案任意计数变化时立即处理变化周期间隔时间处理变化在我当前负责的这个项目中游戏不需要特别实时的羁绊计数更新频率在这里我可以采用方案2直接给定一个计时器每1秒获取一次羁绊计数对比缓存中的计数后处理变化。综上我们已经确定数据怎样储存怎样检测变化。现在我们可以着手整理系统的基本骨架。骨架流程我们按照系统需求整理出基本的逻辑流程。骨架脚本-- 流派羁绊系统---class FBS : ObjectlocalFBSoop.class()---注册系统functionFBS:__init(plr)self._plrplrend---初始化系统functionFBS:setup()---流派计数缓存---type { [string]: integer }self._bonds{}-- 创建每1秒计时器self._updaterTimer.StartLoop(1,function()self:update()end)end---获取羁绊计数缓存值functionFBS:get_bond(key)returnself._bonds[key]or0end---设置羁绊计数缓存值functionFBS:set_bond(key,value)self._bonds[key]valueend---检测到羁绊计数变化functionFBS:on_bond_change(key,new_val)localold_valself:get_bond(key)localdeltanew_val-old_val--TODO ... 处理变化传播逻辑-- 更新缓存self:set_bond(key,new_val)end---检测一次变化functionFBS:update()localplr_bondsself._plr:get_bonds()-- 假设玩家类存在该方法获取实时计数状态fork,vinpairs(plr_bonds)doifself:get_bond(k)~vthenself:on_bond_change(k,v)endendend---注销系统functionFBS:remove()self._updater:remove()self._updaternilself._bondsnilself._plrnilend2. 计数变化状态的更新计数效果的开启和关闭在上1节中我们已经搭建好了检测变化的系统骨架现在我们的系统已经具备了获取计数变化并更新缓存的能力。为了让系统能真正影响游戏逻辑效果我们还需要这个系统能够和游戏脚本交互。假设我们有这样的游戏脚本逻辑-- 剑修-2每1秒增加1点攻击力GameScript.Bond[剑修-2]{-- 开启效果on_openfunction(plr,ctx)ctx.timerTimer.StartLoop(1,function()plr:setAttr(攻击力,plr:getAttr(攻击力)1)end)end,-- 关闭效果on_closefunction(plr,ctx)ctx.timer:remove()end,}GameScript.Bond[剑修-4]...GameScript.Bond[剑修-6]...GameScript.Bond[剑修-8]...现在我们需要通过我们的羁绊计数系统对其进行管理实现上1节中未完成的部分。我们需要预设各流派的激活节点并在计数变化时进行一次状态更新并调用相关的脚本。FBS.ActivatePoints{[剑修]{2,4,6,8}}functionFBS:setup()-- ... 原有代码---各节点激活状态---type { [string]: { [integer]: boolean? } }self._activate_states{}end---动态为 activate_states 分配必要的子项functionFBS:protect_activate_state(key,point)-- 确保只处理被注册了解锁节点的部分ifnottable.find(FBS.ActivatePoints[key],point)thenreturnfalseendifnotself._activate_states[key]thenself._activate_states[key]{}endreturntrueend---设置羁绊计数节点的解锁状态缓存functionFBS:set_activate_state(key,point,new_state)ifnotself:protect_activate_state(key,point)thenreturnendself._activate_states[key][point]new_stateend---处理羁绊计数节点的解锁状态functionFBS:process_activate_state(key,point,new_state)ifnotself:protect_activate_state(key,point)thenreturnendlocalold_stateself._activate_states[key][point]ifold_statenew_statethenreturnendself._activate_states[key][point]new_state self:call_script(key,point,new_statetrueandon_openoron_close)end---调用羁绊计数效果脚本functionFBS:call_script(key,point,method_name)localscript_keystring.format(%s-%s,key,point)localscript_bodyGameScript.Bond[script_key]ifscript_bodythenlocalmethodscript_body[method_name]ifmethodthen---假设存在一个方法用于通过唯一string KEY获取一个table用于bond脚本储存临时数据---type tablelocalctxself._plr:get_ctx(FBS-..script_key)method(self._plr,ctx)-- 如果调用的是失活逻辑运行完脚本后回收上下文表ifmethod_nameon_closethenself._plr:remove_ctx(FBS-..script_key)endendendend---检测到羁绊计数变化functionFBS:on_bond_change(key,new_val)localold_valself:get_bond(key)localdeltanew_val-old_val-- 处理变化传播逻辑逐节点处理localdire1ifnew_valold_valthendire-1endforiold_val,new_val,diredoself:process_activate_state(key,i,dire1)end-- 更新缓存self:set_bond(key,new_val)end小结数据部分我们是如何处理的我们将玩家的实时数据直接储存到玩家状态本身这个状态属于外部。我们在系统内周期性检测外部状态变化并更新我们系统内部的状态。我们如何处理计数节点状态我们使用self._activate_states以KEY 节点的方式储存每一个流派的每一个计数节点的开启/关闭状态。在发现数据变化时我们通过检查缓存中的节点状态确认某个节点是否产生变化。以此确保我们只响应产生变化的部分无变化的部分则跳过逻辑。我们如何设计业务脚本羁绊效果的业务脚本本质上是一系列开关脚本。我们在对应节点进入开启状态时调用on_open逻辑。而在进入关闭状态时我们调用on_close逻辑。后续谈什么在第二部分中我们会讨论如何让这个系统和UI交互确保能够正确渲染UI文本和Tips相关数据。

相关新闻

基于ddddocr与BurpSuite的验证码自动化识别与绕过实战

基于ddddocr与BurpSuite的验证码自动化识别与绕过实战

1. 项目概述与核心价值 在渗透测试和Web应用安全评估中,登录、注册、找回密码等关键功能点前的验证码,常常是自动化攻击(如暴力破解、撞库)的主要防线。传统的BurpSuite Intruder模块虽然功能强大,但在面对图形验证码时…

2026/10/2 11:14:18 阅读更多 →
Prompt Engineering与Context Engineering:AI后端架构中的核心差异与协同实践

Prompt Engineering与Context Engineering:AI后端架构中的核心差异与协同实践

如果你正在准备2026年的大厂AI后端面试,或者正在设计一个基于大模型的智能应用,那么“Prompt Engineering”和“Context Engineering”这两个词一定高频出现。很多人以为它们只是“写提示词”和“管理上下文”的文字游戏,甚至觉得后者只是前者…

2026/10/10 22:32:08 阅读更多 →
每日财经知识:博格公式选股——一个公式,筛出能长期持有的好公司(基于:TuShare API)

每日财经知识:博格公式选股——一个公式,筛出能长期持有的好公司(基于:TuShare API)

原创 | 来自北方狼 StockStudy园地 | 2026年8月5日 17:41 重庆前置说明:如需要下载本文代码(共有 360M 左右,基础数据),请大家关注微信公众号:“StockStudy园地” 后台回复: 回复:基…

2026/10/8 4:57:00 阅读更多 →

最新新闻

安装谷歌浏览器

安装谷歌浏览器

安装谷歌浏览器 在众多电脑软件中浏览器应该是每台电脑的必备软件,如何选择浏览器,选择哪一款浏览器对于好多电脑小白来说可能不是那么在意,但事实上有一款合适的浏览器是相当重要的。 曾经我看过一个人的电脑,着实让我有些发疯&a…

2026/10/11 4:00:55 阅读更多 →
Golang 中数组和切片的区别?

Golang 中数组和切片的区别?

在 Go 语言的开发与技术面试中,“数组(Array)和切片(Slice)的区别”是一个被提及频率极高的高频问题。许多刚从 C/C、Java 或 Python 转到 Go 的开发者往往会产生认知偏差:C/C 开发者习惯了将“数组名作为指…

2026/10/11 4:00:55 阅读更多 →
STM32CubeMx开发之路—10使用IIC读写24C02

STM32CubeMx开发之路—10使用IIC读写24C02

STM32CubeMx开发之路—10使用IIC读写24C02 附件 源码仓库: 码云仓库 运行环境 Windows10STM32CubeMX Version 5.2.0Keil5(MDK5) Version 5.28.0.0 简介 本例程主要讲解如何使用硬件IIC读写24C02 STM32CubeMx基本配置 基础配置过程请参考 STM32CubeMx(Keil5)开发之路—配置第…

2026/10/11 4:00:55 阅读更多 →
为什么连接器太多会挤占上下文窗口

为什么连接器太多会挤占上下文窗口

摘要本文围绕智能创作助手在信息检索与内容生成中的应用展开,重点探讨如何基于用户意图和搜索词,通过网络检索整合有效信息,生成结构清晰、逻辑严谨且具备实用价值的文本。内容涵盖从关键词提取到多源信息融合的全流程处理机制,强…

2026/10/11 4:00:55 阅读更多 →
STM32CubeMx开发之路—12使用ADC和DAC

STM32CubeMx开发之路—12使用ADC和DAC

STM32CubeMx开发之路 — 使用ADC和DAC 运行环境 Windows10STM32CubeMX Version 5.2.0Keil5(MDK5) Version 5.28.0.0芯片 STM32F103ZE 简介 本例程主要讲解如何使用ADC和DAC STM32CubeMx基本配置 基础配置过程请参考 STM32CubeMx(Keil5)开发之路—配置第一个项目 CubeMX配置 …

2026/10/11 4:00:55 阅读更多 →
RT-Thread—STM32—EasyFlash

RT-Thread—STM32—EasyFlash

RT-Thread—STM32—EasyFlash 概述 本教程主要根据官方推荐的教程进行改编,详细信息请参考EasyFlash软件包 本例程的模板使用通用模板环境搭建里面的模板 RT-Thread——STM32——FAL库 示例工程请参见文末的源码仓库链接, 建议从头开始移植, 加深印象。 配置 打开工…

2026/10/11 3:59:54 阅读更多 →

日新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 5:23:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 21:32:20 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 10:38:42 阅读更多 →