初始化仓库

This commit is contained in:
2026-08-10 23:35:23 +08:00
commit 8399ee5664
48 changed files with 1097 additions and 0 deletions
+4
View File
@@ -0,0 +1,4 @@
root = true
[*]
charset = utf-8
+2
View File
@@ -0,0 +1,2 @@
# Normalize EOL for all files that Git considers text files.
* text=auto eol=lf
+3
View File
@@ -0,0 +1,3 @@
# Godot 4+ specific ignores
.godot/
/android/
Binary file not shown.
@@ -0,0 +1,36 @@
[remap]
importer="font_data_dynamic"
type="FontFile"
uid="uid://dme1iomr5u0e7"
path="res://.godot/imported/LXGWWenKai-Light.ttf-ec3765d1a28f599b542e80b43c54944c.fontdata"
[deps]
source_file="res://assets/fonts/lxgw-wenkai-v1.522/LXGWWenKai-Light.ttf"
dest_files=["res://.godot/imported/LXGWWenKai-Light.ttf-ec3765d1a28f599b542e80b43c54944c.fontdata"]
[params]
Rendering=null
antialiasing=1
generate_mipmaps=false
disable_embedded_bitmaps=true
multichannel_signed_distance_field=false
msdf_pixel_range=8
msdf_size=48
allow_system_fallback=true
force_autohinter=false
modulate_color_glyphs=false
hinting=3
subpixel_positioning=4
keep_rounding_remainders=true
oversampling=0.0
Fallbacks=null
fallbacks=[]
Compress=null
compress=true
preload=[]
language_support={}
script_support={}
opentype_features={}
@@ -0,0 +1,36 @@
[remap]
importer="font_data_dynamic"
type="FontFile"
uid="uid://vjxlelc2r2lk"
path="res://.godot/imported/LXGWWenKai-Medium.ttf-7874def67b3cdf89ec9f04c454f74b51.fontdata"
[deps]
source_file="res://assets/fonts/lxgw-wenkai-v1.522/LXGWWenKai-Medium.ttf"
dest_files=["res://.godot/imported/LXGWWenKai-Medium.ttf-7874def67b3cdf89ec9f04c454f74b51.fontdata"]
[params]
Rendering=null
antialiasing=1
generate_mipmaps=false
disable_embedded_bitmaps=true
multichannel_signed_distance_field=false
msdf_pixel_range=8
msdf_size=48
allow_system_fallback=true
force_autohinter=false
modulate_color_glyphs=false
hinting=3
subpixel_positioning=4
keep_rounding_remainders=true
oversampling=0.0
Fallbacks=null
fallbacks=[]
Compress=null
compress=true
preload=[]
language_support={}
script_support={}
opentype_features={}
@@ -0,0 +1,36 @@
[remap]
importer="font_data_dynamic"
type="FontFile"
uid="uid://duxymf2xy66em"
path="res://.godot/imported/LXGWWenKai-Regular.ttf-4b7a37620712eb3c5b0811a13ce812d9.fontdata"
[deps]
source_file="res://assets/fonts/lxgw-wenkai-v1.522/LXGWWenKai-Regular.ttf"
dest_files=["res://.godot/imported/LXGWWenKai-Regular.ttf-4b7a37620712eb3c5b0811a13ce812d9.fontdata"]
[params]
Rendering=null
antialiasing=1
generate_mipmaps=false
disable_embedded_bitmaps=true
multichannel_signed_distance_field=false
msdf_pixel_range=8
msdf_size=48
allow_system_fallback=true
force_autohinter=false
modulate_color_glyphs=false
hinting=3
subpixel_positioning=4
keep_rounding_remainders=true
oversampling=0.0
Fallbacks=null
fallbacks=[]
Compress=null
compress=true
preload=[]
language_support={}
script_support={}
opentype_features={}
@@ -0,0 +1,36 @@
[remap]
importer="font_data_dynamic"
type="FontFile"
uid="uid://dv0mnlx0fqjad"
path="res://.godot/imported/LXGWWenKaiMono-Light.ttf-578c556e63460fe509a3eed7b0e20444.fontdata"
[deps]
source_file="res://assets/fonts/lxgw-wenkai-v1.522/LXGWWenKaiMono-Light.ttf"
dest_files=["res://.godot/imported/LXGWWenKaiMono-Light.ttf-578c556e63460fe509a3eed7b0e20444.fontdata"]
[params]
Rendering=null
antialiasing=1
generate_mipmaps=false
disable_embedded_bitmaps=true
multichannel_signed_distance_field=false
msdf_pixel_range=8
msdf_size=48
allow_system_fallback=true
force_autohinter=false
modulate_color_glyphs=false
hinting=3
subpixel_positioning=4
keep_rounding_remainders=true
oversampling=0.0
Fallbacks=null
fallbacks=[]
Compress=null
compress=true
preload=[]
language_support={}
script_support={}
opentype_features={}
@@ -0,0 +1,36 @@
[remap]
importer="font_data_dynamic"
type="FontFile"
uid="uid://b0sai8dfnn2vq"
path="res://.godot/imported/LXGWWenKaiMono-Medium.ttf-9bcb20d0cda8b7e7290f1845c17ae4dc.fontdata"
[deps]
source_file="res://assets/fonts/lxgw-wenkai-v1.522/LXGWWenKaiMono-Medium.ttf"
dest_files=["res://.godot/imported/LXGWWenKaiMono-Medium.ttf-9bcb20d0cda8b7e7290f1845c17ae4dc.fontdata"]
[params]
Rendering=null
antialiasing=1
generate_mipmaps=false
disable_embedded_bitmaps=true
multichannel_signed_distance_field=false
msdf_pixel_range=8
msdf_size=48
allow_system_fallback=true
force_autohinter=false
modulate_color_glyphs=false
hinting=3
subpixel_positioning=4
keep_rounding_remainders=true
oversampling=0.0
Fallbacks=null
fallbacks=[]
Compress=null
compress=true
preload=[]
language_support={}
script_support={}
opentype_features={}
@@ -0,0 +1,36 @@
[remap]
importer="font_data_dynamic"
type="FontFile"
uid="uid://dsp8stow5ndhc"
path="res://.godot/imported/LXGWWenKaiMono-Regular.ttf-2931aa1fc087599321bf814a8ef180f6.fontdata"
[deps]
source_file="res://assets/fonts/lxgw-wenkai-v1.522/LXGWWenKaiMono-Regular.ttf"
dest_files=["res://.godot/imported/LXGWWenKaiMono-Regular.ttf-2931aa1fc087599321bf814a8ef180f6.fontdata"]
[params]
Rendering=null
antialiasing=1
generate_mipmaps=false
disable_embedded_bitmaps=true
multichannel_signed_distance_field=false
msdf_pixel_range=8
msdf_size=48
allow_system_fallback=true
force_autohinter=false
modulate_color_glyphs=false
hinting=3
subpixel_positioning=4
keep_rounding_remainders=true
oversampling=0.0
Fallbacks=null
fallbacks=[]
Compress=null
compress=true
preload=[]
language_support={}
script_support={}
opentype_features={}
+94
View File
@@ -0,0 +1,94 @@
Copyright 2021-2026 LXGW (https://github.com/lxgw/LxgwWenKai)
Copyright 2020 The Klee Project Authors (https://github.com/fontworks-fonts/Klee)
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
https://openfontlicense.org
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 MiB

+40
View File
@@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://yosl3o8yjyks"
path="res://.godot/imported/图片大门.png-03ea66f8e1eb82ba7952374321f00064.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/sprites/ui/图片大门.png"
dest_files=["res://.godot/imported/图片大门.png-03ea66f8e1eb82ba7952374321f00064.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
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 MiB

+40
View File
@@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bofyisl3opy18"
path="res://.godot/imported/宗门全景.png-d969df84bf06c400df6e36c494864bbe.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/sprites/ui/宗门全景.png"
dest_files=["res://.godot/imported/宗门全景.png-d969df84bf06c400df6e36c494864bbe.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
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 MiB

+40
View File
@@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://b31gywmlagrbw"
path="res://.godot/imported/宗门后山.png-7a9df51075ec2cc8660f9ccd87b9a616.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/sprites/ui/宗门后山.png"
dest_files=["res://.godot/imported/宗门后山.png-7a9df51075ec2cc8660f9ccd87b9a616.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
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 MiB

+40
View File
@@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cveohqimqn1rq"
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
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 MiB

+40
View File
@@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cl8abjnqbrx01"
path="res://.godot/imported/灵石矿.png-ecb322a78c1d966bfd5ce47475fa7fb5.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/sprites/ui/灵石矿.png"
dest_files=["res://.godot/imported/灵石矿.png-ecb322a78c1d966bfd5ce47475fa7fb5.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
+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128"><rect width="124" height="124" x="2" y="2" fill="#363d52" stroke="#212532" stroke-width="4" rx="14"/><g fill="#fff" transform="translate(12.322 12.322)scale(.101)"><path d="M105 673v33q407 354 814 0v-33z"/><path fill="#478cbf" d="m105 673 152 14q12 1 15 14l4 67 132 10 8-61q2-11 15-15h162q13 4 15 15l8 61 132-10 4-67q3-13 15-14l152-14V427q30-39 56-81-35-59-83-108-43 20-82 47-40-37-88-64 7-51 8-102-59-28-123-42-26 43-46 89-49-7-98 0-20-46-46-89-64 14-123 42 1 51 8 102-48 27-88 64-39-27-82-47-48 49-83 108 26 42 56 81zm0 33v39c0 276 813 276 814 0v-39l-134 12-5 69q-2 10-14 13l-162 11q-12 0-16-11l-10-65H446l-10 65q-4 11-16 11l-162-11q-12-3-14-13l-5-69z"/><path d="M483 600c0 34 58 34 58 0v-86c0-34-58-34-58 0z"/><circle cx="725" cy="526" r="90"/><circle cx="299" cy="526" r="90"/></g><g fill="#414042" transform="translate(12.322 12.322)scale(.101)"><circle cx="307" cy="532" r="60"/><circle cx="717" cy="532" r="60"/></g></svg>

After

Width:  |  Height:  |  Size: 995 B

+43
View File
@@ -0,0 +1,43 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cmq11s40d4wom"
path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://icon.svg"
dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.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
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false
+39
View File
@@ -0,0 +1,39 @@
; Engine configuration file.
; It's best edited using the editor UI and not directly,
; since the parameters that go here are not all obvious.
;
; Format:
; [section] ; section goes between []
; param=value ; assign values to parameters
config_version=5
[application]
config/name="仙宗"
run/main_scene="uid://c1exffg84ojqx"
config/features=PackedStringArray("4.7", "Forward Plus")
config/icon="res://icon.svg"
[autoload]
GameState="*res://src/Core/GameState.gd"
TimeSystem="*res://src/Core/TimeSystem.gd"
Settings="*res://src/Core/Settings.gd"
GameConfig="*res://src/Core/GameConfig.gd"
[display]
window/size/viewport_width=1280
window/size/viewport_height=720
window/stretch/mode="canvas_items"
window/stretch/aspect="expand"
[physics]
3d/physics_engine="Jolt Physics"
[rendering]
rendering_device/driver.windows="d3d12"
+7
View File
@@ -0,0 +1,7 @@
[gd_resource type="Theme" format=3 uid="uid://b3cyleh82wiq4"]
[ext_resource type="FontFile" uid="uid://dsp8stow5ndhc" path="res://assets/fonts/lxgw-wenkai-v1.522/LXGWWenKaiMono-Regular.ttf" id="1_c7a8v"]
[resource]
default_font = ExtResource("1_c7a8v")
default_font_size = 32
+7
View File
@@ -0,0 +1,7 @@
[gd_resource type="Theme" format=3 uid="uid://btnjeju2d47x8"]
[ext_resource type="FontFile" uid="uid://dsp8stow5ndhc" path="res://assets/fonts/lxgw-wenkai-v1.522/LXGWWenKaiMono-Regular.ttf" id="1_ayi8a"]
[resource]
default_font = ExtResource("1_ayi8a")
default_font_size = 24
+9
View File
@@ -0,0 +1,9 @@
[gd_resource type="LabelSettings" format=3 uid="uid://bn06sljdiloor"]
[ext_resource type="FontFile" uid="uid://dsp8stow5ndhc" path="res://assets/fonts/lxgw-wenkai-v1.522/LXGWWenKaiMono-Regular.ttf" id="1_wrmha"]
[resource]
font = ExtResource("1_wrmha")
font_size = 24
outline_size = 2
outline_color = Color(0, 0, 0, 1)
+36
View File
@@ -0,0 +1,36 @@
## 全局游戏状态(Autoload 单例)。
## 负责场景间参数传递与会话状态管理,不持有游戏内数据。
extends Node
## 进入游戏的方式。
enum GameMode { NEW_GAME, LOAD_GAME }
## 当前进入游戏的方式。
var mode: GameMode = GameMode.NEW_GAME
## 当前存档组 ID(两级存档第一级,SaveSystem 分配)。
var profile_id: int = 0
## 要加载的槽位文件名(仅 LOAD_GAME 时有效,如 "auto"/"slot_1754734800")。
var save_slot: String = ""
# 游戏内时间(12 月 × 30 天 = 360 天/年),实际推进由 TimeSystem 负责
var year: int = 1 # 年
var month: int = 1 # 月(1-12
var day: int = 1 # 日(1-30
## 请求开始新游戏。
## @param pid: 新存档组 ID(主菜单创建)
func request_new_game(pid: int) -> void:
mode = GameMode.NEW_GAME
profile_id = pid
save_slot = ""
year = 1
month = 1
day = 1
## 请求加载指定存档。
## @param pid: 存档组 ID
## @param slot_name: 槽位文件名(不含 .json
func request_load_game(pid: int, slot_name: String) -> void:
mode = GameMode.LOAD_GAME
profile_id = pid
save_slot = slot_name
+1
View File
@@ -0,0 +1 @@
uid://c0o83k384x3wp
+7
View File
@@ -0,0 +1,7 @@
[gd_scene format=3 uid="uid://c1exffg84ojqx"]
[ext_resource type="PackedScene" uid="uid://q1b6t22ej3ej" path="res://src/UI/Panels/MainMenu/MainMenu.tscn" id="1_g6xmk"]
[node name="MainGame" type="Node" unique_id=42551660]
[node name="MainMenu" parent="." unique_id=285750365 instance=ExtResource("1_g6xmk")]
+21
View File
@@ -0,0 +1,21 @@
## 用户设置(Autoload 单例)。
## 负责个人偏好设置的持久化,保存于 user:// 目录,与游戏存档分离。
extends Node
## 设置文件的保存路径。
const SAVE_PATH := "user://settings.cfg"
## 新游戏开局时的默认流速档位索引(1 = 5x)。
var default_speed_index := 1
## 从磁盘加载设置(不存在则保持默认值)。
func load_settings() -> void:
var cfg := ConfigFile.new()
if cfg.load(SAVE_PATH) == OK:
default_speed_index = cfg.get_value("time", "speed_index", 1)
## 将当前设置写入磁盘。
func save_settings() -> void:
var cfg := ConfigFile.new()
cfg.set_value("time", "speed_index", default_speed_index)
cfg.save(SAVE_PATH)
+1
View File
@@ -0,0 +1 @@
uid://dpnjkyle57umm
+139
View File
@@ -0,0 +1,139 @@
## 全局时间系统(Autoload 单例)。
## 负责游戏时间的推进与播报,仅在世界场景中运行。
## 历法:12 月 × 30 日 = 360 日/年。
extends Node
## 每当推进一日后发出。
## @param year: 当前年份
## @param month: 当前月份(1-12
## @param day: 当前日(1-30
signal day_passed(year: int, month: int, day: int)
## 每当进入新月份时发出(同一天内 day_passed 之后)。
## @param year: 当前年份
## @param month: 当前月份(1-12
signal month_passed(year: int, month: int)
## 每当进入新年份时发出(同一天内 month_passed 之后)。
## @param year: 当前年份
signal year_passed(year: int)
## 时间流速档位变化时发出。
## @param speed_index: 新档位在 SPEEDS 中的索引
signal speed_changed(speed_index: int)
## 暂停状态变化时发出。
## @param paused: 是否已暂停
signal pause_changed(paused: bool)
## 可选的时间流速倍率档位。
const SPEEDS := [1.0, 5.0, 20.0]
## 每月的天数。
const DAYS_PER_MONTH := 30
## 每年的月数。
const MONTHS_PER_YEAR := 12
## 现实世界每 1 天对应的时长(秒)。
const DAY_LENGTH := 0.5
## 当前流速档位在 SPEEDS 中的索引。
var speed_index := 0
## 当前流速倍率(与 SPEEDS[speed_index] 保持一致)。
var speed := 1.0
## 是否暂停时间推进。
var paused := false
## 已累积的现实时间(秒),未满 1 天。
var _elapsed := 0.0
## 每帧累积时间,满一天推进日期(仅游戏世界场景内)。
func _process(delta: float) -> void:
if paused or not _is_in_game():
return
_elapsed += delta * speed
if _elapsed >= DAY_LENGTH:
_elapsed -= DAY_LENGTH
_advance()
## 判断当前场景是否为游戏世界场景(主菜单/存档界面不推进时间)。
## 通过 "game_scene" 分组识别,而非场景名。
func _is_in_game() -> bool:
var scene := get_tree().current_scene
return scene != null and scene.is_in_group("game_scene")
## 推进一日并广播对应信号,跨月/跨年时补发 month_passed / year_passed。
func _advance() -> void:
var new_month := false
var new_year := false
GameState.day += 1
if GameState.day > DAYS_PER_MONTH:
GameState.day = 1
GameState.month += 1
new_month = true
if GameState.month > MONTHS_PER_YEAR:
GameState.month = 1
GameState.year += 1
new_year = true
day_passed.emit(GameState.year, GameState.month, GameState.day)
if new_month:
month_passed.emit(GameState.year, GameState.month)
if new_year:
year_passed.emit(GameState.year)
## 循环切换下一档流速,返回新倍率。
func cycle_speed() -> float:
speed_index = (speed_index + 1) % SPEEDS.size()
speed = SPEEDS[speed_index]
speed_changed.emit(speed_index)
return speed
## 应用用户设置中的默认流速档位(新游戏开局调用)。
func apply_default_speed() -> void:
set_speed_index(Settings.default_speed_index)
## 直接设置流速档位(越界自动钳制)。
## @param index: 目标档位索引
func set_speed_index(index: int) -> void:
speed_index = clampi(index, 0, SPEEDS.size() - 1)
speed = SPEEDS[speed_index]
speed_changed.emit(speed_index)
## 切换暂停状态,返回切换后的暂停状态。
func toggle_pause() -> bool:
paused = not paused
pause_changed.emit(paused)
return paused
## 显式设置暂停状态(幂等,状态未变化时不发信号)。
## @param value: 目标暂停状态
func set_paused(value: bool) -> void:
if paused == value:
return
paused = value
pause_changed.emit(paused)
## 当前流速的显示文本,如 "x5"。
func get_speed_label() -> String:
return "x%d" % int(speed)
## 当前日期数组 [年, 月, 日]。
func get_current_date() -> Array:
return [GameState.year, GameState.month, GameState.day]
## 当前日期文本,如 "3年 5月 12日"。
func get_date_text() -> String:
return "%d%d%d" % [GameState.year, GameState.month, GameState.day]
## 直接设置日期(供读档/测试使用)。
## @param y: 年
## @param m: 月(1-12
## @param d: 日(1-30
func set_date(y: int, m: int, d: int) -> void:
GameState.year = y
GameState.month = m
GameState.day = d
+1
View File
@@ -0,0 +1 @@
uid://b8f8t2phmhq2e
+28
View File
@@ -0,0 +1,28 @@
extends Control
func _ready() -> void:
pass
func _on_MainMenu_NewGame_ButtonUp() -> void:
pass # Replace with function body.
func _on_MainMenu_LoadGame_ButtonUp() -> void:
$Menu.hide()
$SavePannel.show()
pass # Replace with function body.
func _on_MainMenu_Settings_ButtonUp() -> void:
pass # Replace with function body.
func _on_MainMenu_Exit_ButtonUp() -> void:
get_tree().quit()
pass # Replace with function body.
func _on_SavePannel_Esc_pressed() -> void:
$SavePannel.hide()
$Menu.show()
pass # Replace with function body.
+1
View File
@@ -0,0 +1 @@
uid://re0q67p6ppnv
+74
View File
@@ -0,0 +1,74 @@
[gd_scene format=3 uid="uid://q1b6t22ej3ej"]
[ext_resource type="Texture2D" uid="uid://yosl3o8yjyks" path="res://assets/sprites/ui/图片大门.png" id="1_hrti0"]
[ext_resource type="Script" uid="uid://re0q67p6ppnv" path="res://src/UI/Panels/MainMenu/MainMenu.gd" id="1_wrf65"]
[ext_resource type="Theme" uid="uid://b3cyleh82wiq4" path="res://resources/mainmenu_button_theme.tres" id="2_cwvg5"]
[ext_resource type="PackedScene" uid="uid://cqdytnp2v07v" path="res://src/UI/Panels/SavePannel.tscn" id="4_q7typ"]
[node name="MainMenu" type="Control" unique_id=285750365]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_wrf65")
[node name="BG" type="TextureRect" parent="." unique_id=1279813992]
layout_mode = 1
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
texture = ExtResource("1_hrti0")
expand_mode = 2
[node name="Menu" type="CenterContainer" parent="." unique_id=684900922]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
[node name="VBoxContainer" type="VBoxContainer" parent="Menu" unique_id=313362564]
custom_minimum_size = Vector2(400, 0)
layout_mode = 2
alignment = 1
[node name="ButtonNewGame" type="Button" parent="Menu/VBoxContainer" unique_id=1170524877]
layout_mode = 2
size_flags_vertical = 3
theme = ExtResource("2_cwvg5")
text = "新游戏"
[node name="ButtonLoadGame" type="Button" parent="Menu/VBoxContainer" unique_id=145977970]
layout_mode = 2
size_flags_vertical = 3
theme = ExtResource("2_cwvg5")
text = "加载游戏"
[node name="ButtonSettings" type="Button" parent="Menu/VBoxContainer" unique_id=1526312497]
layout_mode = 2
size_flags_vertical = 3
theme = ExtResource("2_cwvg5")
text = "设置"
[node name="ButtonExit" type="Button" parent="Menu/VBoxContainer" unique_id=1558322531]
layout_mode = 2
size_flags_vertical = 3
theme = ExtResource("2_cwvg5")
text = "退出"
[node name="SavePannel" parent="." unique_id=1536921001 instance=ExtResource("4_q7typ")]
visible = false
layout_mode = 1
[connection signal="button_up" from="Menu/VBoxContainer/ButtonNewGame" to="." method="_on_MainMenu_NewGame_ButtonUp"]
[connection signal="button_up" from="Menu/VBoxContainer/ButtonLoadGame" to="." method="_on_MainMenu_LoadGame_ButtonUp"]
[connection signal="button_up" from="Menu/VBoxContainer/ButtonSettings" to="." method="_on_MainMenu_Settings_ButtonUp"]
[connection signal="button_up" from="Menu/VBoxContainer/ButtonExit" to="." method="_on_MainMenu_Exit_ButtonUp"]
[connection signal="save_panel_esc_pressed" from="SavePannel" to="." method="_on_SavePannel_Esc_pressed"]
+33
View File
@@ -0,0 +1,33 @@
## 存档面板(挂载于 SavePanel.tscn)。
## 两级浏览:左侧存档组列表 → 右侧该组槽位列表。
## 存档模式(游戏内):点"新建存档"每次创建新槽位;读档模式(主菜单):点槽位读档。
extends Panel
## 面板模式。
enum Mode { SAVE, LOAD }
## 请求关闭面板(返回上级界面)。
signal save_panel_esc_pressed
## 槽位条目场景。
const SAVE_SLOT_SCENE := preload("res://src/UI/Panels/SaveSlot.tscn")
#@onready var title_label: Label = %TitleLabel
#@onready var group_container: VBoxContainer = %GroupContainer
#@onready var slot_list: VBoxContainer = %SlotList
#@onready var new_slot_button: Button = %Button_NewSlot
## 当前模式。
var mode: Mode = Mode.LOAD
## 当前浏览的存档组 ID。
#var _current_profile: int = 0
### 打开面板前的暂停状态(存档模式关闭时恢复)。
#var _was_paused := false
func _on_SavePanel_Esc_ButtonUp() -> void:
save_panel_esc_pressed.emit()
pass # Replace with function body.
func _on_SavePanel_NewSlot_ButtonUp() -> void:
pass # Replace with function body.
+1
View File
@@ -0,0 +1 @@
uid://dhh02xtieoq2s
+72
View File
@@ -0,0 +1,72 @@
[gd_scene format=3 uid="uid://cqdytnp2v07v"]
[ext_resource type="Script" uid="uid://dhh02xtieoq2s" path="res://src/UI/Panels/SavePannel.gd" id="1_lyly3"]
[ext_resource type="Theme" uid="uid://btnjeju2d47x8" path="res://resources/save_menu_button_theme.tres" id="2_bgsuy"]
[ext_resource type="LabelSettings" uid="uid://bn06sljdiloor" path="res://resources/save_menu_label_settings.tres" id="2_i6d4q"]
[node name="SavePannel" type="Panel" unique_id=1536921001]
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_lyly3")
[node name="VBoxContainer" type="VBoxContainer" parent="." unique_id=56335316]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer" unique_id=718817298]
layout_mode = 2
size_flags_vertical = 3
[node name="TitleLabel" type="Label" parent="VBoxContainer/HBoxContainer" unique_id=2128647553]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 1
text = "选择存档"
label_settings = ExtResource("2_i6d4q")
horizontal_alignment = 1
vertical_alignment = 1
[node name="Spacer" type="Control" parent="VBoxContainer/HBoxContainer" unique_id=187185831]
layout_mode = 2
size_flags_horizontal = 3
size_flags_stretch_ratio = 5.0
[node name="Button_NewSlot" type="Button" parent="VBoxContainer/HBoxContainer" unique_id=657984753]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
theme = ExtResource("2_bgsuy")
text = "新建存档"
[node name="Button_Esc" type="Button" parent="VBoxContainer/HBoxContainer" unique_id=272892241]
layout_mode = 2
size_flags_horizontal = 3
theme = ExtResource("2_bgsuy")
text = "返回"
[node name="ScrollContainer" type="ScrollContainer" parent="VBoxContainer" unique_id=520657017]
layout_mode = 2
size_flags_vertical = 3
size_flags_stretch_ratio = 15.0
[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer/ScrollContainer" unique_id=1858690088]
layout_mode = 2
[node name="GroupContainer" type="VBoxContainer" parent="VBoxContainer/ScrollContainer/HBoxContainer" unique_id=1215509679]
unique_name_in_owner = true
layout_mode = 2
[node name="SaveSlotList" type="VBoxContainer" parent="VBoxContainer/ScrollContainer/HBoxContainer" unique_id=1157397953]
unique_name_in_owner = true
layout_mode = 2
[connection signal="button_up" from="VBoxContainer/HBoxContainer/Button_NewSlot" to="." method="_on_SavePanel_NewSlot_ButtonUp"]
[connection signal="button_up" from="VBoxContainer/HBoxContainer/Button_Esc" to="." method="_on_SavePanel_Esc_ButtonUp"]
+1
View File
@@ -0,0 +1 @@
extends Panel
+1
View File
@@ -0,0 +1 @@
uid://b3kck4qod545u
+55
View File
@@ -0,0 +1,55 @@
[gd_scene format=3 uid="uid://d1fw0ofrshjir"]
[ext_resource type="Script" uid="uid://b3kck4qod545u" path="res://src/UI/Panels/SaveSlot.gd" id="1_gsy4a"]
[ext_resource type="LabelSettings" uid="uid://bn06sljdiloor" path="res://resources/save_menu_label_settings.tres" id="2_lm8et"]
[ext_resource type="Theme" uid="uid://btnjeju2d47x8" path="res://resources/save_menu_button_theme.tres" id="2_m8lv8"]
[node name="SaveSlot" type="Panel" unique_id=815772812]
anchors_preset = 14
anchor_top = 0.5
anchor_right = 1.0
anchor_bottom = 0.5
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_gsy4a")
[node name="HBoxContainer" type="HBoxContainer" parent="." unique_id=1394744552]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
[node name="SlotIndexLabel" type="Label" parent="HBoxContainer" unique_id=1779842797]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 1
label_settings = ExtResource("2_lm8et")
horizontal_alignment = 1
vertical_alignment = 1
[node name="VBoxContainer" type="VBoxContainer" parent="HBoxContainer" unique_id=1166688104]
layout_mode = 2
size_flags_horizontal = 3
size_flags_stretch_ratio = 15.0
[node name="SaveNameLabel" type="Label" parent="HBoxContainer/VBoxContainer" unique_id=391910928]
layout_mode = 2
size_flags_vertical = 3
[node name="SaveSlotInfo" type="Label" parent="HBoxContainer/VBoxContainer" unique_id=125642674]
layout_mode = 2
size_flags_vertical = 3
[node name="ButtonDelete" type="Button" parent="HBoxContainer" unique_id=250829961]
layout_mode = 2
size_flags_horizontal = 3
theme = ExtResource("2_m8lv8")
text = "删除"
[node name="ButtonLoad" type="Button" parent="HBoxContainer" unique_id=1197277104]
layout_mode = 2
size_flags_horizontal = 3
theme = ExtResource("2_m8lv8")
text = "▶"