Files
rthythm_archor_game/README.md
T
2026-07-06 22:59:47 -07:00

34 KiB
Raw Blame History

Rthythm_archor_game

Rthythm_archor_game 是一个使用 Godot 4.6 开发的 2D 节奏横板动作游戏原型。项目核心来自《Anchor》策划方案:玩家不是用传统方向键自由移动,而是在音乐拍点窗口内输入动作,通过攻击、蓄力、技能、位移、浮空、击退、时间锚点和 Past / Future 双相位来推进战斗。

当前版本已经完成可运行的第一关战斗闭环:菜单与难度选择、第一关小怪流程、Boss 房门控、Boss 战入场、HUD、节奏条、时间锚点、攻击 Buff、玩家与敌人动作、Boss 行为、双层音乐、判定门控与输入锁定(反狂按)、Windows 打包链路、自动化回归测试都已接入。

快速开始

环境

  • 引擎:Godot 4.6.x
  • 主场景:res://scenes/main/main.tscn
  • 项目配置:project.godot
  • 默认音乐:res://assets/audio/ev_past1.mp3

在 Godot 中打开本目录后,运行主场景即可进入游戏流程。

以下命令中的 <godot> 代表 Godot 4.6.3 可执行文件路径。Windows 下请使用 Godot_v4.6.3-stable_win64_console.execonsole 包装器才能看到 stdout 输出; 它按自身文件名寻找同目录的 GUI 版,两个文件必须按原名放在同一目录)。

命令行运行单个测试示例:

<godot> --headless --path . --script tests/test_level1_spawn_flow.gd

重新导入 / 检查项目资源:

<godot> --headless --path . --import

基本操作

输入 Godot action 语义
A combo_a 左向攻击;长按后释放为左向蓄力剑雨
D combo_d 右向攻击;长按后释放为右向蓄力剑雨
W combo_w 上挑、浮空、空中动作入口
S combo_s 下砸、防御或特殊蓄力入口
Space combo_space 特殊键,内部符号为 SP
E runtime toggle_move_list 显示 / 隐藏招式表
Esc ui_cancel 游戏中暂停;暂停菜单内返回上一层

注意:

  • A / D / W / S / Space 不直接自由移动角色。每次输入先进入节奏判定,再决定是否执行动作。
  • 判定门控(2026-07-05 new1 定案,反狂按):每个节奏点只能被一次有效输入消耗。同一节奏点被消耗后的第 1 次重复按键按双击容错静默忽略(视同没按、无惩罚);第 2 次重复、或落在 BAD 窗之外的空按,判 MISS——不出招、连击清零、四拍槽写 Ø,并触发 0.5 秒输入锁定。锁定期间的按键完全无效:不判定、不留痕、也不刷新锁定时长。门控只作用于实时判定的输入(测试 / AI 的预置判定绕过)。实现见 RhythmManager.gate_judged_inputinput_lockout_seconds = 0.5consumed_repeat_grace = 1)。
  • 输入锁定若横跨时间锚点拍,该锚点必破(锁定期无法产生维持锚点的判定 → 超时 → 相位切换)。这是有意设计:失误的代价随连击档位升高而变重。
  • W + A / D 会触发带明显横向位移的空中抛物线式动作表现。
  • S 蓄力后按 Space 释放的斩波按玩家当前朝向发射:朝左即向左,不再自动瞄准最近敌人。
  • A / D 蓄力释放的剑雨落点与玩家可见脚底地面线对齐(角色锚点 y=560、可见脚底线 y=520)。
  • A / D 蓄力已进入 armed / charging 状态时按下 Space 会中断蓄力并按四拍槽派生解算(四拍槽仍保有 [A],故 [A][SP] 解算为可穿过 Boss 的冲刺斩);S 蓄力不受此规则影响。
  • 右上角没有常驻暂停按钮,暂停只通过 Esc 触发。

当前主流程

Title / DifficultySelect
-> Gameplay_FrontArea
-> 第一关小怪流程
-> 全部小怪清场
-> Boss 房路径解封
-> 玩家进入 Boss 区域
-> Boss HUD 立即显示,Boss AI 激活
-> Gameplay_BossRoom
-> Victory / Defeat / Result

难度选择由 GameFlowManager 管理,菜单贴图位于 assets/ui/menu/。难度页面点击后会保留选中态,并通过确认按钮进入游戏;返回、暂停、音量、退出确认、结算页面也在同一流程管理器中。

标题侧表现:

  • 标题、难度选择、退出确认界面持续播放节奏音乐(ev_past1.mp3,走 Music 总线,由 GameFlowManager 的常驻播放器承载,不受 SceneTree 暂停影响)。
  • 标题背景在「过去」与「现在」两张场景图之间循环交叉淡入淡出。
  • 点击开始游戏后标题音乐停止,游戏内音乐从第 0 拍重新播放(RhythmManager.start() + AudioLayerController.restart_layers())。

难度影响:

难度 判定窗口(Perfect / Good / Bad 秒) 小怪血量
简单 0.090 / 0.160 / 0.260 ×1650
普通 0.060 / 0.115 / 0.215 ×31950
困难 0.030 / 0.070 / 0.170 ×53250

判定窗口定义在 GameSettings.DIFFICULTY_WINDOWS,经 apply_judgement_windows 写入 RhythmManager

小怪血量倍率定义在 GameSettings.DIFFICULTY_MINION_HEALTH_MULTIPLIER,由 minion.gd_ready 时读取;Boss 血量不受该倍率影响。

核心玩法循环

当前战斗循环如下:

RhythmManager 推进音乐时间
-> ChartRunner 触发谱面事件与预告
-> 玩家在节奏窗口输入 A / D / W / S / Space
-> InputComponent 创建 InputIntent
-> ActionController 调用 RhythmManager 判定
-> 判定门控 gate_judged_input:锁定期 / 已消耗节奏点的按键在此被拦下
   (ok = 消耗该节奏点继续;ignored = 视同没按;miss = 记 MISS 并锁定 0.5s
-> ComboWindow 记录最近四拍输入
-> ActionResolver 根据四拍槽与角色状态选择 ActionData
-> ActionExecutor 执行动作、消耗或回复能量、打开命中窗口
-> CombatManager / Resolver 结算伤害、击退、打断、防御、受击
-> TimeAnchorSystem 根据判定事实结算时间锚点
-> UI 刷新节奏、判定、combo、Buff、血量、能量、蓄力和四拍槽

A / D 蓄力释放与 S + Space 二段施放两条蓄力路径同样经过判定门控。

时间锚点不会新增输入按键。同一次玩家输入同时服务于动作系统和锚点系统:动作系统决定是否出招,锚点系统决定是否维持当前时间相位。

第一关关卡实现

实现入口:

  • scenes/stage/stage.tscn
  • scenes/stage/stage.gd
  • scenes/stage/level_director.gd
  • scenes/stage/boss_room_gate.gd
  • scenes/enemies/minion_behavior.gd

第一关沿用参考工程的角色、Boss、背景、HUD 和相机相对大小,只调整关卡流程、出怪方式、门控和位置关系。玩家、小怪、Boss 的地面锚点统一在 y = 560

关键坐标

对象 坐标 / 范围 说明
竞技场左边界 x = 1120 小怪巡逻 / 后撤左边界
左侧增援刷新点 x = 1420 左侧入场起点
玩家出生点 (1180, 560) 2026-07-05 new2:地图偏左出生,开场向右推进遇敌
战斗中心 x = 2047 增援入场目标基准
阶段一近战怪 (2200, 560) 开局预置;玩家从左侧出生点推进约 1000px 后遭遇
右侧增援刷新点 x = 2240 右侧入场起点(与小怪右侧安全线同值)
小怪右侧安全线 x = 2240 Boss 空气墙左侧 220px;所有小怪都限制在此线左侧
Boss 空气墙 / 触发参考 gate_x = 2460 小怪不会越过该区域
Boss 初始锚点 (2520, 560) Boss 战前 combat_enabled = false
相机初始位置 (1180, 395) 跟随玩家,camera_follow_offset = (0, -165)

以上均为 stage.tscn 的实际覆盖值;level_director.gd / boss_room_gate.gd 脚本里的 export 默认值会被场景覆盖,以 tscn 为准。

LevelDirector 会根据 BossRoomGate.gate_xboss_gate_minion_clearance = 220 自动计算前场最大活动范围。动态刷新的远程怪、近战怪,以及编辑器内预置的小怪,都会统一套用这条安全边界,避免刷到空气墙右侧或相机边缘。

出怪阶段

第一关总计 6 只小怪。

阶段 触发条件 内容
阶段一 开局 预置近战怪 × 1
阶段二 击败第一只近战怪 玩家附近生成远程怪 × 1,生成点可感知但不贴脸
阶段三 击败阶段二远程怪 按 2 秒间隔生成 4 只增援:近战L、远程R、近战R、远程L
清场 击败全部 6 只小怪 解封 Boss 房路径并广播 front_area_cleared

阶段三的“右侧”增援也不会刷到空气墙右侧;运行时会被夹到前场安全线以内。

Boss 房门控

BossRoomGate 当前规则:

  • 开局 sealed = true,阻挡玩家进入 Boss 区域。
  • 小怪全灭后 LevelDirector 调用 unseal(),空气墙碰撞关闭,视觉保持透明。
  • 玩家跨过门线(x >= gate_x)的瞬间 lock() 立即触发:Boss 解锁、面板显示,不需要走到 Boss 面前。
  • lock() 只触发一次 Boss 战入场逻辑。
  • 进入 Boss 区域后空气墙不会重新显示,也不会重新启用碰撞,会完全消失。
  • Boss 入场时立即激活 Boss AI,并主动刷新 Boss HUD 绑定。
  • Boss 面板只在 Gameplay_BossRoom 显示;前场阶段隐藏,即使 Boss 已被绑定也不会提前显示。

相机在 Boss 区域未解锁时会限制右侧视野,避免提前看到 Boss 区域。

玩家系统

实现入口:

  • scenes/characters/player.tscn
  • scenes/characters/player.gd
  • scenes/components/
  • resources/actions/
  • resources/player_action_bindings.tres

玩家由组件组合而成:

  • HealthComponent:生命
  • EnergyComponent:能量
  • ChargeComponent:蓄力
  • InputComponent:输入转 intent
  • ComboWindow:四拍槽
  • ActionController:动作生命周期(含判定门控接入)
  • ActionResolver:四拍槽 + 角色状态 → ActionData 解算
  • ActionExecutor:动作效果执行
  • MotionExecutor:动作位移
  • MovementMotor:浮空、落地、击退等运动处理
  • StateMachine:地面 / 动作 / 防御 / 生死状态轴
  • DamageEmitter / DamageReceiver:攻击与受击区域
  • EffectContainerBuff / Debuff 容器
  • StreakCounter:连续成功动作计数
  • AttackBuffComponent:时间锚点攻击 Buff(含回血与受伤掉层)
  • BurstComponent:爆发动作门槛
  • FrameCollisionDriver:帧动画命中框驱动
  • ContactFxSpawner:命中接触特效
  • OverheadChargeSegments:头顶蓄力段显示
  • Visual/AttackBuffVisualVisual/FxOverlay + Visual/FxAnimationPlayerBuff 层数与 FX 贴片表现

动作由 ActionData 资源驱动,数据包含输入模式、能量、伤害倍率、水平 / 竖直位移、击退、命中类型、Startup / Active / Recovery 拍数、可取消时机、可执行状态、标签、动画名等。

当前已接入:

  • 普通左右攻击
  • 上挑与空中动作
  • 下砸
  • 防御
  • Dash / 冲刺斩
  • A / D 长按蓄力剑雨
  • S + SP 二段式蓄力
  • 四拍槽派生动作
  • 攻击命中特效与蓄力释放世界 FX
  • 强势 Buff 视觉效果,层数越多表现越明显

玩家死亡动画会保持地面线一致;死亡动画结束后尸体会消失。

小怪系统

实现入口:

  • scenes/enemies/minion.tscn
  • scenes/enemies/minion.gd
  • scenes/enemies/minion_behavior.gd
  • resources/actions/enemies/
  • resources/time_phase/profile_past_strong_enemy.tres
  • resources/time_phase/profile_future_strong_enemy.tres

小怪分近战与远程两类,并有 Past / Future 两种形态。

基础攻击力按职责区分(2026-07-05 new3 定案):近战 50、远程 25。由 LevelDirectorMinionBehavior.role 统一写入 DamageEmitter.damage(预置怪与动态刷新怪都覆盖),最终伤害仍乘相位强弱倍率。

近战怪

  • Past 形态:jin_zhan_3,强势
  • Future 形态:jin_zhan_1,弱势
  • 会巡逻、警戒、追击、按拍攻击
  • 强势相位 2 拍攻击一次,弱势相位 4 拍攻击一次
  • 距离参数(new3):警戒 360、追踪停步 120、出手距离 120、攻击判定前缘约 140(动作 range = 130)、巡逻半径 110
  • 强势相位命中会打断并击退玩家约 86px(knockback_mult_x = 2.4);弱势相位命中只掉血
  • 朝向按目标位置正确翻转,不再固定朝右 / 朝左

远程怪

  • Past 形态:yuan_cheng_1,小女孩,弱势
  • Future 形态:yuan_cheng_2,女巫,强势
  • 不巡逻,固定站位射击(站位停步 340、警戒 540)
  • 最大开火距离 450,压在相机可视半宽(约 460px)以内——刚进画面即可开火,但绝不从屏幕外攻击玩家
  • 近身后撤:玩家进入危险距离 220 持续 0.6 秒 → 向远离玩家方向退开 220px(贴墙无退路时反向跳过玩家身位);后撤结束按节拍停顿 1 拍再恢复攻击;3 秒冷却
  • 受击脱离(2026-07-05 新增):2 秒链窗内连续受击 4 次 → 0.4 秒闪烁无敌 + 跳跃形式高速脱离(3.2× 速度);3 秒冷却防连续触发。无敌通过 FrameCollisionDriver.damage_receiver_enabled 实现(直接改 Area2D 会被驱动器每帧重申覆盖)
  • 小女孩和女巫的视觉高度已对齐,两个形态都水平射击,projectile 发射高度一致(projectile_height = 86
  • 小女孩素材原生朝右(native_facing = RIGHT),镜像翻转以此为准,攻击朝向始终对准玩家

小怪形态切换时会保持脚下锚点稳定,避免动画移动过程中 y 轴突变造成视觉瞬移。

Boss 系统

实现入口:

  • scenes/enemies/boss.tscn
  • scenes/enemies/boss.gd
  • scenes/enemies/boss_behavior_tree.gd
  • resources/actions/enemies/

Boss 当前支持:

  • 近战连段
  • 远程射击
  • 二连发射击
  • Dash / retreat
  • 行为树决策
  • 谱面事件优先级
  • 受击链逃脱(1.2 秒链窗内连续受击 4 次 → 取消当前动作、boss_retreat_dash 逃脱;4 秒冷却;训练桩状态不逃脱)
  • Past / Future 招式池差异
  • 普攻恒霸体(2026-07-05 new3 定案):对不耗能量的攻击(base_cost <= 0,即玩家普通攻击)伤害照常结算,但不被打断、不被击退;只有耗能技能能压制 Boss。实现为 boss.gdshrugs_off_hit + CombatResolver 受击方钩子。项目没有韧性 / 削韧系统——策划以霸体规则替代了 new3 §6.5 的韧性方案
  • 远程(Future)相位被近身 ≤240px 时优先 boss_retreat_dash 拉开距离(后撤本身无伤害、8 拍冷却、后撤完接远程攻击)
  • 相位切换后停顿 1 拍再决策(以事件总线最后拍号为基准)
  • Boss 战前静默,进入 Boss 区域后才激活
  • Boss 血条、名称和头像 HUD

行为树距离阈值(2026-07-05 调整后):melee_distance = 180ranged_distance = 360dash_distance = 460(超过则考虑突进,4 拍冷却)、远程相位后撤触发 retreat_trigger_distance = 240;决策间隔 2 拍(Future 相位 ×0.5)。

Boss 入场规则由 BossRoomGateGameFlowManager 共同处理:玩家进入 Boss 区域后,Boss 从训练桩状态切换为可战斗状态,Boss 面板立即出现。

时间相位与时间锚点

实现入口:

  • autoload/time_phase_manager.gd
  • autoload/time_anchor_system.gd
  • resources/time_anchor_frequency_default.tres
  • resources/time_phase/
  • scenes/components/time_phase_adapter.gd
  • scenes/audio/audio_layer_controller.gd
  • scenes/ui/rhythm_track.gd

世界有两个时间相位:

past
future

TimePhaseManager 是相位唯一写入者。相位改变后通过 EventBus.time_phase_changed 广播,Stage、UI、音乐、敌人强弱、Buff 系统分别响应。

时间锚点规则:

  • 时间锚点是特殊节奏拍,不是额外按键。
  • 锚点拍内 perfect / good / bad 都能维持当前相位(锚点带 min_grade 字段可提高门槛,当前谱面均用默认 bad,即三档都维持)。
  • 锚点超时或 Miss 会切换 Past / Future。空按触发的 0.5 秒输入锁定若横跨锚点拍,该锚点必破。
  • perfect / good 成功锚定会增加 1 层攻击 Buff。
  • bad 只保持相位,不增加攻击 Buff。
  • 当前攻击 Buff 上限为 7 层;每层对 damage_mult 加算 +0.5(每层 +50% 伤害,线性叠加,7 层满层 ×4.5)。effect 资源为 resources/effects/time_phase/effect_time_anchor_attack_buff.tres
  • 每次实际相位切换时,Buff 层数减少 2,最低为 0。
  • 锚点成功会按判定质量回血:Perfect 30、Good 20、Bad 10;生命低于 50% 时回血翻倍。回血按 4 拍窗口限一次——同一窗口内第二次锚点成功只加 Buff 不回血(高连击档位下每 4 拍最多 4 个锚点,只有第一个触发回血)。
  • 受伤掉层与霸体:玩家被攻击进入受伤状态时掉落一半 Buff 层数(向下取整),每掉 1 层获得 0.5 秒霸体(SuperArmor:伤害照吃、不被打断、无击退);霸体期间不会再次进入受伤状态,因此不会连锁掉层。实现见 AttackBuffComponent + resources/effects/effect_hurt_super_armor.tres

连击数会影响时间锚点频率:

连击数 每 4 拍锚点数
0 - 7 1
8 - 15 2
16+ 4

节奏 UI 当前做过可读性强化:

  • 特殊节奏点放大,时间锚点比普通节奏点更明显。
  • 节奏点命中中心后的 flash / hit 特效放大且保留更久。
  • 锚点成功、断裂会使用不同颜色反馈。
  • 节奏点从两侧向中心的移动直接由 RhythmManager 的歌曲时间驱动(get_current_beat_progress),全程连续丝滑,到达中心的时刻与拍点严格重合。

UI 与 HUD

实现入口:

  • scenes/ui/main_ui.tscn
  • scenes/ui/main_ui.gd
  • scenes/ui/rhythm_track.tscn
  • scenes/ui/rhythm_track.gd
  • scenes/ui/combo_window_hud.tscn
  • scenes/ui/combo_window_hud.gd
  • assets/ui/

当前 HUD 包含:

  • 玩家状态栏:头像面板、HP、EN、蓄力条、蓄力等级
  • Boss 状态栏:Boss 头像、名称、血条,只在 Boss 战显示
  • 中央节奏条:左右节奏点向中心收束
  • 时间锚点:特殊节奏点纹理与放大显示
  • 判定艺术字:Perfect / Good / Bad / Miss
  • combo 计数
  • ATK Buff 读数
  • 7 格 Buff 点亮条
  • 四拍槽
  • E 键招式表
  • 调试面板,默认隐藏

HUD 由主场景绑定玩家和 Boss

Main
  -> Stage
      -> ActorsContainer
          -> Player
          -> Boss
  -> UILayer
      -> UI

Boss 面板显示条件是:

flow state == Gameplay_BossRoom
and boss_actor is valid

因此前场阶段不会提前显示 Boss 血条;进入 Boss 区域时 BossRoomGate 会主动绑定 Boss,确保 HUD 立即可见。

音频

实现入口:

  • autoload/sfx_manager.gd
  • scenes/audio/audio_layer_controller.gd
  • assets/audio/

当前音频系统包含:

  • Past / Future 双音乐层同步播放
  • 相位切换时交叉淡入淡出
  • 节奏时钟不因切相位重置
  • 标题侧节奏音乐(GameFlowManager 常驻播放器,Music 总线)
  • 开局重置:_reset_run_state()RhythmManager.start() 归零时钟后,立即调 AudioLayerController.restart_layers() 把双音轨拉回第 0 拍,不等漂移校正
  • UI、攻击、命中、锚点等事件 SFX 入口

当前 Future 层仍使用占位处理,可继续替换为正式 Future 音乐资源。

谱面与事件

实现入口:

  • resources/beat_chart.gd
  • resources/chart_track.gd
  • resources/chart_event.gd
  • resources/charts/
  • scenes/chart/chart_runner.gd

BeatChart 由多个 ChartTrack 组成,每个 track 内包含若干 ChartEvent。当前事件支持:

  • enemy_action
  • show_accent_marker
  • camera_pulse
  • time_anchor
  • force_time_phase

ChartRunner 负责按音乐时间触发事件、提前广播 upcoming 事件给 UI、根据 time_phase_mask 过滤当前相位不可触发事件,并将敌人动作事件路由到目标 Actor。

当前谱面资源包括:

  • resources/charts/stage7_boss_opening.tres
  • resources/charts/stage9_boss_duel.tres

战斗结算

实现入口:

  • autoload/combat_manager.gd
  • scripts/resolvers/stat_resolver.gd
  • scripts/resolvers/combat_resolver.gd
  • scripts/resolvers/defense_resolver.gd
  • scenes/components/damage_emitter.gd
  • scenes/components/damage_receiver.gd
  • scenes/components/effect_container.gd

战斗结算采用 resolver 管线:

  • StatResolver 计算伤害、消耗、回复、动作位移。
  • CombatResolver 处理命中结果、击退和命中上下文。
  • DefenseResolver 处理防御、格挡、减伤、打断规则。
  • CombatManager 负责一次命中事实的缓存、生命扣除、击退、打断、效果事件和 hit_confirmed 广播。

强弱与打断规则:

  • 只有强势状态小怪能打断玩家。
  • 弱势小怪攻击只结算伤害,不打断、不击退、不取消玩家动作。
  • Boss 恒定视为强势,Boss 攻击可以打断玩家(玩家霸体动作除外)。
  • 强弱状态在动作开始时快照,命中前切相位不会 retroactively 改变本次攻击。
  • 受击方霸体钩子(2026-07-05 新增):CombatResolver 结算时调用受击方的 shrugs_off_hit(action),返回 true 则本次命中的打断与击退一并取消、伤害照常。目前只有 Boss 实现该钩子(普攻恒霸体、耗能技能可压制)。
  • 击退跟随伤害判定通道:击退判定倍率走 damage 通道(perfect 1.0 / good 0.85 / bad 0.7),且仅在攻击方拥有打断权时结算——弱势攻击与被霸体消化的攻击击退为零;受击方处于 Invincible / SuperArmor 防御态时同样归零。
  • 所有耗能技能都带击退 / 击飞(dash_slash 1.5、combo_finisher 2.0、ground_smash 2.2 + 上挑、zhan_bo 1.0/1.3/1.6、jian_yu 0.8);玩家弹丸由 ActorsContainer 注入基准击退 (120, 304)

目录结构

路径 说明
addons/godot_mcp/ Godot MCP 插件
assets/audio/ 音乐与 SFX
assets/art/ground/ 地面、远景、中景背景
assets/art/characters/ 玩家、Boss、小怪素材
assets/art/effects/ 通用特效图集
assets/ui/menu/ 标题、难度、暂停、确认等菜单贴图
assets/ui/panels/ 玩家与 Boss 状态栏面板、Boss 头像
assets/ui/rhythm/ 节奏条、锚点、节奏点、中心纹理
assets/ui/buff/ Buff 点亮 / 未点亮图标
assets/ui/buff_effect/ 玩家攻击 Buff 特效帧
assets/ui/combo/ combo 数字素材
assets/ui/judgements/ Perfect / Good / Bad / Miss 判定艺术字素材
assets/ui/strong_buff/ 强势状态视觉特效
autoload/ 9 个游戏单例:事件总线、节奏、难度设置、统计、战斗、相位、锚点、音效、流程
build/windows/ Windows 打包产物(Rthythm_archor_game.exe,单文件内嵌 pck
docs/ 策划、架构、第一关设计和决策文档
resources/actions/ 玩家动作数据
resources/actions/enemies/ 敌人与 Boss 动作数据
resources/charts/ 谱面资源
resources/effects/ Buff / Debuff / 相位效果
resources/time_phase/ Past / Future 强弱 profile
scenes/audio/ 双音乐层控制
scenes/characters/ 玩家与角色基类
scenes/chart/ 谱面运行器
scenes/combat/ projectile、一次性 FX、动作解析
scenes/components/ 可复用 Actor 组件
scenes/enemies/ 小怪、Boss、行为树与 AI
scenes/ground/ 地面与背景场景
scenes/main/ 主场景入口
scenes/stage/ 关卡、相机、门控、出怪导演、projectile 生成
scenes/ui/ HUD、节奏条、能量条、四拍槽
scripts/resolvers/ 战斗、数值、防御、动作规则 resolver
tests/ SceneTree 自动化测试(66 个)
tools/ 内容导出、谱面验证和模拟工具
export_presets.cfg "Windows Desktop" 导出预设(x86_64 / embed_pck 单 exe

自动化测试

项目包含 66 个 Godot SceneTree 测试,覆盖:

  • 架构迁移契约
  • 输入 intent 与节奏判定 payload
  • 判定门控与输入锁定(节奏点一次性消耗、双击容错、MISS + 0.5s 锁定)
  • 动作控制、四拍槽、蓄力、能量
  • 战斗 resolver、Effect、强弱打断规则
  • new3 怪物 / Boss 行为规则(Boss 霸体、按职责基础攻击、远程怪受击脱离)
  • 玩家场景、动画节奏、死亡表现、剑雨落点
  • 小怪节拍、朝向、远程射击、高度、行为状态机
  • 第一关出怪流程与 Boss 房门控
  • Boss 行为、Boss HUD、Boss projectile
  • 菜单、难度选择、暂停、GameFlow
  • 时间相位、时间锚点、攻击 Buff
  • HUD 布局、节奏条、E 键招式表、UI 动画回归

常用回归命令(<godot> 见「快速开始」):

<godot> --headless --path . --script tests/test_input_gate.gd
<godot> --headless --path . --script tests/test_new3_enemy_rules.gd
<godot> --headless --path . --script tests/test_level1_spawn_flow.gd
<godot> --headless --path . --script tests/test_boss_room_gate.gd
<godot> --headless --path . --script tests/test_boss_room_entry_hud_and_wall.gd
<godot> --headless --path . --script tests/test_minion_behavior_states.gd
<godot> --headless --path . --script tests/test_minion_cadence_and_facing.gd
<godot> --headless --path . --script tests/test_player2_fx_and_witch_projectile.gd
<godot> --headless --path . --script tests/test_rhythm_feedback_and_move_list.gd
<godot> --headless --path . --script tests/test_phase9_boss_health_ui.gd
<godot> --headless --path . --script tests/test_title_music_and_background.gd
<godot> --headless --path . --script tests/test_difficulty_minion_health.gd
<godot> --headless --path . --script tests/test_hurt_buff_drop_and_super_armor.gd
<godot> --headless --path . --script tests/test_blade_rain_alignment.gd

也可以串行跑一组关键回归:

GODOT=<godot 可执行文件路径>
for test_file in \
  tests/test_input_gate.gd \
  tests/test_new3_enemy_rules.gd \
  tests/test_game_flow.gd \
  tests/test_level1_spawn_flow.gd \
  tests/test_boss_room_gate.gd \
  tests/test_boss_room_entry_hud_and_wall.gd \
  tests/test_minion_behavior_states.gd \
  tests/test_level1_melee_contact.gd \
  tests/test_boss_integration.gd \
  tests/test_minion_phase_system.gd \
  tests/test_main_ui_camera_canvas.gd \
  tests/test_phase9_boss_health_ui.gd \
  tests/test_rhythm_ui_layout.gd \
  tests/test_x1_visual_baseline.gd \
  tests/test_player_combo_input.gd \
  tests/test_combo_hud.gd \
  tests/test_blade_rain_alignment.gd
do
  "$GODOT" --headless --path . --script "$test_file" || exit $?
done

已知存量失败:test_stage4_player_scene(期望旧版 2 倍 Visual 缩放的历史基线,与当前实现无关,排查回归时可忽略)。

部分测试在加载资源时可能打印 Godot 的 UID fallback 或 MCP port warning;如果最终输出 PASS ... 且退出码为 0,则测试通过。

设计文档

文档 说明
docs/AnchorV1.0.md 核心策划方案
docs/Level1Design.md 第一关关卡与小怪行为设计
docs/new1.md 策划需求:节奏输入有效范围(判定门控)
docs/new2.md 策划需求:标题固定与出生点左移
docs/new3.md 策划需求:怪物与 Boss 行为设定
docs/decisions.md 迁移、调试、玩法手感和技术决策日志

注意:new1.md / new3.md 的原文与最终实现有出入(例如 new1 的"零代价无效输入"被改为"MISS + 锁定"、new3 的韧性系统被霸体规则替代、720 射程被否决)——最终口径以 docs/decisions.md 顶部的 "2026-07-05 new1/new2/new3 需求落地" 条目为准。

打包与发布

项目已具备完整的 Windows 打包链路:

  • 导出预设:export_presets.cfg(已入库)——预设名 "Windows Desktop"x86_64embed_pck = true(单 exe 内嵌资源包)。
  • 产物路径:build/windows/Rthythm_archor_game.exe(约 143MB)。
  • 前提:Godot 4.6.3-stable 导出模板需安装在 %APPDATA%\Godot\export_templates\4.6.3.stable\(目录名必须精确匹配引擎版本号去掉 .official.<hash> 后缀;升级引擎版本时需换用对应版本的模板包)。

重新打包只需两条命令:

<godot> --headless --path . --import
<godot> --headless --path . --export-release "Windows Desktop" "build/windows/Rthythm_archor_game.exe"

打包注意事项:导出包内 DirAccess 列出的资源名带 .remap / .import 后缀,运行时扫描 res:// 的代码必须去后缀还原原名再 load() 并去重(action_resolver.gd 等三处已按此模式修复);新增运行时扫描代码时务必遵守,更稳的做法是预加载资源列表。

Godot MCP

项目包含 Godot MCP 插件:

  • addons/godot_mcp/
  • project.godot 中已启用插件
  • Autoload 注册了 MCPScreenshotMCPInputServiceMCPGameInspector

这允许外部工具对 Godot 运行场景进行截图、输入模拟、节点检查和自动化测试。命令行 headless import 时如果已有其他项目占用 MCP 端口,可能出现 project mismatch warning;通常不影响导入或测试结果。

当前实现状态

已实现:

  • 标题、难度选择、暂停、确认、胜负和结算流程
  • 第一关 6 小怪流程与 Boss 房解锁
  • 玩家从地图偏左出生(x=1180),开场向右推进遇敌(2026-07-05 new2
  • 判定门控与输入锁定:节奏点一次性消耗、双击容错、空按 MISS + 0.5 秒锁定(2026-07-05 new1 定案)
  • 小怪全部限制在 Boss 空气墙左侧安全区
  • Boss 区域入场后 Boss HUD 立即显示
  • Boss 区域空气墙进入后完全消失,不再显示或阻挡
  • 玩家节奏输入、四拍槽、动作执行
  • 能量、蓄力、技能释放与剑雨落点对齐
  • 玩家 projectile 与敌人 projectile
  • 小女孩 / 女巫高度对齐,远程水平射击
  • 小怪节拍攻击、朝向、强弱打断规则
  • new3 怪物 / Boss 行为体系:近战基础攻击 50 / 远程 25、距离参数重调、远程怪受击 4 次闪烁无敌跳跃脱离、射程压到视距内、Boss 普攻恒霸体 + 耗能技能压制、Boss 远程相位近身后撤、相位切换停顿(2026-07-05)
  • Boss 行为树与谱面驱动动作
  • 命中、伤害、击退、打断、防御和生命结算
  • Effect / Buff / Debuff 管线
  • Past / Future 时间相位
  • 时间锚点调度、结算和放大视觉反馈
  • 攻击 Buff 7 层显示、伤害加成和玩家特效增强
  • 双音乐层同步切换
  • 世界色调与径向相位切换 wipe
  • HUD:节奏条、combo、ATK、Buff、判定艺术字、状态栏、Boss 栏、四拍槽、E 键招式表
  • Windows 打包链路(export_presets.cfg + 单 exe 内嵌 pck,打包版已做端到端验证)
  • 自动化测试覆盖关键系统(66 个测试)

仍可继续打磨:

  • 替换正式 Future 音乐层
  • 继续扩展 Boss 相位差异和条件锚点
  • 增加更多正式谱面与战斗段落
  • 继续调优 HUD 美术尺寸、透明度和可读性
  • 扩展小怪组合与关卡后续段落
  • 播测校准 2026-07-05 数值:近战小怪强势单跳约 38、Boss 近战翻倍后的压力、高连击档位下单次失误(断连击 + 锁定 + 锚点必破)的代价
  • 进战斗场景瞬间批量启停碰撞体会刷非致命的 "flushing queries" 物理警告,可改 deferred 消除

开发约定

  • EventBus 是系统间事实广播中心,避免跨系统硬引用。
  • TimePhaseManager 是时间相位唯一写入者。
  • TimeAnchorSystem 只消费判定事实,不参与输入链路裁决。
  • GameFlowManager 管理菜单、暂停、难度、胜负和 BossRoom 状态。
  • 动作数值优先写入 ActionData 资源,不硬编码在角色脚本中。
  • Buff / Debuff 优先走 EffectContainer 和 effect 资源。
  • 战斗数值通过 resolver 计算,减少场景脚本间耦合。
  • UI 尽量订阅事实信号,不主动推导战斗状态。
  • 关卡坐标优先通过 Stage / LevelDirector 导出参数表达,并补测试锁定。
  • 新功能或 bugfix 应补充对应 tests/test_*.gd 回归测试。