diff --git a/assets/sprites/ui/灵田.png b/assets/sprites/ui/灵田.png new file mode 100644 index 0000000..d4c624c Binary files /dev/null and b/assets/sprites/ui/灵田.png differ diff --git a/assets/sprites/ui/灵田.png.import b/assets/sprites/ui/灵田.png.import new file mode 100644 index 0000000..96394bc --- /dev/null +++ b/assets/sprites/ui/灵田.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b7cfvmuq8m7g3" +path="res://.godot/imported/灵田.png-1999fb337f7e0865f893a16872e15f6b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/sprites/ui/灵田.png" +dest_files=["res://.godot/imported/灵田.png-1999fb337f7e0865f893a16872e15f6b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/doc/design/建筑系统设计.md b/doc/design/建筑系统设计.md new file mode 100644 index 0000000..033b98a --- /dev/null +++ b/doc/design/建筑系统设计.md @@ -0,0 +1,212 @@ +# 建筑系统设计(D6:建筑系统基础) + +> 对应开发计划表 D6(8/8):① 灵石矿场景 ② 建造→产出 ③ 升级。交付标准:建筑产资源,升级加速。 +> 本文档只描述设计,不包含代码。 +> 状态:设计稿,待审阅通过后实现 + +--- + +## 一、核心循环 + +``` +建造(花灵石)→ 每日产出(灵石/食物)→ 攒资源升级 → 产出加速 → 支撑修炼/招募经济 +``` + +- 纯挂机产出:与修炼/招募同节奏,监听 `TimeSystem.day_passed` 每日结算 +- 产出直接进入 SectManager 资源(HUD 实时联动) + +--- + +## 二、数据模型(Building) + +| 字段 | 类型 | 说明 | +|------|------|------| +| `type` | 枚举 BuildingType | 建筑种类(灵石矿 / 灵田) | +| `level` | int | 等级(1 起) | + +价格与产出**不在建筑上存副本**,运行时按 `type + level` 从 GameConfig 计算,杜绝数值漂移(与修炼数值同一原则)。 + +### 本期建筑种类 + +| 类型 | 名称 | 产出 | 消费资源 | +|------|------|------|---------| +| SPIRIT_STONE_MINE | 灵石矿 | 灵石/日 | 建造/升级花灵石 | +| SPIRIT_FIELD | 灵田 | 食物/日 | 建造/升级花灵石 | + +> 食物为通用资源(顶部栏常驻显示,见通用资源分析文档),需在 SectManager 新增。**HUD 显示名为"灵米"**(内部资源名 `food`)。 +> +> **后续建筑规划**:灵药园(产灵草,修炼资源,W5 炼丹材料)——与灵田分工:灵田管口粮(食物),药园管药材(灵草),加新建筑 = 配置加一节 + 枚举加一项 + 产出分发加一行。 + +> **无地图摆放**:本期建筑统一以面板条目呈现(BuildingsPanel 数据行),灵石矿与灵田同套处理,不建单独场景。地图摆放(建筑实体显示在宗门画面上)属 P2 扩展。 + +--- + +## 三、产出机制 + +- **BuildingManager**(新 Autoload)监听 `day_passed`,遍历已建建筑逐座结算 +- 灵石矿 → `SectManager.add_spirit_stones(output)` +- 灵田 → `SectManager.add_food(output)` +- 产出量与等级相关:`产出 = 基础产出 × 升级产出倍率^(等级-1)` + +## 三·五、口粮消耗与断粮离宗 + +灵田产出的食物有真实用途——**练气期弟子每日吃粮**(筑基+辟谷,为将来预留)。 + +### 断粮后果三方案(选定:方案 B) + +按修仙设定,练气期尚未辟谷(引气入体 ≠ 断食),仍需进食;通常筑基期逐渐辟谷、金丹期完全辟谷——"断粮有后果"是成立的。具体后果有三档可选: + +| 方案 | 断粮后果 | 特点 | +|------|---------|------| +| **A 饿死** | 断粮累计 N 天(如 30 天)→ 弟子死亡,从名录移除 | 忠于设定,压力最大;但需死亡表现(遗物/坟冢等),范围膨胀 | +| **B 离宗(选定)** | 断粮累计 N 天 → 弟子出走投奔他处,名录移除 | 效果同 A,叙事更软("出走"而非"死亡"),UI/代码最简单,契合宗门经营题材 | +| **C 不致命** | 只修炼效率减半,永远不死 | 最温和,生存压力弱,经济闭环不成立 | + +**选定理由**:方案 B 的代码量约等于 A(定时检查 + 名录移除,名录/详情 UI 均为现成),但"弟子出走"比"饿死"更符合宗门经营题材的叙事基调,也避开死亡表现系统的范围膨胀,适合 M1 前落地。 + +### 机制细则(方案 B) + +1. **每日消耗**:`食物 -= 练气弟子数 × 人均消耗`(配置 `consumption_per_disciple`,默认 1) +2. **断粮判定**:食物不足以覆盖全部练气弟子时 → 食物归 0,全体练气弟子**饥饿天数 +1**;食物充足 → 饥饿天数清零 +3. **饥饿惩罚**:饥饿期间修炼速度 × `hunger_speed_multiplier`(默认 0.5) +4. **离宗**:饥饿天数 ≥ `hunger_threshold_days`(默认 30)→ 弟子**离宗出走**,从名录移除(控制台日志"X 因断粮离宗") +5. 筑基+弟子不消耗口粮(`realm_index != 0` 豁免,为筑基系统预留) + +**设计意图**:生存压力驱动经济闭环——断粮 → 修炼放缓 → 弟子出走 → 玩家被迫种灵田/合理经营,而不是让食物纯积累无意义。 + +--- + +## 四、建造与升级 + +| 操作 | 规则 | +|------|------| +| 建造 | 检查灵石 ≥ 建造价 → 扣除 → 建筑入列(等级 1) | +| 升级 | 检查灵石 ≥ 升级价 → 扣除 → 等级 +1 | +| 升级价 | `建造价 × 升级价格倍率^等级`(即升到 2 级花 建造价×倍率) | +| 等级上限 | 配置 `max_level`(默认 10) | + +资源不足时:UI 按钮禁用,无其他副作用。 + +--- + +## 五、配置节(game_config.cfg 新增) + +```ini +[building] ; 建筑系统通用 +starting_spirit_stones=500 ; 开局灵石(解决初始资金为 0,新游戏发放) +starting_food=100 ; 开局食物(口粮缓冲,新游戏发放) +max_level=10 ; 建筑等级上限 + +[building_mine] ; 灵石矿 +cost=200 ; 建造价(灵石) +output=10 ; 日产出(灵石) +upgrade_cost_x=2.0 ; 升级价格倍率 +upgrade_output_x=1.5 ; 升级产出倍率 + +[building_field] ; 灵田 +cost=100 ; 建造价(灵石) +output=5 ; 日产出(食物) +upgrade_cost_x=2.0 ; 升级价格倍率 +upgrade_output_x=1.5 ; 升级产出倍率 + +[food] ; 口粮与生存 +consumption_per_disciple=1 ; 练气弟子人均日消耗 +hunger_speed_multiplier=0.5 ; 饥饿期间修炼速度倍率 +hunger_threshold_days=30 ; 断粮累计天数上限(达到即离宗) +``` + +> 加新建筑 = 配置加一节 + 枚举加一项 + BuildingManager 产出分发加一行(对照 `[recruitment_*]` 模式)。 + +--- + +## 六、UI 建筑面板(BuildingsPanel) + +- **入口**:TopBar"资源"按钮(Button_ResourcesManagement,当前未接线)→ 打开 +- 打开面板时**暂停时间**(与弟子名录面板一致,关闭恢复) +- 面板结构(复用青绿弹窗模式): + - 标题"宗门建筑" + - 每种建筑一行:名称 / 等级 / 日产出 + 建造或升级按钮(显示价格,资源不足禁用) + - 底部"关闭"按钮 + 遮罩点击关闭 +- 数据驱动:监听 `buildings_changed` 重建列表,打开时主动刷新 + +--- + +## 七、分步实现规划(小步可验证,每步独立跑通) + +### 步骤 1:SectManager 加食物资源 + 开局资源发放 + +| 项 | 内容 | +|----|------| +| 改动 | `SectManager.gd` 加 `food` 资源 + `add_food/remove_food` + `food_changed` 信号;`MainGame.gd` 新游戏时发放开局灵石/食物 | +| 验证 | 无头运行后控制台打印 `SectManager.food`,增减接口调用正确 | + +### 步骤 2:HUD 食物显示 + +| 项 | 内容 | +|----|------| +| 改动 | `TopBarHUD.tscn` 加"食物"标签对;`top_bar_hud.gd` 连 `food_changed` 信号 + 初始值 | +| 验证 | 开局 100 食物显示在顶栏;`add_food` 实时刷新 | + +### 步骤 3:`[building]` / `[food]` 配置节 + GameConfig 读取 + +| 项 | 内容 | +|----|------| +| 改动 | `game_config.cfg` 加两节(开局灵石/食物、灵石矿/灵田参数、口粮/饥饿参数);`GameConfig.gd` 加对应字段 + `building_params` 字典 + 解析 | +| 验证 | 无头打印各配置值,缺项回退默认值 | + +### 步骤 4:Building 模型 + BuildingManager + +| 项 | 内容 | +|----|------| +| 改动 | `src/Sect/buildings/Building.gd`(type/level + 价格产出计算,运行时读配置);`src/Sect/BuildingManager.gd`(建造/升级/每日产出/`buildings_changed` 信号);`project.godot` 注册 Autoload | +| 验证 | 模拟:建造扣费入列、每日产出进 SectManager、升级后产出提升 | + +### 步骤 5:口粮消耗 + 饥饿惩罚 + 断粮离宗 + +| 项 | 内容 | +|----|------| +| 改动 | `Disciple.gd` 加 `hunger_days`;`CultivationManager.gd` 每日先结算口粮(消耗→饥饿→离宗),`_gain_exp` 乘饥饿倍率 | +| 验证 | 模拟 40 天断粮:饥饿累计、修炼减半、第 30 天离宗、日志可见;恢复食物后清零 | + +### 步骤 6:BuildingsPanel UI + "资源"按钮接线 + +| 项 | 内容 | +|----|------| +| 改动 | `src/UI/Panels/BuildingsPanel/`(面板场景+脚本,每类型一行:名称/等级/日产出+建造或升级按钮);`TopBarHUD.tscn` 连"资源"按钮 → 新信号 → `MainGame.gd` 打开面板 | +| 验证 | 无头布局检查 + F5 手测:建造/升级/禁用态/暂停恢复 | + +### 步骤 7:整体挂机验证 + 提交 + +| 项 | 内容 | +|----|------| +| 改动 | 无(仅验证) | +| 验证 | 挂机模拟:开局 500 灵石→建灵田→产出覆盖口粮→攒灵石升级→产出加速;断粮场景:不建灵田→30 天弟子离宗;对照八节验收清单逐项勾选 | + +> 依赖关系:1→2 顺序执行(HUD 依赖食物资源);3→4 顺序执行(Building 依赖配置);5 依赖 1/3;6 依赖 4;7 为最终验证。 + +--- + +## 八、验收清单(D6 交付标准) + +- [ ] 新游戏开局赠送 500 灵石 + 100 食物(配置可调),HUD 可见 +- [ ] 点"资源"按钮打开建筑面板(时间暂停,关闭恢复) +- [ ] 灵石充足时可建造灵石矿/灵田,扣费入列 +- [ ] 每日自动产出灵石/食物,HUD 实时增长 +- [ ] 升级建筑后产出提升(升级倍率生效),价格按倍率递增 +- [ ] 灵石不足时建造/升级按钮禁用 +- [ ] 等级达到上限后不可再升级 +- [ ] 练气弟子每日消耗食物;断粮后饥饿天数累计、修炼速度减半 +- [ ] 断粮累计 30 天弟子离宗(名录移除 + 日志) +- [ ] 食物恢复充足后饥饿清零 +- [ ] 建筑/饥饿数据为纯数据(可序列化,D8 存档接入) + +--- + +## 九、与后续任务衔接 + +| 后续任务 | 衔接方式 | +|----------|----------| +| D8 存档接入 | Building 纯数据模型直接序列化 | +| W3 财政经济 | 建筑产出进入收支流水;俸禄发放扣灵石 | +| W5 生产制造 | 灵田/灵石矿的弟子匹配度(灵根→效率)接入 | +| 修炼系统 | 后续灵气建筑(灵泉/聚灵阵)动态化 `qi_concentration` | diff --git a/doc/开发计划表.md b/doc/开发计划表.md index ea380be..c971c04 100644 --- a/doc/开发计划表.md +++ b/doc/开发计划表.md @@ -1,7 +1,7 @@ # 开发计划表 > 开始日期:2026-08-03(周一) 每日有效开发约 2 小时 -> 进度更新:2026-08-08  D1–D4 完成;D5(修炼循环)未启动,进度落后 1 天(设计文档已就绪,待实现) +> 进度更新:2026-08-08  D1–D4 完成;D5(修炼循环)未启动,进度落后 1 天(设计文档已更新:灵根容量公式 1÷根数、无灵根体修预留、修炼数值配置化,待实现);D3 追加增强完成(灵根数量 1~5 权重配置化、天灵根改为仅天骄资质嵌套判定) ## 一、每日作息模板(工作日) @@ -21,9 +21,9 @@ | ---- | -- | ---- | ---- | -------- | ---- | | 8/3 一 | D1 | TimeSystem | ① 日期变量(年月日) ② tick 推进 ③ 暂停/加速 | HUD 显示年月日,可调速度 | ✅ 完成(含月/年信号、Settings 持久化) | | 8/4 二 | D2 | SectManager 数据模型 | ① 单例 ② 灵石/灵气/声望 ③ 增减接口 | 控制台可读写资源 | ✅ 完成(灵石/声望增减+信号,HUD 实时绑定) | -| 8/5 三 | D3 | 弟子生成 + 入宗分流 | ① 随机名字/资质/灵根 ② 按资质分四类 ③ 招募流程 | 开局 5 选 3 必选满,定期弹窗可全拒/全收 | ✅ 完成(弹窗招募:开局5选3+定期3候选,配置驱动含天灵根3%;新增 GameConfig 配置系统) | +| 8/5 三 | D3 | 弟子生成 + 入宗分流 | ① 随机名字/资质/灵根 ② 按资质分四类 ③ 招募流程 | 开局 5 选 3 必选满,定期弹窗可全拒/全收 | ✅ 完成(弹窗招募:开局5选3+定期3候选,配置驱动含天灵根;新增 GameConfig 配置系统)
追加:天灵根改为仅天骄资质再掷(`heavenly_root_chance`),灵根数量 1~5 权重配置化(`root_count_weights`),容量公式 1÷根数 | | 8/6 四 | D4 | 弟子列表 UI | ① 列表条目场景 ② 姓名/资质/境界显示 ③ 点击详情 | 列表可浏览弟子 | ✅ 完成(管理按钮入口,名录面板+详情弹窗,天灵根标记,打开面板暂停时间) | -| 8/7 五 | D5 | 修炼循环 | ① 修为随时间增长(资质×灵气) ② 境界门槛 ③ 突破判定 | 弟子自动修炼,可突破 | ⬜ | +| 8/7 五 | D5 | 修炼循环 | ① 修为随时间增长(资质×灵气) ② 境界门槛 ③ 突破判定 | 弟子自动修炼,可突破 | ⬜(设计已就绪:容量=1÷根数、无灵根体修预留、[cultivation] 配置节,待实现) | | 8/8 六 | D6 | 建筑系统基础 | ① 灵石矿场景 ② 建造→每时辰产出 ③ 升级 | 建筑产灵石,升级加速 | ⬜ | | 8/9 日 | D7 | 休息 / 补漏 | 修本周 bug,整理代码 | git 干净 | ⬜ | | 8/10 一 | D8 | 存档接入 | ① SaveSystem JSON 序列化 ② 存/读接口 ③ 替换 SavePanel 测试数据 | 读档后数据还原 | ⬜ | diff --git a/resources/game_config.cfg b/resources/game_config.cfg index 063fe46..2e6f506 100644 --- a/resources/game_config.cfg +++ b/resources/game_config.cfg @@ -29,4 +29,4 @@ level_thresholds=[100, 200, 350, 550, 800, 1100, 1500, 2000, 2600, 3300, 4100, 5 bottleneck_levels=[4, 7, 10, 13] ; 瓶颈目标层(升到这些层需突破判定) [ui] ; UI 通用 -hud_font_size=28 ; HUD 字体大小 +hud_font_size=24 ; HUD 字体大小 diff --git a/resources/hud_button_theme.tres b/resources/hud_button_theme.tres new file mode 100644 index 0000000..7f62da6 --- /dev/null +++ b/resources/hud_button_theme.tres @@ -0,0 +1,7 @@ +[gd_resource type="Theme" format=3 uid="uid://05ygdcq8dme4"] + +[ext_resource type="FontFile" uid="uid://drt448qncx27p" path="res://assets/fonts/dingliezhuhaifont-20240831GengXinBan)-2.ttf" id="1_fwts0"] + +[resource] +default_font = ExtResource("1_fwts0") +default_font_size = 24 diff --git a/resources/hud_label_settings.tres b/resources/hud_label_settings.tres new file mode 100644 index 0000000..917afd7 --- /dev/null +++ b/resources/hud_label_settings.tres @@ -0,0 +1,13 @@ +[gd_resource type="LabelSettings" format=3 uid="uid://d1v74ab2ldtn7"] + +[ext_resource type="FontFile" uid="uid://drt448qncx27p" path="res://assets/fonts/dingliezhuhaifont-20240831GengXinBan)-2.ttf" id="1_fg5xm"] + +[resource] +font = ExtResource("1_fg5xm") +font_size = 24 +font_color = Color(0.82, 0.95, 0.9, 1) +outline_size = 3 +outline_color = Color(0, 0, 0, 0.8) +shadow_size = 2 +shadow_color = Color(0, 0, 0, 0.7) +shadow_offset = Vector2(1, 2) diff --git a/resources/main_menu_theme.tres b/resources/main_menu_theme.tres new file mode 100644 index 0000000..d3a4033 --- /dev/null +++ b/resources/main_menu_theme.tres @@ -0,0 +1,7 @@ +[gd_resource type="Theme" format=3 uid="uid://ctuanla5trf4s"] + +[ext_resource type="FontFile" uid="uid://drt448qncx27p" path="res://assets/fonts/dingliezhuhaifont-20240831GengXinBan)-2.ttf" id="1_cviax"] + +[resource] +default_font = ExtResource("1_cviax") +default_font_size = 32 diff --git a/src/Core/SectManager.gd b/src/Core/SectManager.gd index a21e914..1457e04 100644 --- a/src/Core/SectManager.gd +++ b/src/Core/SectManager.gd @@ -3,9 +3,11 @@ extends Node signal spirit_stones_changed(new_value: int, delta: int) signal reputation_changed(new_value: int, delta: int) +signal food_changed(new_value: int, delta: int) var spirit_stones := 0 # 灵石 var reputation := 0 # 声望 +var food := 0 # 灵米(食物资源,HUD 显示"灵米") func add_spirit_stones(amount: int) -> void: @@ -23,3 +25,11 @@ func add_reputation(amount: int) -> void: func remove_reputation(amount: int) -> void: reputation -= amount emit_signal("reputation_changed", reputation, -amount) + +func add_food(amount: int) -> void: + food += amount + emit_signal("food_changed", food, amount) + +func remove_food(amount: int) -> void: + food -= amount + emit_signal("food_changed", food, -amount) diff --git a/src/UI/HUD/TopBarHUD.tscn b/src/UI/HUD/TopBarHUD.tscn index 96f64e7..78a7f17 100644 --- a/src/UI/HUD/TopBarHUD.tscn +++ b/src/UI/HUD/TopBarHUD.tscn @@ -1,11 +1,14 @@ [gd_scene format=3 uid="uid://dl0tb68vsw3c6"] -[ext_resource type="FontFile" uid="uid://drt448qncx27p" path="res://assets/fonts/dingliezhuhaifont-20240831GengXinBan)-2.ttf" id="1_pa2rn"] [ext_resource type="Script" uid="uid://d3o1ssph7ca58" path="res://src/UI/HUD/top_bar_hud.gd" id="1_vm4eo"] +[ext_resource type="Theme" uid="uid://05ygdcq8dme4" path="res://resources/hud_button_theme.tres" id="2_ymrsi"] +[ext_resource type="LabelSettings" uid="uid://d1v74ab2ldtn7" path="res://resources/hud_label_settings.tres" id="3_4k476"] [sub_resource type="LabelSettings" id="LabelSettings_bn2o5"] -font = ExtResource("1_pa2rn") font_size = 32 +shadow_size = 2 +shadow_color = Color(0, 0, 0, 0.7) +shadow_offset = Vector2(1, 2) [node name="TopBarHud" type="Control" unique_id=1115394694] layout_mode = 3 @@ -16,167 +19,204 @@ grow_horizontal = 2 grow_vertical = 2 script = ExtResource("1_vm4eo") -[node name="HBoxContainer" type="HBoxContainer" parent="." unique_id=1608257100] +[node name="VBoxContainer" type="VBoxContainer" parent="." unique_id=1616038110] layout_mode = 1 -anchors_preset = 10 +anchors_preset = 15 anchor_right = 1.0 -offset_bottom = 23.0 +anchor_bottom = 1.0 grow_horizontal = 2 +grow_vertical = 2 -[node name="Label_Currency" type="Label" parent="HBoxContainer" unique_id=766096596] +[node name="HBoxContainer2" type="HBoxContainer" parent="VBoxContainer" unique_id=2089867867] layout_mode = 2 -size_flags_horizontal = 3 -size_flags_vertical = 8 -text = "灵石" -label_settings = SubResource("LabelSettings_bn2o5") -[node name="Value_Currency" type="Label" parent="HBoxContainer" unique_id=1150573727] -unique_name_in_owner = true -layout_mode = 2 -size_flags_horizontal = 3 -size_flags_vertical = 8 -size_flags_stretch_ratio = 2.0 -label_settings = SubResource("LabelSettings_bn2o5") - -[node name="Label_Time" type="Label" parent="HBoxContainer" unique_id=671872515] -layout_mode = 2 -size_flags_horizontal = 3 -size_flags_vertical = 8 -text = "时间" -label_settings = SubResource("LabelSettings_bn2o5") - -[node name="Value_Time" type="Label" parent="HBoxContainer" unique_id=1229577188] -unique_name_in_owner = true -layout_mode = 2 -size_flags_horizontal = 3 -size_flags_vertical = 8 -size_flags_stretch_ratio = 2.0 -label_settings = SubResource("LabelSettings_bn2o5") - -[node name="Label_Reputation" type="Label" parent="HBoxContainer" unique_id=985110673] -layout_mode = 2 -size_flags_horizontal = 3 -size_flags_vertical = 8 -text = "声望" -label_settings = SubResource("LabelSettings_bn2o5") - -[node name="Value_Reputation" type="Label" parent="HBoxContainer" unique_id=2011931119] -unique_name_in_owner = true -layout_mode = 2 -size_flags_horizontal = 3 -size_flags_vertical = 8 -size_flags_stretch_ratio = 2.0 -label_settings = SubResource("LabelSettings_bn2o5") - -[node name="Label_Qi" type="Label" parent="HBoxContainer" unique_id=790000001] -layout_mode = 2 -size_flags_horizontal = 3 -size_flags_vertical = 8 -text = "灵气" -label_settings = SubResource("LabelSettings_bn2o5") - -[node name="Value_Qi" type="Label" parent="HBoxContainer" unique_id=790000002] -unique_name_in_owner = true -layout_mode = 2 -size_flags_horizontal = 3 -size_flags_vertical = 8 -size_flags_stretch_ratio = 2.0 -label_settings = SubResource("LabelSettings_bn2o5") - -[node name="SpeedGroup" type="HBoxContainer" parent="HBoxContainer" unique_id=2144893126] +[node name="SpeedGroup" type="HBoxContainer" parent="VBoxContainer/HBoxContainer2" unique_id=2144893126] layout_mode = 2 size_flags_horizontal = 3 size_flags_stretch_ratio = 3.0 theme_override_constants/separation = 4 -[node name="Button_Pause" type="Button" parent="HBoxContainer/SpeedGroup" unique_id=2144893127] +[node name="Button_Pause" type="Button" parent="VBoxContainer/HBoxContainer2/SpeedGroup" unique_id=2144893127] unique_name_in_owner = true custom_minimum_size = Vector2(64, 0) layout_mode = 2 size_flags_horizontal = 3 size_flags_stretch_ratio = 3.0 -theme_override_fonts/font = ExtResource("1_pa2rn") -theme_override_font_sizes/font_size = 32 +theme = ExtResource("2_ymrsi") text = "暂停" -[node name="Button_Speed1" type="Button" parent="HBoxContainer/SpeedGroup" unique_id=2144893128] +[node name="Button_Speed1" type="Button" parent="VBoxContainer/HBoxContainer2/SpeedGroup" unique_id=2144893128] unique_name_in_owner = true custom_minimum_size = Vector2(48, 0) layout_mode = 2 size_flags_horizontal = 3 size_flags_stretch_ratio = 2.0 -theme_override_fonts/font = ExtResource("1_pa2rn") -theme_override_font_sizes/font_size = 32 +theme = ExtResource("2_ymrsi") text = "1x" -[node name="Button_Speed5" type="Button" parent="HBoxContainer/SpeedGroup" unique_id=2144893129] +[node name="Button_Speed5" type="Button" parent="VBoxContainer/HBoxContainer2/SpeedGroup" unique_id=2144893129] unique_name_in_owner = true custom_minimum_size = Vector2(48, 0) layout_mode = 2 size_flags_horizontal = 3 size_flags_stretch_ratio = 2.0 -theme_override_fonts/font = ExtResource("1_pa2rn") -theme_override_font_sizes/font_size = 32 +theme = ExtResource("2_ymrsi") text = "5x" -[node name="Button_Speed20" type="Button" parent="HBoxContainer/SpeedGroup" unique_id=2144893130] +[node name="Button_Speed20" type="Button" parent="VBoxContainer/HBoxContainer2/SpeedGroup" unique_id=2144893130] unique_name_in_owner = true custom_minimum_size = Vector2(48, 0) layout_mode = 2 size_flags_horizontal = 3 size_flags_stretch_ratio = 2.0 -theme_override_fonts/font = ExtResource("1_pa2rn") -theme_override_font_sizes/font_size = 32 +theme = ExtResource("2_ymrsi") text = "20x" -[node name="placeholder_1" type="Label" parent="HBoxContainer" unique_id=1042446504] +[node name="placeholder_1" type="Label" parent="VBoxContainer/HBoxContainer2" unique_id=1042446504] layout_mode = 2 size_flags_horizontal = 3 -size_flags_vertical = 8 +size_flags_vertical = 1 +size_flags_stretch_ratio = 8.0 label_settings = SubResource("LabelSettings_bn2o5") -[node name="placeholder_2" type="Label" parent="HBoxContainer" unique_id=1526548351] +[node name="Button_StaffManagement" type="Button" parent="VBoxContainer/HBoxContainer2" unique_id=568204305] layout_mode = 2 size_flags_horizontal = 3 -size_flags_vertical = 8 -label_settings = SubResource("LabelSettings_bn2o5") - -[node name="placeholder_3" type="Label" parent="HBoxContainer" unique_id=1170426663] -layout_mode = 2 -size_flags_horizontal = 3 -size_flags_vertical = 8 -label_settings = SubResource("LabelSettings_bn2o5") - -[node name="placeholder_4" type="Label" parent="HBoxContainer" unique_id=1878816574] -layout_mode = 2 -size_flags_horizontal = 3 -size_flags_vertical = 8 -label_settings = SubResource("LabelSettings_bn2o5") - -[node name="Button_StaffManagement" type="Button" parent="HBoxContainer" unique_id=568204305] -layout_mode = 2 -size_flags_horizontal = 3 -size_flags_vertical = 4 -theme_override_fonts/font = ExtResource("1_pa2rn") -theme_override_font_sizes/font_size = 32 +theme = ExtResource("2_ymrsi") text = "管理" -[node name="Button_ResourcesManagement" type="Button" parent="HBoxContainer" unique_id=1424251140] +[node name="Button_ResourcesManagement" type="Button" parent="VBoxContainer/HBoxContainer2" unique_id=1424251140] layout_mode = 2 size_flags_horizontal = 3 -size_flags_vertical = 4 -theme_override_fonts/font = ExtResource("1_pa2rn") -theme_override_font_sizes/font_size = 32 +theme = ExtResource("2_ymrsi") text = "资源" -[node name="Button_Return" type="Button" parent="HBoxContainer" unique_id=867839141] +[node name="Button_Return" type="Button" parent="VBoxContainer/HBoxContainer2" unique_id=867839141] layout_mode = 2 size_flags_horizontal = 3 -size_flags_vertical = 4 -theme_override_fonts/font = ExtResource("1_pa2rn") -theme_override_font_sizes/font_size = 32 +theme = ExtResource("2_ymrsi") text = "返回" -[connection signal="button_up" from="HBoxContainer/SpeedGroup/Button_Pause" to="." method="_on_button_pause_button_up"] -[connection signal="button_up" from="HBoxContainer/Button_StaffManagement" to="." method="_on_button_staff_management_button_up"] -[connection signal="button_up" from="HBoxContainer/Button_Return" to="." method="_on_button_return_button_up"] +[node name="HBoxContainer3" type="HBoxContainer" parent="VBoxContainer" unique_id=2058056395] +layout_mode = 2 + +[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer/HBoxContainer3" unique_id=1608257100] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_stretch_ratio = 25.0 + +[node name="VBoxContainer" type="VBoxContainer" parent="VBoxContainer/HBoxContainer3/HBoxContainer" unique_id=1557830593] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_stretch_ratio = 4.0 + +[node name="HBoxContainer5" type="HBoxContainer" parent="VBoxContainer/HBoxContainer3/HBoxContainer/VBoxContainer" unique_id=967979380] +layout_mode = 2 + +[node name="Label_Time" type="Label" parent="VBoxContainer/HBoxContainer3/HBoxContainer/VBoxContainer/HBoxContainer5" unique_id=671872515] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 8 +theme_override_colors/font_color = Color(0.72, 0.85, 0.78, 1) +text = "时间" +label_settings = ExtResource("3_4k476") + +[node name="Value_Time" type="Label" parent="VBoxContainer/HBoxContainer3/HBoxContainer/VBoxContainer/HBoxContainer5" unique_id=1229577188] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 1 +size_flags_stretch_ratio = 5.0 +theme_override_colors/font_color = Color(0.93, 0.96, 0.88, 1) +label_settings = ExtResource("3_4k476") + +[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer/HBoxContainer3/HBoxContainer/VBoxContainer" unique_id=516862989] +layout_mode = 2 +size_flags_vertical = 3 + +[node name="Label_Currency" type="Label" parent="VBoxContainer/HBoxContainer3/HBoxContainer/VBoxContainer/HBoxContainer" unique_id=766096596] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 1 +theme_override_colors/font_color = Color(0.72, 0.85, 0.78, 1) +text = "灵石" +label_settings = ExtResource("3_4k476") + +[node name="Value_Currency" type="Label" parent="VBoxContainer/HBoxContainer3/HBoxContainer/VBoxContainer/HBoxContainer" unique_id=1150573727] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 1 +size_flags_stretch_ratio = 5.0 +theme_override_colors/font_color = Color(0.93, 0.96, 0.88, 1) +label_settings = ExtResource("3_4k476") + +[node name="HBoxContainer2" type="HBoxContainer" parent="VBoxContainer/HBoxContainer3/HBoxContainer/VBoxContainer" unique_id=2103796675] +layout_mode = 2 + +[node name="Label_Reputation" type="Label" parent="VBoxContainer/HBoxContainer3/HBoxContainer/VBoxContainer/HBoxContainer2" unique_id=985110673] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 8 +theme_override_colors/font_color = Color(0.72, 0.85, 0.78, 1) +text = "声望" +label_settings = ExtResource("3_4k476") + +[node name="Value_Reputation" type="Label" parent="VBoxContainer/HBoxContainer3/HBoxContainer/VBoxContainer/HBoxContainer2" unique_id=2011931119] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 1 +size_flags_stretch_ratio = 5.0 +theme_override_colors/font_color = Color(0.93, 0.96, 0.88, 1) +label_settings = ExtResource("3_4k476") + +[node name="HBoxContainer3" type="HBoxContainer" parent="VBoxContainer/HBoxContainer3/HBoxContainer/VBoxContainer" unique_id=1647418947] +layout_mode = 2 + +[node name="Label_Food" type="Label" parent="VBoxContainer/HBoxContainer3/HBoxContainer/VBoxContainer/HBoxContainer3" unique_id=791000001] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 8 +theme_override_colors/font_color = Color(0.72, 0.85, 0.78, 1) +text = "灵米" +label_settings = ExtResource("3_4k476") + +[node name="Value_Food" type="Label" parent="VBoxContainer/HBoxContainer3/HBoxContainer/VBoxContainer/HBoxContainer3" unique_id=791000002] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 1 +size_flags_stretch_ratio = 5.0 +theme_override_colors/font_color = Color(0.93, 0.96, 0.88, 1) +label_settings = ExtResource("3_4k476") + +[node name="HBoxContainer4" type="HBoxContainer" parent="VBoxContainer/HBoxContainer3/HBoxContainer/VBoxContainer" unique_id=758328210] +layout_mode = 2 + +[node name="Label_Qi" type="Label" parent="VBoxContainer/HBoxContainer3/HBoxContainer/VBoxContainer/HBoxContainer4" unique_id=790000001] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 8 +theme_override_colors/font_color = Color(0.72, 0.85, 0.78, 1) +text = "灵气" +label_settings = ExtResource("3_4k476") + +[node name="Value_Qi" type="Label" parent="VBoxContainer/HBoxContainer3/HBoxContainer/VBoxContainer/HBoxContainer4" unique_id=790000002] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 1 +size_flags_stretch_ratio = 5.0 +theme_override_colors/font_color = Color(0.93, 0.96, 0.88, 1) +label_settings = ExtResource("3_4k476") + +[node name="Label" type="Label" parent="VBoxContainer/HBoxContainer3" unique_id=1867196268] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 1 +size_flags_stretch_ratio = 75.0 + +[connection signal="button_up" from="VBoxContainer/HBoxContainer2/SpeedGroup/Button_Pause" to="." method="_on_button_pause_button_up"] +[connection signal="button_up" from="VBoxContainer/HBoxContainer2/Button_StaffManagement" to="." method="_on_button_staff_management_button_up"] +[connection signal="button_up" from="VBoxContainer/HBoxContainer2/Button_Return" to="." method="_on_button_return_button_up"] diff --git a/src/UI/HUD/top_bar_hud.gd b/src/UI/HUD/top_bar_hud.gd index 7125cf1..674b2f0 100644 --- a/src/UI/HUD/top_bar_hud.gd +++ b/src/UI/HUD/top_bar_hud.gd @@ -1,5 +1,5 @@ ## 顶部信息栏 HUD(挂载于 TopBarHUD.tscn)。 -## 显示灵石/时间/声望,提供时间流速控制与返回主菜单入口。 +## 显示资源(灵石/声望/灵米/灵气浓度)与时间,提供时间流速控制与返回主菜单入口。 extends Control ## 请求返回主菜单。 @@ -11,6 +11,7 @@ signal sign_open_disciples @onready var currency_label: Label = %Value_Currency @onready var reputation_label: Label = %Value_Reputation @onready var qi_label: Label = %Value_Qi +@onready var food_label: Label = %Value_Food @onready var pause_button: Button = %Button_Pause @onready var speed_buttons: Array[Button] = [%Button_Speed1, %Button_Speed5, %Button_Speed20] @@ -24,8 +25,10 @@ func _ready() -> void: # 资源数值:信号仅在变化时触发,初始值需手动设置一次 SectManager.spirit_stones_changed.connect(_on_spirit_stones_changed) SectManager.reputation_changed.connect(_on_reputation_changed) + SectManager.food_changed.connect(_on_food_changed) currency_label.text = str(SectManager.spirit_stones) reputation_label.text = str(SectManager.reputation) + food_label.text = str(SectManager.food) # 灵气浓度:当前为配置固定值(D6 建筑系统接入后动态刷新) qi_label.text = "%d%%" % roundi(GameConfig.qi_concentration * 100) time_label.text = TimeSystem.get_date_text() @@ -46,6 +49,11 @@ func _on_spirit_stones_changed(new_value: int, _delta: int) -> void: func _on_reputation_changed(new_value: int, _delta: int) -> void: reputation_label.text = str(new_value) +## 灵米(食物)变化时刷新显示。 +## @param new_value: 变化后的灵米总量 +func _on_food_changed(new_value: int, _delta: int) -> void: + food_label.text = str(new_value) + ## 点击"返回"按钮。 func _on_button_return_button_up() -> void: sign_return_mainmenu.emit() @@ -69,10 +77,10 @@ func _on_speed_button_up(index: int) -> void: ## 标签共用同一 LabelSettings 资源,改一处全生效;按钮逐个覆盖。 func _apply_hud_font() -> void: var size := GameConfig.hud_font_size - var settings: LabelSettings = $HBoxContainer/Label_Currency.label_settings + var settings: LabelSettings = $VBoxContainer/HBoxContainer3/HBoxContainer/VBoxContainer/HBoxContainer/Label_Currency.label_settings if settings != null: settings.font_size = size - for btn in $HBoxContainer.find_children("*", "Button", true, false): + for btn in $VBoxContainer.find_children("*", "Button", true, false): btn.add_theme_font_size_override("font_size", size) ## 刷新速度组 UI:暂停按钮文字与各档位按下状态。 diff --git a/src/UI/Panels/MainMenu/MainMenu.tscn b/src/UI/Panels/MainMenu/MainMenu.tscn index 852a37d..2bf5a22 100644 --- a/src/UI/Panels/MainMenu/MainMenu.tscn +++ b/src/UI/Panels/MainMenu/MainMenu.tscn @@ -2,7 +2,7 @@ [ext_resource type="Script" uid="uid://drfyh36my6gj2" path="res://src/UI/Panels/MainMenu/MainMenu.gd" id="1_cwvg5"] [ext_resource type="Texture2D" uid="uid://c6bthhmao5fyh" path="res://assets/sprites/ui/图片大门.png" id="2_q7typ"] -[ext_resource type="FontFile" uid="uid://drt448qncx27p" path="res://assets/fonts/dingliezhuhaifont-20240831GengXinBan)-2.ttf" id="3_q7typ"] +[ext_resource type="Theme" uid="uid://ctuanla5trf4s" path="res://resources/main_menu_theme.tres" id="3_7e5ie"] [ext_resource type="PackedScene" uid="uid://dj7b5vssydifa" path="res://src/UI/Panels/SavePanel.tscn" id="3_wrf65"] [node name="MainMenu" type="Control" unique_id=1416317040] @@ -49,29 +49,25 @@ alignment = 1 [node name="NewGame" type="Button" parent="ButtonGroup" unique_id=835084060] custom_minimum_size = Vector2(200, 48) layout_mode = 2 -theme_override_fonts/font = ExtResource("3_q7typ") -theme_override_font_sizes/font_size = 32 +theme = ExtResource("3_7e5ie") text = "新游戏" [node name="LoadGame" type="Button" parent="ButtonGroup" unique_id=2093610529] custom_minimum_size = Vector2(200, 48) layout_mode = 2 -theme_override_fonts/font = ExtResource("3_q7typ") -theme_override_font_sizes/font_size = 32 +theme = ExtResource("3_7e5ie") text = "读取存档" [node name="Settings" type="Button" parent="ButtonGroup" unique_id=2045302694] custom_minimum_size = Vector2(200, 48) layout_mode = 2 -theme_override_fonts/font = ExtResource("3_q7typ") -theme_override_font_sizes/font_size = 32 +theme = ExtResource("3_7e5ie") text = "设置" [node name="Quit" type="Button" parent="ButtonGroup" unique_id=818112870] custom_minimum_size = Vector2(200, 48) layout_mode = 2 -theme_override_fonts/font = ExtResource("3_q7typ") -theme_override_font_sizes/font_size = 32 +theme = ExtResource("3_7e5ie") text = "退出" [node name="SavePanel" parent="." unique_id=619488443 instance=ExtResource("3_wrf65")]