Files
2026-07-06 22:59:47 -07:00

656 lines
34 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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` 回归测试。