Godot 4.x HD-2D 风格动作 RPG 游戏
AI 接手指南:
docs/AI_AGENT_GUIDE.md是当前权威入口。本 README 保留项目概览和部分历史说明,若与 AI 指南冲突,以 AI 指南和当前代码为准。
本次重构解决了根目录混乱、资源重复、命名不规范等问题。
重构前 (混乱): 重构后 (清晰):
touhou-godot/ touhou-godot/
├── *.gd (33个散落脚本) ├── scripts/ ← 所有脚本集中
├── *.tscn (32个散落场景) │ ├── core/ ← 核心系统
├── mokuo.glb, marisa.glb... │ ├── entities/2D/ ← 2D实体
├── sprites/, textures/, shaders/ │ ├── entities/3D/ ← 3D实体
├── tests/, scenes/test/... │ ├── components/ ← 通用组件
└── ... │ ├── systems/ ← 游戏系统
│ ├── npcs/ ← NPC脚本
│ ├── ui/ ← UI脚本
│ ├── vfx/ ← 特效脚本
│ └── tests/ ← 测试脚本
│
├── scenes/ ← 所有场景集中
│ ├── locations/ ← 游戏地点
│ ├── entities/ ← 预制体
│ ├── npcs/ ← NPC场景
│ ├── ui/ ← UI场景
│ └── tests/ ← 测试场景
│
├── assets/ ← 所有资源集中
│ ├── characters/
│ │ ├── mokou/ ← 妹红资源统一
│ │ └── marisa/ ← 魔理沙资源统一
│ ├── vfx/fire/ ← 火焰特效资源
│ └── ...
│
├── effects/ ← 特效预设
│ └── fire/ ← 7个火焰特效 (新)
│
└── _deprecated/ ← 废弃文件存档
├── backup_scenes/
├── duplicate_resources/
└── archive/
| 改动类型 | 说明 |
|---|---|
| 脚本移动 | 33个根目录.gd文件 → scripts/ 对应子目录 |
| 场景移动 | 32个根目录.tscn文件 → scenes/ 对应子目录 |
| 命名统一 | mokuo → mokou (修正拼写) |
| 大小写统一 | 2d/3d/ → 2D/3D/ |
| 资源整合 | 角色资源从3处 → 统一到 assets/characters/ |
| 测试统一 | 4个测试目录 → scripts/tests/ + scenes/tests/ |
| 特效系统 | 新增7个火焰特效 (刀光/爆炸/火柱/喷火器等) |
| 废弃存档 | 所有旧备份/重复文件 → _deprecated/ |
脚本分类基于代码内容而非文件名:
# 正确分类示例:
AimSystem.gd → scripts/components/ # 因为使用 get_parent() 作为玩家组件
ElementEnchant.gd → scripts/entities/2D/ # 因为 extends Area2D
BambooObstacle.gd → scripts/entities/2D/ # 因为 extends StaticBody2D
EnemySpawner.gd → scripts/systems/ # 因为管理敌人生成逻辑位置: effects/fire/
| 文件 | 用途 | 触发时机 |
|---|---|---|
FireBlade.tscn |
火焰刀光 | 轻攻击 (左键) |
FireExplosion.tscn |
火焰爆炸 | 重攻击 (右键) |
FirePillar.tscn |
通天火柱 | 技能攻击 |
FireRing.tscn |
冲刺火圈 | 翻滚冲刺 |
FireSmoke.tscn |
黑烟 | 环境特效 |
Flamethrower.tscn |
喷火器 | 持续伤害 |
GroundFire.tscn |
地火 | 燃烧区域 |
资源位置: assets/vfx/fire/textures/ 和 assets/vfx/fire/models/
scenes/locations/MagicForest.tscn- 魔法之森 (使用 Stylized Nature MegaKit 资源)
| 属性 | 值 |
|---|---|
| 引擎 | Godot 4.5+ (Forward Plus 渲染) |
| 类型 | 3D + 2D 混合 HD-2D 风格 RPG |
| 主题 | 东方 Project 同人游戏 |
| 代码量 | 3000+ 行,200+ 脚本文件 |
| 开发状态 | 核心系统 100% 完成,可游玩原型 |
- NPC 羁绊系统: 6 个核心角色,0-10 级羁绊,礼物/对话/事件互动
- 时间日历系统: 分钟/小时/日期/季节/年份完整循环,8 个节日
- 战斗系统: 3D 玩家控制,敌人 AI,组件化伤害系统
- 农业系统: 3x3 网格,4 种作物,浇水/施肥/收获
- 昼夜天气: 7 时段光照变化,天气/满月特殊事件
- 火焰特效: 7种妹红专属火焰VFX (刀光/爆炸/火柱等)
- 头发物理: SpringBone 动态头发系统
按 F5 启动 → TitleScreen → 新游戏 → BambooHouse → 传送门(E键) → HumanVillage
| 按键 | 功能 |
|---|---|
PageUp/Down |
推进/回退 60 分钟 |
Home |
推进 6 小时 |
I |
打开背包 |
J |
任务日志 |
E |
交互/传送 |
鼠标左键 |
轻攻击 (火焰刀光) |
鼠标右键长按 |
旋转相机 / 重攻击 (火焰爆炸) |
Shift |
翻滚冲刺 (火焰冲击圈) |
touhou-godot/
├── 📂 scripts/ # 所有 GDScript 脚本
│ ├── core/
│ │ ├── autoloads/ # 21个全局单例 (SignalBus, TimeManager等)
│ │ └── managers/ # 管理器类
│ ├── data/ # 数据库 (NPCDatabase, DialogueDatabase等)
│ ├── entities/
│ │ ├── 2D/ # 2D实体脚本 (Player, Enemy, Bullet)
│ │ ├── 3D/ # 3D实体脚本 (Player3D, Enemy3D)
│ │ │ └── states/ # FSM状态类
│ │ └── components/ # 见下方组件目录
│ ├── components/ # 通用组件 (AimSystem, CharacterSkills等)
│ ├── systems/
│ │ ├── farming/ # 农业系统
│ │ ├── combat/ # 战斗系统
│ │ ├── fsm/ # 有限状态机
│ │ └── hd2d/ # HD-2D渲染系统
│ ├── ui/ # UI脚本
│ ├── npcs/
│ │ ├── 2D/ # 2D NPC脚本
│ │ └── 3D/ # 3D NPC脚本 (MarisaNPC3D, KeineNPC3D等)
│ ├── vfx/ # 特效脚本
│ ├── gameplay/ # 游戏逻辑 (ExitDoor, TutorialTrigger等)
│ ├── tools/ # 编辑器工具
│ └── tests/ # 测试脚本
│
├── 📂 scenes/ # 所有 .tscn 场景文件
│ ├── main/ # 主菜单/标题画面
│ ├── locations/ # 游戏地点
│ │ ├── HumanVillage.tscn # 人之里 (3D主场景) ⭐
│ │ ├── BambooHouse.tscn # 竹林小屋 (初始位置)
│ │ ├── MagicForest.tscn # 魔法之森 (新)
│ │ └── TownWorld.tscn # 小镇 (2D旧版)
│ ├── entities/
│ │ ├── 2D/ # 2D预制体
│ │ └── 3D/ # 3D预制体 (Player3D.tscn, Enemy3D.tscn)
│ ├── npcs/ # NPC预制体 (KeineNPC, ReimuNPC等)
│ ├── ui/ # UI场景
│ ├── combat/ # 战斗场景
│ ├── farming/ # 农业场景
│ ├── effects/ # 特效场景 (AttackEffectHitbox等)
│ └── tests/ # 测试场景
│
├── 📂 assets/ # 资源文件
│ ├── characters/
│ │ ├── mokou/ # 妹红资源 (统一位置)
│ │ │ ├── models/ # mokou.glb, mokou.tscn
│ │ │ └── textures/ # 所有妹红纹理
│ │ └── marisa/ # 魔理沙资源 (统一位置)
│ ├── vfx/
│ │ └── fire/ # 火焰特效资源
│ │ ├── textures/ # 火焰翻页纹理
│ │ └── models/ # 火焰模型 (daoguang.fbx等)
│ ├── SUCAI/ # 3D模型和纹理包
│ ├── textures/ # 通用2D纹理
│ ├── data/ # JSON配置
│ └── resources/ # .res/.tres文件
│
├── 📂 effects/ # 特效预设 (.tscn)
│ ├── fire/ # 火焰特效 (7个) ⭐新
│ │ ├── FireBlade.tscn # 刀光
│ │ ├── FireExplosion.tscn # 爆炸
│ │ ├── FirePillar.tscn # 火柱
│ │ ├── FireRing.tscn # 冲刺圈
│ │ ├── FireSmoke.tscn # 黑烟
│ │ ├── Flamethrower.tscn # 喷火器
│ │ └── GroundFire.tscn # 地火
│ ├── 3d_flame/
│ ├── 3d_smoke_explosion/
│ └── ...
│
├── 📂 core/ # 核心定义文件
├── 📂 entities/ # 实体组件定义
├── 📂 addons/ # 编辑器插件
├── 📂 docs/ # 文档
│ └── archive/ # 历史存档 (路径可能过时)
│
├── 📂 _deprecated/ # 废弃文件存档 (不要使用!)
│ ├── backup_scenes/ # 旧版场景
│ ├── duplicate_resources/ # 重复资源
│ ├── archive/ # 历史备份
│ └── README.md # 废弃说明
│
├── project.godot # Godot项目配置
└── README.md # 本文件 (权威)
21 个全局单例,在 project.godot 的 [autoload] 节配置:
| 单例 | 文件 | 职责 |
|---|---|---|
SignalBus |
scripts/core/autoloads/SignalBus.gd |
中央信号总线 (310+ 信号) |
TimeManager |
scripts/core/autoloads/TimeManager.gd |
游戏时间管理 (分钟/小时) |
CalendarManager |
scripts/core/autoloads/CalendarManager.gd |
日期/季节/年份/节日 |
NPCDatabase |
scripts/data/NPCDatabase.gd |
NPC 数据存储 |
NPCManager |
scripts/core/autoloads/NPCManager.gd |
NPC 实例化/生成 |
NPCScheduleManager |
scripts/core/autoloads/NPCScheduleManager.gd |
NPC 日程查询 |
BondSystem |
scripts/core/autoloads/BondSystem.gd |
羁绊等级/点数 |
CompanionSystem |
scripts/core/autoloads/CompanionSystem.gd |
同伴招募/队伍 |
WeatherSystem |
scripts/core/autoloads/WeatherSystem.gd |
天气/满月 |
DayNightManager |
scripts/core/autoloads/DayNightManager.gd |
昼夜光照 |
InventoryManager |
scripts/core/InventoryManager.gd |
背包系统 |
SaveSystem |
scripts/core/SaveSystem.gd |
存档/读档 |
GameStateManager |
scripts/core/GameStateManager.gd |
游戏状态 |
VFX3D |
scripts/core/autoloads/VFX3D.gd |
3D特效管理 |
所有系统间通信都通过 SignalBus,实现完全解耦:
# 发送信号
SignalBus.player_health_changed.emit(new_hp, max_hp)
SignalBus.hour_changed.emit(new_hour)
SignalBus.bond_level_changed.emit(npc_id, new_level)
# 监听信号
SignalBus.player_health_changed.connect(_on_health_changed)
SignalBus.hour_changed.connect(_on_hour_changed)主要信号分类:
- 战斗:
player_health_changed,enemy_killed,damage_dealt - 时间:
time_tick,hour_changed,day_changed,season_changed - NPC:
bond_level_changed,npc_interaction_started,gift_given - UI:
inventory_opened,dialogue_started,show_notification
通用组件 位于 scripts/entities/components/ 和 scripts/components/:
| 组件 | 位置 | 职责 |
|---|---|---|
HealthComponent |
entities/components/ | HP管理,死亡处理 |
HurtboxComponent |
entities/components/ | 接收伤害的碰撞体 |
HitboxComponent |
entities/components/ | 造成伤害的碰撞体 |
StateMachine |
systems/fsm/ | FSM 状态管理 |
AimSystem |
components/ | 玩家瞄准系统 |
CharacterSkills |
components/ | 角色技能 |
使用示例:
# Player3D.tscn 结构
CharacterBody3D
├── HealthComponent
├── HurtboxComponent (Area3D)
├── HitboxComponent (Area3D)
├── StateMachine
│ ├── PlayerIdle
│ ├── PlayerMove
│ ├── PlayerDash
│ └── PlayerAttack
└── ...# 攻击配置
ATTACK_DATA = {
"light": {anim: "Attack_Punch", damage: 15, effect: FireBlade},
"heavy": {anim: "Attack_Kick_1", damage: 25, effect: FireExplosion},
"skill": {anim: "Attack_Kick_2", damage: 40, effect: FirePillar}
}
# 特效预加载
var fire_blade_scene = preload("res://effects/fire/FireBlade.tscn")
var hit_impact_scene = preload("res://effects/fire/FireExplosion.tscn")
var fire_pillar_scene = preload("res://effects/fire/FirePillar.tscn")
var fire_dash_scene = preload("res://effects/fire/FireRing.tscn")| 输入 | 攻击类型 | 特效 |
|---|---|---|
| 鼠标左键 | light | FireBlade (刀光) |
| 鼠标右键 | heavy | FireExplosion (爆炸) |
| 技能键 | skill | FirePillar (火柱) |
| Shift | dash | FireRing (冲刺圈) |
# 6个核心NPC
const NPC_DATABASE = {
"keine": {名称, 头衔, 描述, 种族, 主题色, 精灵资源},
"reimu": {...},
"marisa": {...},
"sakuya": {...},
"koishi": {...},
"kaguya": {...}
}# 每个NPC有4-7个时间段
const NPC_SCHEDULES = {
"keine": [
{start_hour: 8, end_hour: 12, location: "Terakoya", spot: "TerakoyaSpot"},
{start_hour: 12, end_hour: 18, location: "Town", spot: "KeineSpot"},
...
]
}位于 scripts/npcs/3D/:
MarisaNPC3D.gd- 魔理沙 (魔法之森)KeineNPC3D.gd- 慧音 (满月变身白泽)KoishiNPC3D.gd- 恋恋 (雨天出现)KaguyaNPC3D.gd- 辉夜 (夜晚限定)
游戏时间流转:
1 真实秒 = 1 游戏分钟
60 分钟 = 1 小时 → 触发 hour_changed
24 小时 = 1 天 → 触发 day_changed
28 天 = 1 月 (1季)
4 季 = 1 年
季节:
春 (日期 1-28): 樱花粒子
夏 (日期 29-56): 萤火虫粒子
秋 (日期 57-84): 落叶粒子
冬 (日期 85-112): 雪花粒子
-
资源准备:
- 纹理放入
assets/vfx/fire/textures/ - 模型放入
assets/vfx/fire/models/
- 纹理放入
-
创建场景 (
effects/fire/NewEffect.tscn):
[gd_scene format=3]
[ext_resource path="res://assets/vfx/fire/textures/xxx.png" id="1"]
[node name="NewEffect" type="GPUParticles3D"]
...
- 在 Player3D.gd 中预加载:
var new_effect_scene = preload("res://effects/fire/NewEffect.tscn")- 在 _trigger_attack() 中使用:
match type:
"new_type":
if new_effect_scene:
fire_effect = new_effect_scene.instantiate()- 数据库 (
NPCDatabase.gd): 添加NPC数据 - 日程 (
NPCScheduleManager.gd): 添加时间表 - 脚本 (
scripts/npcs/3D/NewNPC3D.gd): 继承 BaseNPC3D - 场景: 添加生成点 Marker3D
参考 scenes/locations/MagicForest.tscn:
- 创建 Node3D 根节点
- 添加
StaticBody3D+CollisionShape3D作为地面 - 实例化
Player3D.tscn - 添加光照和环境
| 任务 | 关键文件 |
|---|---|
| 修改攻击特效 | scripts/entities/3D/Player3D.gd → _trigger_attack() |
| 添加火焰特效 | effects/fire/ + assets/vfx/fire/ |
| 修改 NPC 数据 | scripts/data/NPCDatabase.gd |
| 修改对话内容 | scripts/data/DialogueDatabase.gd |
| 修改时间流速 | scripts/core/autoloads/TimeManager.gd |
| 修改战斗数值 | scripts/entities/3D/Player3D.gd → ATTACK_DATA |
| 添加新信号 | scripts/core/autoloads/SignalBus.gd |
| 修改羁绊阈值 | scripts/core/autoloads/BondSystem.gd |
| 修改场景布局 | scenes/locations/*.tscn |
- 关注点分离: 数据与逻辑分离 (Database 模式)
- 事件驱动: SignalBus 全局信号,系统间解耦
- 组件化: Health/Hitbox/Hurtbox 通用组件
- 状态机: StateMachine 管理角色行为
- 资源集中: 同类资源放在统一目录 (
assets/characters/mokou/) - 命名规范: 2D/3D 大写,mokou 统一拼写
2026-02-02 项目结构重构,火焰特效系统,魔法之森场景
2026-01-26 实现头发动态物理系统 (SpringBone)
2026-01-25 添加 3D 角色模型、UI 系统、天气效果
最后更新: 2026-02-02