Compare commits
No commits in common. '9c7fc660ccc5a649cc16013402a0a0d0527e9f4a' and '07b438313608b4feded5fb8c008bfdb150b833f8' have entirely different histories.
9c7fc660cc
...
07b4383136
@ -1,5 +0,0 @@
|
|||||||
[gd_scene format=3 uid="uid://dw6hyqtfehxqr"]
|
|
||||||
|
|
||||||
[node name="BackgroundMusicPlayer" type="AudioStreamPlayer"]
|
|
||||||
autoplay = true
|
|
||||||
bus = &"Music"
|
|
@ -1,25 +1,73 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace CMSGame
|
namespace CMSGame
|
||||||
{
|
{
|
||||||
public record class GameSettings
|
/// <summary>
|
||||||
|
/// ÓÎÏ·ÉèÖó־û¯
|
||||||
|
///
|
||||||
|
/// TODO Ìí¼Ó VideoSettings ²¢Öع¹
|
||||||
|
/// </summary>
|
||||||
|
public partial class GameSettings : Node
|
||||||
|
{
|
||||||
|
public BattleSettings? OriginalBattleSettings;
|
||||||
|
|
||||||
|
public BattleSettings BattleSettings { set; get; } = new();
|
||||||
|
|
||||||
|
protected string BattleSettingsSavePath = new GodotPath("user://Settings/BattleSettings.json");
|
||||||
|
|
||||||
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
|
MakeDirectories();
|
||||||
|
|
||||||
|
OriginalBattleSettings = GetSettings<BattleSettings>(BattleSettingsSavePath);
|
||||||
|
BattleSettings = OriginalBattleSettings with { };
|
||||||
}
|
}
|
||||||
|
|
||||||
public record class BattleSettings : GameSettings
|
public override void _ExitTree()
|
||||||
{ }
|
{
|
||||||
|
if (BattleSettings != OriginalBattleSettings)
|
||||||
|
{
|
||||||
|
SaveSettings(BattleSettingsSavePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public record class VideoSettings : GameSettings
|
private void MakeDirectories()
|
||||||
{ }
|
{
|
||||||
|
DirAccess.MakeDirRecursiveAbsolute("user://Settings/");
|
||||||
|
}
|
||||||
|
|
||||||
public record class AudioSettings : GameSettings
|
private TSettings GetSettings<TSettings>(string path)
|
||||||
|
where TSettings : SettingsBase, new()
|
||||||
{
|
{
|
||||||
/// <summary>
|
string settings_text = ReadFileAsString(path);
|
||||||
/// 音乐音量
|
var settings = JsonConvert.DeserializeObject<TSettings>(settings_text) ?? new TSettings();
|
||||||
/// </summary>
|
return settings;
|
||||||
public double MusicVolume = 80;
|
}
|
||||||
|
|
||||||
/// <summary>
|
private string ReadFileAsString(string path)
|
||||||
/// 音效音量
|
{
|
||||||
/// </summary>
|
if (FileAccess.FileExists(path))
|
||||||
public double SoundEffectVolume = 80;
|
{
|
||||||
|
using var file = FileAccess.Open(path, FileAccess.ModeFlags.Read);
|
||||||
|
return file.GetAsText();
|
||||||
|
}
|
||||||
|
return "null";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SaveSettings(string path)
|
||||||
|
{
|
||||||
|
string settings_text = JsonConvert.SerializeObject(BattleSettings);
|
||||||
|
using var file = FileAccess.Open(path, FileAccess.ModeFlags.Write);
|
||||||
|
file.StoreString(settings_text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public record class SettingsBase
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public record class BattleSettings : SettingsBase
|
||||||
|
{
|
||||||
|
public bool PauseBattleWhenCharacterIsSelected = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,106 +0,0 @@
|
|||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace CMSGame
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 游戏设置持久化节点
|
|
||||||
///
|
|
||||||
/// 在游戏开始时载入用户设置,并在游戏关闭时保存用户设置。
|
|
||||||
/// </summary>
|
|
||||||
public partial class GameSettingsNode : Node
|
|
||||||
{
|
|
||||||
protected Dictionary<Type, GameSettings> CurrentSettings = new();
|
|
||||||
|
|
||||||
protected Dictionary<Type, GameSettings> OriginalSettings = new();
|
|
||||||
|
|
||||||
protected Dictionary<Type, string> SettingsPaths = new();
|
|
||||||
|
|
||||||
public BattleSettings BattleSettings => GetSettings<BattleSettings>();
|
|
||||||
|
|
||||||
public VideoSettings VideoSettings => GetSettings<VideoSettings>();
|
|
||||||
|
|
||||||
public AudioSettings AudioSettings => GetSettings<AudioSettings>();
|
|
||||||
|
|
||||||
public GameSettingsNode()
|
|
||||||
{
|
|
||||||
RegisterAllSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void _Ready()
|
|
||||||
{
|
|
||||||
MakeDirectories();
|
|
||||||
LoadAllSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void RegisterAllSettings()
|
|
||||||
{
|
|
||||||
RegisterSettings<BattleSettings>("BattleSettings.json");
|
|
||||||
RegisterSettings<VideoSettings>("VideoSettings.json");
|
|
||||||
RegisterSettings<AudioSettings>("AudioSettings.json");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void RegisterSettings<TSettings>(string filename) where TSettings : GameSettings, new()
|
|
||||||
{
|
|
||||||
var defaultSettings = new TSettings();
|
|
||||||
CurrentSettings.Add(typeof(TSettings), defaultSettings);
|
|
||||||
SettingsPaths.Add(typeof(TSettings), new GodotPath($"user://Settings/{filename}"));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void LoadAllSettings()
|
|
||||||
{
|
|
||||||
foreach (var settingsType in SettingsPaths.Keys)
|
|
||||||
{
|
|
||||||
LoadSettings(settingsType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void _ExitTree()
|
|
||||||
{
|
|
||||||
foreach (var settingsType in SettingsPaths.Keys)
|
|
||||||
{
|
|
||||||
if (!OriginalSettings.ContainsKey(settingsType) || OriginalSettings[settingsType] != CurrentSettings[settingsType])
|
|
||||||
{
|
|
||||||
SaveSettings(settingsType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void MakeDirectories()
|
|
||||||
{
|
|
||||||
DirAccess.MakeDirRecursiveAbsolute("user://Settings/");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void LoadSettings(Type settingsType)
|
|
||||||
{
|
|
||||||
string settingsText = ReadFileAsString(SettingsPaths[settingsType]);
|
|
||||||
var settings = JsonConvert.DeserializeObject(settingsText, settingsType);
|
|
||||||
if (settings != null)
|
|
||||||
{
|
|
||||||
OriginalSettings[settingsType] = (GameSettings)settings;
|
|
||||||
CurrentSettings[settingsType] = (GameSettings)settings;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public TSettings GetSettings<TSettings>() where TSettings : GameSettings, new()
|
|
||||||
{
|
|
||||||
return (TSettings)CurrentSettings[typeof(TSettings)];
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string ReadFileAsString(string path)
|
|
||||||
{
|
|
||||||
if (FileAccess.FileExists(path))
|
|
||||||
{
|
|
||||||
using var file = FileAccess.Open(path, FileAccess.ModeFlags.Read);
|
|
||||||
return file.GetAsText();
|
|
||||||
}
|
|
||||||
return "null";
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SaveSettings(Type settingsType)
|
|
||||||
{
|
|
||||||
string settingsText = JsonConvert.SerializeObject(CurrentSettings[settingsType]);
|
|
||||||
using var file = FileAccess.Open(SettingsPaths[settingsType], FileAccess.ModeFlags.Write);
|
|
||||||
file.StoreString(settingsText);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,21 @@
|
|||||||
|
namespace CMSGame
|
||||||
|
{
|
||||||
|
public partial class BattleActionMenu : VBoxContainer
|
||||||
|
{
|
||||||
|
public VBoxContainer? DynamicActions;
|
||||||
|
|
||||||
|
public Button? ItemActionButton;
|
||||||
|
|
||||||
|
public Button? SkillActionButton;
|
||||||
|
|
||||||
|
public Button? CommandActionButton;
|
||||||
|
|
||||||
|
public override void _Ready()
|
||||||
|
{
|
||||||
|
this.GetUniqueNode(ref ItemActionButton, nameof(ItemActionButton));
|
||||||
|
this.GetUniqueNode(ref DynamicActions, nameof(DynamicActions));
|
||||||
|
this.GetUniqueNode(ref SkillActionButton, nameof(SkillActionButton));
|
||||||
|
this.GetUniqueNode(ref CommandActionButton, nameof(CommandActionButton));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
[gd_scene load_steps=2 format=3 uid="uid://bktklsml5d0jg"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://Components/BattleActionMenu.cs" id="1_0bfmk"]
|
||||||
|
|
||||||
|
[node name="BattleActionMenu" type="VBoxContainer"]
|
||||||
|
anchors_preset = 4
|
||||||
|
anchor_top = 0.5
|
||||||
|
anchor_bottom = 0.5
|
||||||
|
offset_top = -15.5
|
||||||
|
offset_right = 40.0
|
||||||
|
offset_bottom = 15.5
|
||||||
|
grow_vertical = 2
|
||||||
|
script = ExtResource("1_0bfmk")
|
||||||
|
|
||||||
|
[node name="ItemActionButton" type="Button" parent="."]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 2
|
||||||
|
text = "物品"
|
||||||
|
|
||||||
|
[node name="DynamicActions" type="VBoxContainer" parent="."]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 2
|
||||||
|
|
||||||
|
[node name="SkillActionButton" type="Button" parent="."]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 2
|
||||||
|
text = "技能"
|
||||||
|
|
||||||
|
[node name="CommandActionButton" type="Button" parent="."]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 2
|
||||||
|
text = "指挥"
|
@ -0,0 +1,49 @@
|
|||||||
|
namespace CMSGame
|
||||||
|
{
|
||||||
|
public partial class BattleHUD : Control
|
||||||
|
{
|
||||||
|
public Vector2 LastMousePressedPosition;
|
||||||
|
|
||||||
|
public Label? BattleTimeLabel;
|
||||||
|
|
||||||
|
public Popup? PauseMenuPopup;
|
||||||
|
|
||||||
|
public Popup? SettingsMenuPopup;
|
||||||
|
|
||||||
|
public BattleActionMenu? BattleActionMenu;
|
||||||
|
|
||||||
|
public override void _Ready()
|
||||||
|
{
|
||||||
|
this.GetUniqueNode(ref BattleTimeLabel, nameof(BattleTimeLabel));
|
||||||
|
this.GetUniqueNode(ref PauseMenuPopup, nameof(PauseMenuPopup));
|
||||||
|
this.GetUniqueNode(ref SettingsMenuPopup, nameof(SettingsMenuPopup));
|
||||||
|
this.GetUniqueNode(ref BattleActionMenu, nameof(BattleActionMenu));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void _GuiInput(InputEvent @event)
|
||||||
|
{
|
||||||
|
if (@event is InputEventMouseButton mouseButtonEvent)
|
||||||
|
{
|
||||||
|
if (mouseButtonEvent.Pressed)
|
||||||
|
{
|
||||||
|
LastMousePressedPosition = mouseButtonEvent.Position;
|
||||||
|
var battleActionMenuRect = new Rect2(BattleActionMenu!.Position, BattleActionMenu.Size);
|
||||||
|
if (!battleActionMenuRect.HasPoint(LastMousePressedPosition))
|
||||||
|
{
|
||||||
|
BattleActionMenu.Visible = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ShowActionMenu(Vector2 position)
|
||||||
|
{
|
||||||
|
if (!BattleActionMenu!.Visible)
|
||||||
|
{
|
||||||
|
BattleActionMenu.Position = position;
|
||||||
|
BattleActionMenu.Visible = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,89 @@
|
|||||||
|
[gd_scene load_steps=4 format=3 uid="uid://dyyrp4px1km16"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://Components/BattleHUD.cs" id="1_12a1x"]
|
||||||
|
[ext_resource type="PackedScene" path="res://Components/SettingsMenuPopup.tscn" id="2_t66a0"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://bktklsml5d0jg" path="res://Components/BattleActionMenu.tscn" id="3_0nyue"]
|
||||||
|
|
||||||
|
[node name="BattleHUD" type="Control"]
|
||||||
|
layout_mode = 3
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
mouse_filter = 1
|
||||||
|
script = ExtResource("1_12a1x")
|
||||||
|
|
||||||
|
[node name="BattleTimeLabel" type="Label" parent="."]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 1
|
||||||
|
offset_right = 41.0
|
||||||
|
offset_bottom = 26.0
|
||||||
|
text = "00:00"
|
||||||
|
metadata/_edit_use_anchors_ = true
|
||||||
|
|
||||||
|
[node name="PauseBattleButton" type="Button" parent="."]
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 7
|
||||||
|
anchor_left = 0.5
|
||||||
|
anchor_top = 1.0
|
||||||
|
anchor_right = 0.5
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
offset_left = -20.0
|
||||||
|
offset_top = -23.0
|
||||||
|
offset_right = 20.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 0
|
||||||
|
focus_mode = 0
|
||||||
|
text = "按下 Space 暂停时间"
|
||||||
|
|
||||||
|
[node name="PauseMenuPopup" type="Popup" parent="."]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
size = Vector2i(242, 306)
|
||||||
|
borderless = false
|
||||||
|
|
||||||
|
[node name="PauseMenu" type="VBoxContainer" parent="PauseMenuPopup"]
|
||||||
|
anchors_preset = 8
|
||||||
|
anchor_left = 0.5
|
||||||
|
anchor_top = 0.5
|
||||||
|
anchor_right = 0.5
|
||||||
|
anchor_bottom = 0.5
|
||||||
|
offset_left = -86.0
|
||||||
|
offset_top = -50.5
|
||||||
|
offset_right = 86.0
|
||||||
|
offset_bottom = 50.5
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
size_flags_horizontal = 4
|
||||||
|
size_flags_vertical = 4
|
||||||
|
|
||||||
|
[node name="ResumeBattleButton" type="Button" parent="PauseMenuPopup/PauseMenu"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 2
|
||||||
|
text = "继续战斗"
|
||||||
|
|
||||||
|
[node name="SettingsMenuButton" type="Button" parent="PauseMenuPopup/PauseMenu"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 2
|
||||||
|
text = "游戏设置"
|
||||||
|
|
||||||
|
[node name="EscapeFromBattleButton" type="Button" parent="PauseMenuPopup/PauseMenu"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 2
|
||||||
|
text = "退出战斗"
|
||||||
|
|
||||||
|
[node name="SettingsMenuPopup" parent="." instance=ExtResource("2_t66a0")]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
visible = false
|
||||||
|
borderless = false
|
||||||
|
|
||||||
|
[node name="BattleActionMenu" parent="." instance=ExtResource("3_0nyue")]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
visible = false
|
||||||
|
layout_mode = 0
|
||||||
|
anchors_preset = 0
|
||||||
|
anchor_top = 0.0
|
||||||
|
anchor_bottom = 0.0
|
||||||
|
offset_top = 0.0
|
||||||
|
offset_bottom = 31.0
|
||||||
|
grow_vertical = 1
|
@ -0,0 +1,35 @@
|
|||||||
|
[gd_scene format=3 uid="uid://blobono0y4pqs"]
|
||||||
|
|
||||||
|
[node name="PreBattleMenu" type="Control"]
|
||||||
|
layout_mode = 3
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
|
||||||
|
[node name="VBoxContainer" type="VBoxContainer" parent="."]
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 8
|
||||||
|
anchor_left = 0.5
|
||||||
|
anchor_top = 0.5
|
||||||
|
anchor_right = 0.5
|
||||||
|
anchor_bottom = 0.5
|
||||||
|
offset_left = -20.0
|
||||||
|
offset_top = -20.0
|
||||||
|
offset_right = 20.0
|
||||||
|
offset_bottom = 20.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
|
||||||
|
[node name="PrepareForBattleButton" type="Button" parent="VBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "战前准备"
|
||||||
|
|
||||||
|
[node name="BeginBattleButton" type="Button" parent="VBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "开始战斗"
|
||||||
|
|
||||||
|
[node name="EscapeFromBattleButton" type="Button" parent="VBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "逃跑"
|
@ -1,22 +0,0 @@
|
|||||||
namespace CMSGame
|
|
||||||
{
|
|
||||||
public partial class AudioSettingsMenu : VBoxContainer
|
|
||||||
{
|
|
||||||
public GameSettingsNode? Settings;
|
|
||||||
|
|
||||||
public HSlider? MasterVolumeSlider;
|
|
||||||
|
|
||||||
public HSlider? MusicVolumeSlider;
|
|
||||||
|
|
||||||
public HSlider? SoundEffectVolumeSlider;
|
|
||||||
|
|
||||||
public override void _Ready()
|
|
||||||
{
|
|
||||||
this.GetAutoloadNode(ref Settings, nameof(GameSettingsNode));
|
|
||||||
|
|
||||||
MasterVolumeSlider = this.GetUniqueNode<HSlider>(nameof(MasterVolumeSlider));
|
|
||||||
MusicVolumeSlider = this.GetUniqueNode<HSlider>(nameof(MusicVolumeSlider));
|
|
||||||
SoundEffectVolumeSlider = this.GetUniqueNode<HSlider>(nameof(SoundEffectVolumeSlider));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
namespace CMSGame
|
|
||||||
{
|
|
||||||
public partial class BattleSettingsMenu : VBoxContainer
|
|
||||||
{
|
|
||||||
public override void _Ready()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
|||||||
namespace CMSGame
|
|
||||||
{
|
|
||||||
public partial class DeveloperOptionsMenu : VBoxContainer
|
|
||||||
{
|
|
||||||
public override void _Ready()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public void On_OpenUserDataDirButton_Pressed()
|
|
||||||
{
|
|
||||||
OS.ShellOpen(new GodotPath("user://"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
namespace CMSGame
|
|
||||||
{
|
|
||||||
public partial class SettingsMenu : TabContainer
|
|
||||||
{
|
|
||||||
public GameSettingsNode? Settings;
|
|
||||||
|
|
||||||
public override void _Ready()
|
|
||||||
{
|
|
||||||
this.GetAutoloadNode(ref Settings, nameof(GameSettingsNode));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,81 +0,0 @@
|
|||||||
[gd_scene load_steps=6 format=3 uid="uid://blk2uswpo2a7k"]
|
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://Components/Settings/SettingsMenu.cs" id="1_av57b"]
|
|
||||||
[ext_resource type="Script" path="res://Components/Settings/DeveloperOptionsMenu.cs" id="2_dgytf"]
|
|
||||||
[ext_resource type="Script" path="res://Components/Settings/BattleSettingsMenu.cs" id="2_xtjo5"]
|
|
||||||
[ext_resource type="Script" path="res://Components/Settings/VideoSettingsMenu.cs" id="3_68iki"]
|
|
||||||
[ext_resource type="Script" path="res://Components/Settings/AudioSettingsMenu.cs" id="4_ciy5h"]
|
|
||||||
|
|
||||||
[node name="SettingsMenu" type="TabContainer"]
|
|
||||||
anchors_preset = 15
|
|
||||||
anchor_right = 1.0
|
|
||||||
anchor_bottom = 1.0
|
|
||||||
grow_horizontal = 2
|
|
||||||
grow_vertical = 2
|
|
||||||
script = ExtResource("1_av57b")
|
|
||||||
|
|
||||||
[node name="BattleSettingsMenu" type="VBoxContainer" parent="."]
|
|
||||||
unique_name_in_owner = true
|
|
||||||
layout_mode = 2
|
|
||||||
script = ExtResource("2_xtjo5")
|
|
||||||
|
|
||||||
[node name="VideoSettingsMenu" type="VBoxContainer" parent="."]
|
|
||||||
unique_name_in_owner = true
|
|
||||||
visible = false
|
|
||||||
layout_mode = 2
|
|
||||||
script = ExtResource("3_68iki")
|
|
||||||
|
|
||||||
[node name="AudioSettingsMenu" type="VBoxContainer" parent="."]
|
|
||||||
unique_name_in_owner = true
|
|
||||||
visible = false
|
|
||||||
layout_mode = 2
|
|
||||||
script = ExtResource("4_ciy5h")
|
|
||||||
|
|
||||||
[node name="GridContainer" type="GridContainer" parent="AudioSettingsMenu"]
|
|
||||||
layout_mode = 2
|
|
||||||
columns = 2
|
|
||||||
|
|
||||||
[node name="Label3" type="Label" parent="AudioSettingsMenu/GridContainer"]
|
|
||||||
layout_mode = 2
|
|
||||||
text = "主音量"
|
|
||||||
|
|
||||||
[node name="MasterVolumeSlider" type="HSlider" parent="AudioSettingsMenu/GridContainer"]
|
|
||||||
unique_name_in_owner = true
|
|
||||||
layout_mode = 2
|
|
||||||
max_value = 1.0
|
|
||||||
step = 0.01
|
|
||||||
value = 0.8
|
|
||||||
|
|
||||||
[node name="Label" type="Label" parent="AudioSettingsMenu/GridContainer"]
|
|
||||||
layout_mode = 2
|
|
||||||
text = "音乐音量"
|
|
||||||
|
|
||||||
[node name="MusicVolumeSlider" type="HSlider" parent="AudioSettingsMenu/GridContainer"]
|
|
||||||
unique_name_in_owner = true
|
|
||||||
custom_minimum_size = Vector2(200, 0)
|
|
||||||
layout_mode = 2
|
|
||||||
max_value = 1.0
|
|
||||||
step = 0.01
|
|
||||||
value = 0.8
|
|
||||||
|
|
||||||
[node name="Label2" type="Label" parent="AudioSettingsMenu/GridContainer"]
|
|
||||||
layout_mode = 2
|
|
||||||
text = "音效音量"
|
|
||||||
|
|
||||||
[node name="SoundEffectVolumeSlider" type="HSlider" parent="AudioSettingsMenu/GridContainer"]
|
|
||||||
unique_name_in_owner = true
|
|
||||||
layout_mode = 2
|
|
||||||
max_value = 1.0
|
|
||||||
step = 0.01
|
|
||||||
value = 0.8
|
|
||||||
|
|
||||||
[node name="DeveloperOptionsMenu" type="VBoxContainer" parent="."]
|
|
||||||
visible = false
|
|
||||||
layout_mode = 2
|
|
||||||
script = ExtResource("2_dgytf")
|
|
||||||
|
|
||||||
[node name="OpenUserDataDirButton" type="Button" parent="DeveloperOptionsMenu"]
|
|
||||||
layout_mode = 2
|
|
||||||
text = "打开用户数据目录"
|
|
||||||
|
|
||||||
[connection signal="pressed" from="DeveloperOptionsMenu/OpenUserDataDirButton" to="DeveloperOptionsMenu" method="On_OpenUserDataDirButton_Pressed"]
|
|
@ -1,27 +0,0 @@
|
|||||||
[gd_scene load_steps=3 format=3 uid="uid://cslqihnfw0me2"]
|
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://Components/Settings/SettingsMenuPopup.cs" id="1_it4yp"]
|
|
||||||
[ext_resource type="PackedScene" uid="uid://blk2uswpo2a7k" path="res://Components/Settings/SettingsMenu.tscn" id="2_qc1kk"]
|
|
||||||
|
|
||||||
[node name="SettingsMenuPopup" type="Popup"]
|
|
||||||
size = Vector2i(800, 485)
|
|
||||||
visible = true
|
|
||||||
script = ExtResource("1_it4yp")
|
|
||||||
|
|
||||||
[node name="VBoxContainer" type="VBoxContainer" parent="."]
|
|
||||||
offset_right = 800.0
|
|
||||||
offset_bottom = 66.0
|
|
||||||
alignment = 1
|
|
||||||
|
|
||||||
[node name="SettingsMenu" parent="VBoxContainer" instance=ExtResource("2_qc1kk")]
|
|
||||||
custom_minimum_size = Vector2(800, 450)
|
|
||||||
layout_mode = 2
|
|
||||||
|
|
||||||
[node name="HidePopupButton" type="Button" parent="VBoxContainer"]
|
|
||||||
unique_name_in_owner = true
|
|
||||||
custom_minimum_size = Vector2(200, 0)
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_horizontal = 4
|
|
||||||
text = "关闭"
|
|
||||||
|
|
||||||
[connection signal="pressed" from="VBoxContainer/HidePopupButton" to="." method="On_HidePopupButton_Pressed"]
|
|
@ -1,10 +0,0 @@
|
|||||||
namespace CMSGame
|
|
||||||
{
|
|
||||||
public partial class VideoSettingsMenu : VBoxContainer
|
|
||||||
{
|
|
||||||
public override void _Ready()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,22 @@
|
|||||||
|
namespace CMSGame
|
||||||
|
{
|
||||||
|
public partial class SettingsMenu : VBoxContainer
|
||||||
|
{
|
||||||
|
public GameSettings? Settings;
|
||||||
|
|
||||||
|
public CheckBox? PauseBattleWhenCharacterIsSelectedCheckBox;
|
||||||
|
|
||||||
|
public override void _Ready()
|
||||||
|
{
|
||||||
|
this.GetAutoloadNode(ref Settings, nameof(GameSettings));
|
||||||
|
this.GetUniqueNode(ref PauseBattleWhenCharacterIsSelectedCheckBox, nameof(PauseBattleWhenCharacterIsSelectedCheckBox));
|
||||||
|
|
||||||
|
PauseBattleWhenCharacterIsSelectedCheckBox!.ButtonPressed = Settings!.BattleSettings!.PauseBattleWhenCharacterIsSelected;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void On_PauseBattleWhenCharacterIsSelectedCheckBox_Toggled(bool pressed)
|
||||||
|
{
|
||||||
|
Settings!.BattleSettings!.PauseBattleWhenCharacterIsSelected = pressed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
[gd_scene load_steps=2 format=3 uid="uid://blk2uswpo2a7k"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://Components/SettingsMenu.cs" id="1_b12ly"]
|
||||||
|
|
||||||
|
[node name="SettingsMenu" type="VBoxContainer"]
|
||||||
|
script = ExtResource("1_b12ly")
|
||||||
|
|
||||||
|
[node name="PauseBattleWhenCharacterIsSelectedCheckBox" type="CheckBox" parent="."]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 2
|
||||||
|
text = "选中角色时暂停战斗"
|
||||||
|
|
||||||
|
[connection signal="toggled" from="PauseBattleWhenCharacterIsSelectedCheckBox" to="." method="On_PauseBattleWhenCharacterIsSelectedCheckBox_Toggled"]
|
@ -0,0 +1,23 @@
|
|||||||
|
[gd_scene load_steps=3 format=3 uid="uid://cslqihnfw0me2"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://Components/SettingsMenuPopup.cs" id="1_it4yp"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://blk2uswpo2a7k" path="res://Components/SettingsMenu.tscn" id="2_qc1kk"]
|
||||||
|
|
||||||
|
[node name="SettingsMenuPopup" type="Popup"]
|
||||||
|
size = Vector2i(172, 101)
|
||||||
|
visible = true
|
||||||
|
script = ExtResource("1_it4yp")
|
||||||
|
|
||||||
|
[node name="VBoxContainer" type="VBoxContainer" parent="."]
|
||||||
|
offset_right = 40.0
|
||||||
|
offset_bottom = 40.0
|
||||||
|
|
||||||
|
[node name="SettingsMenu" parent="VBoxContainer" instance=ExtResource("2_qc1kk")]
|
||||||
|
layout_mode = 2
|
||||||
|
|
||||||
|
[node name="ConfirmButton" type="Button" parent="VBoxContainer"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 2
|
||||||
|
text = "保存并退出"
|
||||||
|
|
||||||
|
[connection signal="pressed" from="VBoxContainer/ConfirmButton" to="." method="On_ConfirmButton_Pressed"]
|
@ -1,7 +0,0 @@
|
|||||||
# 开发者文档
|
|
||||||
|
|
||||||
## itch.io
|
|
||||||
|
|
||||||
``` cmd
|
|
||||||
butler push "Temp/Exports" lightyears1998/cmsgame:windows-64
|
|
||||||
```
|
|
@ -1,6 +1,7 @@
|
|||||||
namespace CMSGame
|
namespace CMSGame
|
||||||
{
|
{
|
||||||
public record class GameSave
|
public class GameSave
|
||||||
{
|
{
|
||||||
|
public List<Character> Characters = new();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,32 @@
|
|||||||
|
namespace CMSGame
|
||||||
|
{
|
||||||
|
public static class BattleGoals
|
||||||
|
{
|
||||||
|
public static readonly Goal<BattleContext> Escape = new()
|
||||||
|
{
|
||||||
|
Name = "保命要紧",
|
||||||
|
BasePriority = -50
|
||||||
|
};
|
||||||
|
|
||||||
|
public static readonly Goal<BattleContext> SelfRegulatory = new()
|
||||||
|
{
|
||||||
|
Name = "自律行动",
|
||||||
|
BasePriority = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
public static readonly Goal<BattleContext> FollowOrder = new()
|
||||||
|
{
|
||||||
|
Name = "服从指令",
|
||||||
|
BasePriority = 50
|
||||||
|
};
|
||||||
|
|
||||||
|
public static List<Goal<BattleContext>> AllGoals()
|
||||||
|
{
|
||||||
|
return new() {
|
||||||
|
Escape,
|
||||||
|
SelfRegulatory,
|
||||||
|
FollowOrder
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
namespace CMSGame
|
||||||
|
{
|
||||||
|
public static class Characters
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
namespace CMSGame
|
||||||
|
{
|
||||||
|
public abstract class Action
|
||||||
|
{
|
||||||
|
public string Name = string.Empty;
|
||||||
|
|
||||||
|
public ActionTargetTypes TargetType;
|
||||||
|
|
||||||
|
public List<IActionTarget> Targets = new();
|
||||||
|
|
||||||
|
public IActionTarget? Target => Targets.Count > 0 ? Targets[0] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ActionTargetTypes
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Single,
|
||||||
|
Multiple
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IActionTarget
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
namespace CMSGame
|
||||||
|
{
|
||||||
|
public class Character
|
||||||
|
{
|
||||||
|
public string FamilyName = string.Empty;
|
||||||
|
|
||||||
|
public string GivenName = string.Empty;
|
||||||
|
|
||||||
|
public string Name => FamilyName + GivenName;
|
||||||
|
|
||||||
|
public int HealthPoint;
|
||||||
|
|
||||||
|
public int MaxHealthPoint;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
namespace CMSGame
|
||||||
|
{
|
||||||
|
public abstract class Effect
|
||||||
|
{
|
||||||
|
public string Name = string.Empty;
|
||||||
|
|
||||||
|
public string Description = string.Empty;
|
||||||
|
|
||||||
|
public abstract void Perform(Character character);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,58 @@
|
|||||||
|
namespace CMSGame
|
||||||
|
{
|
||||||
|
public class Goal<TContext> where TContext : IGoalContext
|
||||||
|
{
|
||||||
|
public string Name = string.Empty;
|
||||||
|
|
||||||
|
public int BasePriority;
|
||||||
|
|
||||||
|
public List<GoalValidityModifier<TContext>> ValidityModifiers = new();
|
||||||
|
|
||||||
|
public List<GoalPriorityModifier<TContext>> PriorityModifiers = new();
|
||||||
|
|
||||||
|
public bool IsValid()
|
||||||
|
{
|
||||||
|
return ValidityModifiers.All(modifier => modifier.Execute());
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Priority()
|
||||||
|
{
|
||||||
|
return BasePriority + PriorityModifiers.Sum(modifier => modifier.Execute());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IGoalContext
|
||||||
|
{
|
||||||
|
IList<Action> ListActions();
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract class GoalModifier<TContext>
|
||||||
|
{
|
||||||
|
public string Name = string.Empty;
|
||||||
|
|
||||||
|
public TContext Context;
|
||||||
|
|
||||||
|
protected GoalModifier(TContext context)
|
||||||
|
{
|
||||||
|
Context = context;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract class GoalValidityModifier<TContext> : GoalModifier<TContext>
|
||||||
|
{
|
||||||
|
protected GoalValidityModifier(TContext context) : base(context)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract bool Execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract class GoalPriorityModifier<TContext> : GoalModifier<TContext>
|
||||||
|
{
|
||||||
|
protected GoalPriorityModifier(TContext context) : base(context)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract int Execute();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
namespace CMSGame
|
||||||
|
{
|
||||||
|
public class Plan
|
||||||
|
{
|
||||||
|
public readonly List<Action> Actions = new();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
namespace CMSGame
|
||||||
|
{
|
||||||
|
public abstract class Planner<TContext> where TContext : IGoalContext
|
||||||
|
{
|
||||||
|
public TContext Context;
|
||||||
|
|
||||||
|
public Planner(TContext context)
|
||||||
|
{
|
||||||
|
Context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract Plan MakePlan();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace CMSGame
|
||||||
|
{
|
||||||
|
public abstract class Skill
|
||||||
|
{
|
||||||
|
public string Name = string.Empty;
|
||||||
|
|
||||||
|
public List<Effect> Effects = new();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace CMSGame
|
||||||
|
{
|
||||||
|
public class Battle
|
||||||
|
{
|
||||||
|
public List<BattleParty> Parties = new();
|
||||||
|
|
||||||
|
public BattleParty Attacker;
|
||||||
|
|
||||||
|
public BattleParty Defender;
|
||||||
|
|
||||||
|
public BattleParty PlayerParty;
|
||||||
|
|
||||||
|
public Battle(BattleParty attacker, BattleParty defender, BattleParty playerParty)
|
||||||
|
{
|
||||||
|
Attacker = attacker;
|
||||||
|
Defender = defender;
|
||||||
|
PlayerParty = playerParty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Begin()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
namespace CMSGame
|
||||||
|
{
|
||||||
|
public class BattleCharacter
|
||||||
|
{
|
||||||
|
public List<Goal<BattleContext>> Goals = new();
|
||||||
|
|
||||||
|
public Character Character;
|
||||||
|
|
||||||
|
public BattleCharacter(Character character)
|
||||||
|
{
|
||||||
|
Character = character;
|
||||||
|
EstablishGoals();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EstablishGoals()
|
||||||
|
{
|
||||||
|
Goals = BattleGoals.AllGoals();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
namespace CMSGame
|
||||||
|
{
|
||||||
|
public class BattleContext : IGoalContext
|
||||||
|
{
|
||||||
|
public IList<Action> ListActions()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
namespace CMSGame
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 2D 战场
|
||||||
|
/// </summary>
|
||||||
|
public class BattleField
|
||||||
|
{
|
||||||
|
/// <summary>战场宽度</summary>
|
||||||
|
public int Width = 20;
|
||||||
|
|
||||||
|
/// <summary>战场长度</summary>
|
||||||
|
public int Length = 100;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
namespace CMSGame
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 2D 战场坐标
|
||||||
|
/// </summary>
|
||||||
|
public class BattleFieldPosition
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 坐标点相对于 2D 摄像机镜头所在竖直平面的距离
|
||||||
|
/// </summary>
|
||||||
|
public int Depth;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 坐标点相对于 2D 摄像机初始对准位置的偏移量
|
||||||
|
/// </summary>
|
||||||
|
public int Offset;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace CMSGame
|
||||||
|
{
|
||||||
|
public class BattleParty
|
||||||
|
{
|
||||||
|
public bool IsAttacker;
|
||||||
|
|
||||||
|
public bool IsDefender;
|
||||||
|
|
||||||
|
public bool IsPlayerParty;
|
||||||
|
|
||||||
|
public List<BattleCharacter> Characters = new();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,58 @@
|
|||||||
|
namespace CMSGame
|
||||||
|
{
|
||||||
|
public partial class BattleCharacterNode : CharacterBody3D
|
||||||
|
{
|
||||||
|
[Signal]
|
||||||
|
public delegate void MousePressedEventHandler(Vector3 position);
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Texture SpriteTexture = new();
|
||||||
|
|
||||||
|
public BattleFieldPosition? BattleFieldPosition;
|
||||||
|
|
||||||
|
public Character? Character;
|
||||||
|
|
||||||
|
public Sprite3D? Sprite3D;
|
||||||
|
|
||||||
|
public Label3D? StatusLabel;
|
||||||
|
|
||||||
|
public int ActionPoint;
|
||||||
|
|
||||||
|
public double ActionPointGathering;
|
||||||
|
|
||||||
|
public override void _Ready()
|
||||||
|
{
|
||||||
|
this.GetUniqueNode(ref Sprite3D, nameof(Sprite3D));
|
||||||
|
this.GetUniqueNode(ref StatusLabel, nameof(StatusLabel));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void _Process(double delta)
|
||||||
|
{
|
||||||
|
UpdateStatus(delta);
|
||||||
|
UpdateUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateStatus(double delta)
|
||||||
|
{
|
||||||
|
ActionPointGathering += delta;
|
||||||
|
ActionPoint += (int)ActionPointGathering / 10;
|
||||||
|
ActionPointGathering %= 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateUI()
|
||||||
|
{
|
||||||
|
StatusLabel!.Text = $"HP {Character!.HealthPoint}/{Character.MaxHealthPoint}\nAP {ActionPoint}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void _InputEvent(Camera3D camera, InputEvent @event, Vector3 position, Vector3 normal, int shapeIdx)
|
||||||
|
{
|
||||||
|
if (@event is InputEventMouseButton mouseButtonEvent)
|
||||||
|
{
|
||||||
|
if (mouseButtonEvent.Pressed)
|
||||||
|
{
|
||||||
|
EmitSignal(SignalName.MousePressed, position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
[gd_scene load_steps=4 format=3 uid="uid://dje5jk73mjb6a"]
|
||||||
|
|
||||||
|
[ext_resource type="Texture2D" uid="uid://cnilysgmgw8n4" path="res://Temp/Characters/1_19.png" id="1_o3tjt"]
|
||||||
|
[ext_resource type="Script" path="res://Nodes/BattleCharacterNode.cs" id="2_vbdi8"]
|
||||||
|
|
||||||
|
[sub_resource type="BoxShape3D" id="BoxShape3D_r28jb"]
|
||||||
|
size = Vector3(0.84, 1.46, 0.17)
|
||||||
|
|
||||||
|
[node name="BattleCharacter" type="CharacterBody3D"]
|
||||||
|
script = ExtResource("2_vbdi8")
|
||||||
|
|
||||||
|
[node name="AudioStreamPlayer2D" type="AudioStreamPlayer3D" parent="."]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
|
||||||
|
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.23, 0)
|
||||||
|
shape = SubResource("BoxShape3D_r28jb")
|
||||||
|
|
||||||
|
[node name="Sprite3D" type="Sprite3D" parent="."]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0)
|
||||||
|
shaded = true
|
||||||
|
alpha_cut = 2
|
||||||
|
texture = ExtResource("1_o3tjt")
|
||||||
|
|
||||||
|
[node name="StatusLabel" type="Label3D" parent="."]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.74, 0)
|
||||||
|
text = "状态标签"
|
||||||
|
vertical_alignment = 2
|
||||||
|
autowrap_mode = 3
|
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"profiles": {
|
||||||
|
"CMSGame": {
|
||||||
|
"commandName": "Executable",
|
||||||
|
"executablePath": "C:\\Users\\light\\AppData\\Local\\Programs\\Godot\\Godot_v4.0.2-stable_mono_win64\\Godot_v4.0.2-stable_mono_win64.exe",
|
||||||
|
"workingDirectory": "."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,82 @@
|
|||||||
namespace CMSGame
|
namespace CMSGame
|
||||||
{
|
{
|
||||||
public partial class BattleScene : Node2D
|
public partial class BattleScene : Node3D
|
||||||
{
|
{
|
||||||
|
public BattleHUD? HUD;
|
||||||
|
|
||||||
|
public Popup? PauseMenuPopup;
|
||||||
|
|
||||||
|
public Popup? SettingsMenuPopup;
|
||||||
|
|
||||||
|
public double Time;
|
||||||
|
|
||||||
|
public bool IsPause = false;
|
||||||
|
|
||||||
|
private bool IsPauseBeforePauseMenuPopup = false;
|
||||||
|
|
||||||
|
public override void _Ready()
|
||||||
|
{
|
||||||
|
this.GetUniqueNode(ref HUD, nameof(HUD));
|
||||||
|
PauseMenuPopup = HUD!.PauseMenuPopup;
|
||||||
|
SettingsMenuPopup = HUD.SettingsMenuPopup;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void _Process(double delta)
|
||||||
|
{
|
||||||
|
if (!IsPause)
|
||||||
|
{
|
||||||
|
Time += delta;
|
||||||
|
}
|
||||||
|
UpdateUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void _UnhandledInput(InputEvent input)
|
||||||
|
{
|
||||||
|
if (input.IsActionPressed("battle_pause_toggle"))
|
||||||
|
{
|
||||||
|
TogglePauseBattle();
|
||||||
|
}
|
||||||
|
else if (input.IsActionPressed("battle_pause"))
|
||||||
|
{
|
||||||
|
ShowPauseMenu();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateUI()
|
||||||
|
{
|
||||||
|
HUD!.BattleTimeLabel!.Text = TimeHelper.FormatTime(Time);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TogglePauseBattle()
|
||||||
|
{
|
||||||
|
IsPause = !IsPause;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ShowPauseMenu()
|
||||||
|
{
|
||||||
|
IsPauseBeforePauseMenuPopup = IsPause;
|
||||||
|
IsPause = true;
|
||||||
|
PauseMenuPopup!.PopupCentered();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void On_PauseBattleButton_Pressed()
|
||||||
|
{
|
||||||
|
TogglePauseBattle();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void On_PauseMenuPopup_PopupHide()
|
||||||
|
{
|
||||||
|
IsPause = IsPauseBeforePauseMenuPopup;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void On_ResumeBattleButton_Pressed()
|
||||||
|
{
|
||||||
|
PauseMenuPopup!.Hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void On_SettingsMenuButton_Pressed()
|
||||||
|
{
|
||||||
|
SettingsMenuPopup!.PopupCentered();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,63 @@
|
|||||||
[gd_scene load_steps=2 format=3 uid="uid://cp6aa655vykt1"]
|
[gd_scene load_steps=10 format=3 uid="uid://cp6aa655vykt1"]
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://Scenes/BattleScene.cs" id="1_n6bn7"]
|
[ext_resource type="Script" path="res://Scenes/BattleScene.cs" id="1_n6bn7"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://dyyrp4px1km16" path="res://Components/BattleHUD.tscn" id="2_u4666"]
|
||||||
|
|
||||||
[node name="BattleScene" type="Node2D"]
|
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_vrgig"]
|
||||||
|
sky_horizon_color = Color(0.64625, 0.65575, 0.67075, 1)
|
||||||
|
ground_horizon_color = Color(0.64625, 0.65575, 0.67075, 1)
|
||||||
|
|
||||||
|
[sub_resource type="Sky" id="Sky_26whx"]
|
||||||
|
sky_material = SubResource("ProceduralSkyMaterial_vrgig")
|
||||||
|
|
||||||
|
[sub_resource type="Environment" id="Environment_hv4sx"]
|
||||||
|
background_mode = 2
|
||||||
|
sky = SubResource("Sky_26whx")
|
||||||
|
tonemap_mode = 2
|
||||||
|
glow_enabled = true
|
||||||
|
|
||||||
|
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_udghy"]
|
||||||
|
uv1_scale = Vector3(20, 20, 20)
|
||||||
|
|
||||||
|
[sub_resource type="PlaneMesh" id="PlaneMesh_30sfg"]
|
||||||
|
material = SubResource("StandardMaterial3D_udghy")
|
||||||
|
size = Vector2(40, 20)
|
||||||
|
|
||||||
|
[sub_resource type="WorldBoundaryShape3D" id="WorldBoundaryShape3D_a4f8m"]
|
||||||
|
|
||||||
|
[node name="BattleScene" type="Node3D"]
|
||||||
script = ExtResource("1_n6bn7")
|
script = ExtResource("1_n6bn7")
|
||||||
|
|
||||||
|
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
|
||||||
|
environment = SubResource("Environment_hv4sx")
|
||||||
|
|
||||||
|
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 0.558497, 0.829506, 0, -0.829506, 0.558497, 0, 10.6856, 0)
|
||||||
|
shadow_enabled = true
|
||||||
|
|
||||||
|
[node name="Camera3D" type="Camera3D" parent="."]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 0.939693, 0.34202, 0, -0.34202, 0.939693, 0, 2.35115, 0)
|
||||||
|
|
||||||
|
[node name="CanvasLayer" type="CanvasLayer" parent="Camera3D"]
|
||||||
|
|
||||||
|
[node name="HUD" parent="Camera3D/CanvasLayer" instance=ExtResource("2_u4666")]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
|
||||||
|
[node name="Ground" type="Node3D" parent="."]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
|
||||||
|
[node name="Area3D" type="Area3D" parent="Ground"]
|
||||||
|
|
||||||
|
[node name="MeshInstance3D" type="MeshInstance3D" parent="Ground/Area3D"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -10)
|
||||||
|
mesh = SubResource("PlaneMesh_30sfg")
|
||||||
|
skeleton = NodePath("../..")
|
||||||
|
|
||||||
|
[node name="CollisionShape3D" type="CollisionShape3D" parent="Ground/Area3D"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -10)
|
||||||
|
shape = SubResource("WorldBoundaryShape3D_a4f8m")
|
||||||
|
|
||||||
|
[node name="Characters" type="Node3D" parent="."]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
|
||||||
|
[node name="Objects" type="Node3D" parent="."]
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
namespace CMSGame
|
||||||
|
{
|
||||||
|
public partial class BattleSceneTest : Node3D
|
||||||
|
{
|
||||||
|
public BattleScene? BattleScene;
|
||||||
|
|
||||||
|
public override void _Ready()
|
||||||
|
{
|
||||||
|
BattleScene = GetNode<BattleScene>("BattleScene");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void On_BattleCharacter_MousePressed(Vector3 _)
|
||||||
|
{
|
||||||
|
BattleScene!.HUD!.ShowActionMenu(BattleScene.HUD.LastMousePressedPosition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
[gd_scene load_steps=10 format=3 uid="uid://dgi0d8jybvlk0"]
|
||||||
|
|
||||||
|
[ext_resource type="PackedScene" uid="uid://cp6aa655vykt1" path="res://Scenes/BattleScene.tscn" id="1_fdqdi"]
|
||||||
|
[ext_resource type="Script" path="res://Tests/BattleSceneTest.cs" id="1_tuul4"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://dje5jk73mjb6a" path="res://Nodes/BattleCharacterNode.tscn" id="3_nau0d"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://w6qckexp2he1" path="res://Temp/Characters/2_73.png" id="4_jnah0"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://du6o3upum6lkr" path="res://Temp/Characters/3_0.png" id="5_4vahd"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://cl11bl8lcnwha" path="res://Temp/Characters/4_2.png" id="6_6563q"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://dc27ugd4sik7m" path="res://Temp/Characters/5_4.png" id="7_a35tl"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://cl8nkrx2bk76n" path="res://Temp/Characters/6_1.png" id="8_oklwm"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://ch0pdjtnr3y7r" path="res://Temp/Characters/7.png" id="9_wor4w"]
|
||||||
|
|
||||||
|
[node name="BattleSceneTest" type="Node3D"]
|
||||||
|
script = ExtResource("1_tuul4")
|
||||||
|
|
||||||
|
[node name="BattleScene" parent="." instance=ExtResource("1_fdqdi")]
|
||||||
|
|
||||||
|
[node name="BattleCharacter" parent="BattleScene/Characters" index="0" instance=ExtResource("3_nau0d")]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.1026, 0.524168, -2.96058)
|
||||||
|
|
||||||
|
[node name="BattleCharacter2" parent="BattleScene/Characters" index="1" instance=ExtResource("3_nau0d")]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.25622, 0.524168, -2.87261)
|
||||||
|
|
||||||
|
[node name="Sprite3D" parent="BattleScene/Characters/BattleCharacter2" index="2"]
|
||||||
|
texture = ExtResource("4_jnah0")
|
||||||
|
|
||||||
|
[node name="BattleCharacter3" parent="BattleScene/Characters" index="2" instance=ExtResource("3_nau0d")]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.524168, -4.12488)
|
||||||
|
|
||||||
|
[node name="Sprite3D" parent="BattleScene/Characters/BattleCharacter3" index="2"]
|
||||||
|
texture = ExtResource("5_4vahd")
|
||||||
|
|
||||||
|
[node name="BattleCharacter4" parent="BattleScene/Characters" index="3" instance=ExtResource("3_nau0d")]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.737777, 0.524168, -3.35854)
|
||||||
|
|
||||||
|
[node name="Sprite3D" parent="BattleScene/Characters/BattleCharacter4" index="2"]
|
||||||
|
texture = ExtResource("6_6563q")
|
||||||
|
|
||||||
|
[node name="BattleCharacter5" parent="BattleScene/Characters" index="4" instance=ExtResource("3_nau0d")]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.6372, 0.524168, -3.47228)
|
||||||
|
|
||||||
|
[node name="Sprite3D" parent="BattleScene/Characters/BattleCharacter5" index="2"]
|
||||||
|
texture = ExtResource("7_a35tl")
|
||||||
|
|
||||||
|
[node name="BattleCharacter6" parent="BattleScene/Characters" index="5" instance=ExtResource("3_nau0d")]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.27585, 0.524168, -5.80874)
|
||||||
|
|
||||||
|
[node name="Sprite3D" parent="BattleScene/Characters/BattleCharacter6" index="2"]
|
||||||
|
texture = ExtResource("8_oklwm")
|
||||||
|
|
||||||
|
[node name="BattleCharacter7" parent="BattleScene/Characters" index="6" instance=ExtResource("3_nau0d")]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.44713, 0.524168, -12.3572)
|
||||||
|
|
||||||
|
[node name="Sprite3D" parent="BattleScene/Characters/BattleCharacter7" index="2"]
|
||||||
|
texture = ExtResource("9_wor4w")
|
||||||
|
|
||||||
|
[editable path="BattleScene"]
|
||||||
|
[editable path="BattleScene/Characters/BattleCharacter2"]
|
||||||
|
[editable path="BattleScene/Characters/BattleCharacter3"]
|
||||||
|
[editable path="BattleScene/Characters/BattleCharacter4"]
|
||||||
|
[editable path="BattleScene/Characters/BattleCharacter5"]
|
||||||
|
[editable path="BattleScene/Characters/BattleCharacter6"]
|
||||||
|
[editable path="BattleScene/Characters/BattleCharacter7"]
|
@ -0,0 +1,16 @@
|
|||||||
|
namespace CMSGame
|
||||||
|
{
|
||||||
|
public static class GameSaves
|
||||||
|
{
|
||||||
|
public static readonly GameSave Demo1 = new()
|
||||||
|
{
|
||||||
|
Characters = new() {
|
||||||
|
new Character {
|
||||||
|
FamilyName = "腾",
|
||||||
|
GivenName = "牧心",
|
||||||
|
HealthPoint = 80
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
@ -1,7 +0,0 @@
|
|||||||
[gd_resource type="Theme" load_steps=2 format=3 uid="uid://cn55cr5w4yy3n"]
|
|
||||||
|
|
||||||
[ext_resource type="FontFile" uid="uid://tfubgavtu25o" path="res://Assets/Fonts/Tiejili/TiejiliSC-Regular.otf" id="1_usckb"]
|
|
||||||
|
|
||||||
[resource]
|
|
||||||
default_font = ExtResource("1_usckb")
|
|
||||||
default_font_size = 32
|
|
@ -1,15 +0,0 @@
|
|||||||
[gd_resource type="AudioBusLayout" format=3 uid="uid://ca3y006advrdf"]
|
|
||||||
|
|
||||||
[resource]
|
|
||||||
bus/1/name = &"Music"
|
|
||||||
bus/1/solo = false
|
|
||||||
bus/1/mute = false
|
|
||||||
bus/1/bypass_fx = false
|
|
||||||
bus/1/volume_db = 0.0
|
|
||||||
bus/1/send = &"Master"
|
|
||||||
bus/2/name = &"SoundEffect"
|
|
||||||
bus/2/solo = false
|
|
||||||
bus/2/mute = false
|
|
||||||
bus/2/bypass_fx = false
|
|
||||||
bus/2/volume_db = 0.0
|
|
||||||
bus/2/send = &"Master"
|
|
Loading…
Reference in new issue