diff --git a/assets/sprites/ui/BG1.png b/assets/sprites/ui/BG1.png new file mode 100644 index 0000000..dda27bb Binary files /dev/null and b/assets/sprites/ui/BG1.png differ diff --git a/assets/sprites/ui/BG1.png.import b/assets/sprites/ui/BG1.png.import new file mode 100644 index 0000000..a0a01f5 --- /dev/null +++ b/assets/sprites/ui/BG1.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://caeqoc6wx8toy" +path="res://.godot/imported/BG1.png-6bf4b9c36da6bbdf71bd2c8203f4cb53.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/sprites/ui/BG1.png" +dest_files=["res://.godot/imported/BG1.png-6bf4b9c36da6bbdf71bd2c8203f4cb53.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/UI/StartMenu.md b/doc/design/UI/StartMenu.md new file mode 100644 index 0000000..dbee937 --- /dev/null +++ b/doc/design/UI/StartMenu.md @@ -0,0 +1,124 @@ +# 开始菜单设计 + +## 一、场景结构 + +采用**单场景 + 子节点切换**方案,仅一个 `MainMenu.tscn`。 + +``` +MainMenu.tscn +├── BG (TextureRect) +│ └── 背景图片 +├── Logo (TextureRect) +│ └── 游戏 Logo +├── ButtonGroup (VBoxContainer) +│ ├── 新游戏按钮 → 显示 NewGamePanel +│ ├── 读取存档按钮 → 显示 LoadGamePanel +│ ├── 设置按钮 → 显示 SettingsPanel +│ └── 退出按钮 → get_tree().quit() +├── NewGamePanel (Panel, 默认隐藏) +│ ├── 宗门名称输入框 (LineEdit) +│ ├── 难度选择 (OptionButton) +│ │ ├── 简单 +│ │ ├── 普通 +│ │ └── 困难 +│ ├── 确认按钮 → 进入游戏 +│ └── 返回按钮 → 隐藏自身 +├── LoadGamePanel (Panel, 默认隐藏) +│ ├── 存档列表 (ItemList) +│ ├── 加载按钮 +│ └── 返回按钮 +└── SettingsPanel (Panel, 默认隐藏) + ├── 音量滑块 (HSlider) + ├── 全屏切换 (CheckBox) + └── 返回按钮 +``` + +## 二、场景节点属性说明 + +### MainMenu(根节点 — Control) + +| 属性 | 值 | 说明 | +|------|----|------| +| `anchors_preset` | 15(Full Rect) | 四角锚定父节点边界 | +| `anchor_right` | 1.0 | 右边缘锚定到父节点右边界 | +| `anchor_bottom` | 1.0 | 下边缘锚定到父节点下边界 | +| `grow_horizontal` | 2 | 控件缩小时向右收缩 | +| `grow_vertical` | 2 | 控件缩小时向下收缩 | +| `size_flags_horizontal` | 3 | Fill + Expand,水平填充可用空间 | +| `size_flags_vertical` | 3 | Fill + Expand,垂直填充可用空间 | + +### BG(TextureRect — 背景) + +| 属性 | 值 | 说明 | +|------|----|------| +| `anchors_preset` | 15(Full Rect) | 铺满父节点 | +| `anchor_right` / `anchor_bottom` | 1.0 | 锚定右下边界 | +| `stretch_mode` | 0(Scale) | 拉伸图片铺满,保持原始比例 | + +### Logo(TextureRect — 游戏 Logo) + +| 属性 | 值 | 说明 | +|------|----|------| +| `anchors_preset` | 1(Top Center) | 顶部居中锚点 | +| `anchor_left` / `anchor_right` | 0.5 | 水平居中 | +| `offset_left` | -200 | 左偏移,使宽度为 400 | +| `offset_right` | 200 | 右偏移 | +| `offset_top` | 60 | 距顶部 60px | +| `offset_bottom` | 260 | 距顶部 260px(高 200) | +| `grow_horizontal` | 2 | 向左收缩 | + +### ButtonGroup(VBoxContainer — 按钮组) + +| 属性 | 值 | 说明 | +|------|----|------| +| `anchors_preset` | 8(Center) | 居中锚定 | +| `anchor_left / top / right / bottom` | 0.5 | 中心点对齐 | +| `offset_left` | -100 | 向左扩展 100px(总宽 200) | +| `offset_right` | 100 | 向右扩展 100px | +| `offset_top` | -80 | 向上扩展 80px(总高 160) | +| `offset_bottom` | 80 | 向下扩展 80px | +| `grow_horizontal` | 2 | 向左收缩 | +| `grow_vertical` | 2 | 向上收缩 | +| `theme_override_constants/separation` | 16 | 按钮间距 16px | + +### Button(子按钮) + +| 属性 | 值 | 说明 | +|------|----|------| +| `custom_minimum_size` | Vector2(200, 48) | 按钮最小尺寸,宽 200 高 48 | +| `text` | "新游戏" 等 | 按钮显示文字 | + +--- + +## 三、面板切换逻辑 + +所有面板放在同一场景内,通过 `visible` 属性切换。 + +```gdscript +func _on_new_game_pressed(): + button_group.hide() + new_game_panel.show() + +func _on_back_pressed(): + new_game_panel.hide() + button_group.show() +``` + +## 四、进入游戏流程 + +新游戏确认后调用: + +```gdscript +func _on_confirm_new_game(): + var sect_name = $NewGamePanel/NameInput.text + var difficulty = $NewGamePanel/Difficulty.selected + # 初始化游戏数据 + GameData.start_new_game(sect_name, difficulty) + get_tree().change_scene_to_file("res://src/main/MainGame.tscn") +``` + +## 五、注意事项 + +- 面板切换使用 `show()` / `hide()`,不销毁节点,保留输入状态 +- 背景和 Logo 可加淡入动画(AnimationPlayer) +- 存档列表数据来源:`ResourceSaver` 序列化的存档文件 diff --git a/doc/design/通用资源分析.md b/doc/design/通用资源分析.md index c28d0f2..03e2251 100644 --- a/doc/design/通用资源分析.md +++ b/doc/design/通用资源分析.md @@ -86,16 +86,16 @@ ```gdscript enum DisplayType { - TOPBAR, # 顶部栏常驻 - PANEL # 面板查看 + TOPBAR, # 顶部栏常驻 + PANEL # 面板查看 } enum ResourceCategory { - CURRENCY, # 货币 - BASIC, # 基础 - CULTIVATION, # 修炼 - CRAFTING, # 锻造 - SPECIAL # 特殊 + CURRENCY, # 货币 + BASIC, # 基础 + CULTIVATION, # 修炼 + CRAFTING, # 锻造 + SPECIAL # 特殊 } ``` diff --git a/project.godot b/project.godot index 3a5e40f..b1aee05 100644 --- a/project.godot +++ b/project.godot @@ -11,6 +11,7 @@ config_version=5 [application] config/name="模拟宗门" +run/main_scene="uid://d1odycoaqhhyg" config/features=PackedStringArray("4.7", "Forward Plus") config/icon="res://icon.svg" diff --git a/src/Core/MainGame.tscn b/src/Core/MainGame.tscn new file mode 100644 index 0000000..2c5ce37 --- /dev/null +++ b/src/Core/MainGame.tscn @@ -0,0 +1,3 @@ +[gd_scene format=3 uid="uid://box7tj5iyiopq"] + +[node name="MainGame" type="Node" unique_id=2053561265] diff --git a/src/UI/Panels/MainMenu/MainMenu.gd b/src/UI/Panels/MainMenu/MainMenu.gd new file mode 100644 index 0000000..ead8985 --- /dev/null +++ b/src/UI/Panels/MainMenu/MainMenu.gd @@ -0,0 +1,18 @@ +extends Control + + +func MainMenu_NewGame_ButtonUp() -> void: + pass # Replace with function body. + + +func MainMenu_LoadGame_ButtonUp() -> void: + pass # Replace with function body. + + +func MainMenu_Settings_ButtonUp() -> void: + pass # Replace with function body. + + +func MainMenu_Quit_ButtonUp() -> void: + get_tree().quit(); + pass # Replace with function body. diff --git a/src/UI/Panels/MainMenu/MainMenu.gd.uid b/src/UI/Panels/MainMenu/MainMenu.gd.uid new file mode 100644 index 0000000..1a53b52 --- /dev/null +++ b/src/UI/Panels/MainMenu/MainMenu.gd.uid @@ -0,0 +1 @@ +uid://drfyh36my6gj2 diff --git a/src/UI/Panels/MainMenu/MainMenu.tscn b/src/UI/Panels/MainMenu/MainMenu.tscn new file mode 100644 index 0000000..1824571 --- /dev/null +++ b/src/UI/Panels/MainMenu/MainMenu.tscn @@ -0,0 +1,73 @@ +[gd_scene format=3 uid="uid://d1odycoaqhhyg"] + +[ext_resource type="Script" uid="uid://drfyh36my6gj2" path="res://src/UI/Panels/MainMenu/MainMenu.gd" id="1_cwvg5"] +[ext_resource type="Texture2D" uid="uid://caeqoc6wx8toy" path="res://assets/sprites/ui/BG1.png" id="1_hrti0"] + +[node name="MainMenu" type="Control" unique_id=1416317040] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 +script = ExtResource("1_cwvg5") + +[node name="BG" type="TextureRect" parent="." unique_id=2104369666] +layout_mode = 0 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +texture = ExtResource("1_hrti0") + +[node name="Logo" type="TextureRect" parent="." unique_id=1485724026] +layout_mode = 1 +anchors_preset = 5 +anchor_left = 0.5 +anchor_right = 0.5 +offset_left = -200.0 +offset_top = 60.0 +offset_right = 200.0 +offset_bottom = 260.0 +grow_horizontal = 2 + +[node name="ButtonGroup" type="VBoxContainer" parent="." unique_id=569064410] +layout_mode = 0 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -100.0 +offset_top = -80.0 +offset_right = 100.0 +offset_bottom = 80.0 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_constants/separation = 16 + +[node name="NewGame" type="Button" parent="ButtonGroup" unique_id=835084060] +custom_minimum_size = Vector2(200, 48) +layout_mode = 2 +text = "新游戏" + +[node name="LoadGame" type="Button" parent="ButtonGroup" unique_id=2093610529] +custom_minimum_size = Vector2(200, 48) +layout_mode = 2 +text = "读取存档" + +[node name="Settings" type="Button" parent="ButtonGroup" unique_id=2045302694] +custom_minimum_size = Vector2(200, 48) +layout_mode = 2 +text = "设置" + +[node name="Quit" type="Button" parent="ButtonGroup" unique_id=818112870] +custom_minimum_size = Vector2(200, 48) +layout_mode = 2 +text = "退出" + +[connection signal="button_up" from="ButtonGroup/NewGame" to="." method="MainMenu_NewGame_ButtonUp"] +[connection signal="button_up" from="ButtonGroup/LoadGame" to="." method="MainMenu_LoadGame_ButtonUp"] +[connection signal="button_up" from="ButtonGroup/Settings" to="." method="MainMenu_Settings_ButtonUp"] +[connection signal="button_up" from="ButtonGroup/Quit" to="." method="MainMenu_Quit_ButtonUp"] diff --git a/src/UI/Panels/StartMenu.tscn b/src/UI/Panels/StartMenu.tscn deleted file mode 100644 index 7ee1f53..0000000 --- a/src/UI/Panels/StartMenu.tscn +++ /dev/null @@ -1,16 +0,0 @@ -[gd_scene format=3 uid="uid://bkatopgh40fte"] - -[ext_resource type="PackedScene" uid="uid://dl0tb68vsw3c6" path="res://src/UI/HUD/TopBarHUD.tscn" id="1_jy7gm"] - -[node name="StartMenu" type="Control" unique_id=1272477823] -layout_mode = 3 -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -grow_horizontal = 2 -grow_vertical = 2 - -[node name="TopBarHud" parent="." unique_id=1115394694 instance=ExtResource("1_jy7gm")] -custom_minimum_size = Vector2(100, 100) -custom_maximum_size = Vector2(100, 100) -layout_mode = 0