Initial project sync

This commit is contained in:
wxm
2026-07-06 22:55:14 -07:00
commit 8cca00d0da
1066 changed files with 58585 additions and 0 deletions
+656
View File
@@ -0,0 +1,656 @@
# 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.exe`console 包装器才能看到 stdout 输出;
它按自身文件名寻找同目录的 GUI 版,两个文件必须按原名放在同一目录)。
命令行运行单个测试示例:
```bash
<godot> --headless --path . --script tests/test_level1_spawn_flow.gd
```
重新导入 / 检查项目资源:
```bash
<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_input``input_lockout_seconds = 0.5``consumed_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 触发。
## 当前主流程
```text
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 血量不受该倍率影响。
## 核心玩法循环
当前战斗循环如下:
```text
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_x``boss_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`:攻击与受击区域
- `EffectContainer`Buff / Debuff 容器
- `StreakCounter`:连续成功动作计数
- `AttackBuffComponent`:时间锚点攻击 Buff(含回血与受伤掉层)
- `BurstComponent`:爆发动作门槛
- `FrameCollisionDriver`:帧动画命中框驱动
- `ContactFxSpawner`:命中接触特效
- `OverheadChargeSegments`:头顶蓄力段显示
- `Visual/AttackBuffVisual``Visual/FxOverlay` + `Visual/FxAnimationPlayer`Buff 层数与 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**。由 `LevelDirector``MinionBehavior.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.gd``shrugs_off_hit` + `CombatResolver` 受击方钩子。项目**没有**韧性 / 削韧系统——策划以霸体规则替代了 new3 §6.5 的韧性方案
- 远程(Future)相位被近身 ≤240px 时优先 `boss_retreat_dash` 拉开距离(后撤本身无伤害、8 拍冷却、后撤完接远程攻击)
- 相位切换后停顿 1 拍再决策(以事件总线最后拍号为基准)
- Boss 战前静默,进入 Boss 区域后才激活
- Boss 血条、名称和头像 HUD
行为树距离阈值(2026-07-05 调整后):`melee_distance = 180``ranged_distance = 360``dash_distance = 460`(超过则考虑突进,4 拍冷却)、远程相位后撤触发 `retreat_trigger_distance = 240`;决策间隔 2 拍(Future 相位 ×0.5)。
Boss 入场规则由 `BossRoomGate``GameFlowManager` 共同处理:玩家进入 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`
世界有两个时间相位:
```text
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:
```text
Main
-> Stage
-> ActorsContainer
-> Player
-> Boss
-> UILayer
-> UI
```
Boss 面板显示条件是:
```text
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>` 见「快速开始」):
```bash
<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
```
也可以串行跑一组关键回归:
```bash
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_64`embed_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>` 后缀;升级引擎版本时需换用对应版本的模板包)。
重新打包只需两条命令:
```bash
<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 注册了 `MCPScreenshot``MCPInputService``MCPGameInspector`
这允许外部工具对 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` 回归测试。