battleManager模块化重构
本文最后更新于13 天前,其中的信息可能已经过时,如有错误请发送邮件到big_fw@foxmail.com

重构前:一个什么都管的“总导演”

在重构之前,位于 early_battle/ 目录下的 battle_manager.gd 脚本几乎承担了战斗系统的所有职责。我们可以称它为一个“上帝对象” (God Object),因为它什么都想管:

  • 角色管理: 它自己维护着 player_charactersenemy_characters 两个数组,负责添加和移除角色。
  • 回合管理: 它自己维护着 turn_queue 回合队列,并通过 _build_turn_queue 函数来根据速度排序,决定谁先行动。
  • 状态管理: 它通过一个庞大的 _on_state_changed 函数来控制战斗的每一个阶段(回合开始、玩家行动、敌人行动、回合结束等)。
  • 规则判断: 它用 check_battle_end_condition 函数来判断战斗的胜负。
  • 视觉表现: 它包含了大量的 _play_*_effect 函数,直接通过 Tween 来实现角色抖动、变色等视觉效果。

这样做的问题很明显:
所有逻辑都耦合在一个文件里,当你想修改其中任何一个功能时(比如改变回合排序规则,或者调整一个技能的视觉效果),你都必须在这个几百行的庞大文件中找到对应的代码,并且要非常小心,以免不经意间破坏了其他逻辑。这使得代码难以维护和扩展。


重构后:一个“总导演” + 多个“专业导演”

重构后,新的 battle/ 目录引入了“模块化”思想。原来的 BattleManager 被拆分,其核心职责被分配给了几个新的、高度专注的管理器(Manager)脚本。

下面我们来看看这些新的“专业导演”各自负责什么:

1. BattleCharacterRegistryManager.gd (角色注册管理器)

  • 核心职责: 管理所有参与战斗的角色
  • 接管了什么: 它完全接管了旧 BattleManager 中对 player_charactersenemy_characters 数组的管理。
  • 如何工作:
    • 现在,当一个角色加入或离开战斗时,不再是直接操作 BattleManager 的数组,而是调用这个管理器的 register_characterunregister_character 方法。
    • 它成为了战斗中所有角色的“户籍中心”,提供了如 get_player_team, get_enemy_team, is_team_defeated 等方便查询的方法。
    • 新的 BattleManager 不再关心角色具体是怎么存储的,它只需要向这个管理器查询:“把所有活着的敌人给我”或者“判断一下A和B是不是敌人”。

2. TurnOrderManager.gd (回合顺序管理器)

  • 核心职责: 决定谁在什么时候行动
  • 接管了什么: 接管了旧 BattleManager 中的 turn_queue_build_turn_queue 的逻辑。
  • 如何工作:
    • 它的唯一任务就是维护回合队列。当一个大回合开始时,BattleManager 会命令它 build_queue()
    • 当需要下一个行动者时,BattleManager 会向它调用 get_next_character()
    • 所有关于回合顺序的逻辑(比如按速度排序,或者未来可能加入的“插队”机制)都将在这里实现,与战斗的其他部分完全隔离。

3. CombatRuleManager.gd (战斗规则管理器)

  • 核心职责: 判断战斗的胜负
  • 接管了什么: 接管了旧 BattleManager 中的 check_battle_end_condition 逻辑。
  • 如何工作:
    • 它的职责就是定义“怎样算赢?”和“怎样算输?”。
    • 它通过查询 BattleCharacterRegistryManager 来了解队伍的存活情况,然后根据规则(例如,一方全部阵亡)来判断战斗是否结束。
    • 如果未来要增加新的胜利或失败条件(比如“超过20回合算失败”),你只需要修改这个文件,而不用动 BattleManager

4. BattleVisualEffects.gd (战斗视觉效果管理器)

  • 核心职责: 处理所有的视觉和听觉表现
  • 接管了什么: 接管了旧 BattleManager 中所有以 _play_ 开头的视觉效果函数。
  • 如何工作:
    • 它将“逻辑”和“表现”彻底分离。例如,Character 脚本在计算后得知自己受到了10点伤害(这是逻辑),然后它会通知 BattleManagerBattleManager 再命令 BattleVisualEffects 去“播放一个受击特效”并“显示一个-10的伤害数字”(这是表现)。
    • 这意味着你的战斗逻辑可以完全脱离视觉效果运行。你可以轻松地更换、升级或关闭所有视觉效果,而无需改动任何核心战斗代码。

5. BattleStateManager.gd (状态管理器)

  • 核心职责: 驱动战斗流程的状态机
  • 这个模块在重构前后变化不大,因为它本身的设计已经很好了,就是一个纯粹的状态机。它定义了战斗的各个阶段(IDLE, START, PLAYER_TURN 等),并负责在这些状态间切换。

新的 BattleManager.gd:真正的“总导演”

那么,经过重构后,新的 BattleManager.gd 变成了什么样呢?

它不再亲力亲为,而是变成了一个真正的“总导演”。它的代码现在非常简洁,读起来就像是战斗的“剧本大纲”:

  • 它持有对所有“专业导演”(各个子管理器)的引用。
  • 在它的 _on_state_changed 函数中,它不再执行具体操作,而是发出指令:
    • 当进入 ROUND_START 状态,它对 TurnOrderManager 说:“建立新的回合队列”。
    • 当进入 TURN_START 状态,它对 TurnOrderManager 说:“告诉我下一个该谁行动了”。
    • 当一个行动结束后,它问 CombatRuleManager:“战斗结束了吗?”。
    • 当一个角色受到伤害时,它对 BattleVisualEffects 说:“给他播放一个受伤动画”。

总结:重构带来的巨大优势

这次重构将一个大而全的复杂脚本拆分成了多个小而精的独立模块,最终达成了以下目的:

  1. 高内聚,低耦合: 每个模块只做一件事,并且做得很好(高内聚)。模块之间的依赖关系变得清晰,不再是乱成一团的毛线球(低耦合)。
  2. 清晰易读: 当你看到 TurnOrderManager 这个文件名时,你立刻就知道它的作用。代码的可读性大大增强。
  3. 易于维护和调试: 如果回合顺序出错了,你只需要检查 TurnOrderManager。如果视觉效果不播放,你只需要检查 BattleVisualEffects。问题定位变得非常简单。
  4. 易于扩展: 想添加新的战斗规则?修改 CombatRuleManager。想支持更酷炫的技能特效?扩展 BattleVisualEffects。添加新功能不再是噩梦。

总而言之,这次重构是一次非常成功的软件工程实践,它将一个难以维护的系统,改造成了一个清晰、灵活、可扩展的模块化系统,为你将来在这个战斗系统上添加更多复杂功能打下了坚实的基础。希望这个讲解能帮助你更清晰地了解这个战斗系统的“总导演”脚本!

文末附加内容
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇