From c25d985f87df9bb556443ab99218febbafab1f7a Mon Sep 17 00:00:00 2001 From: Cold-Mint Date: Sat, 14 Sep 2024 23:38:57 +0800 Subject: [PATCH] =?UTF-8?q?Improve=20the=20efficiency=20of=20backpack=20UI?= =?UTF-8?q?=20toggle=20visibility.=20Prepare=20for=20the=20upcoming=20work?= =?UTF-8?q?bench=20UI.=20=E6=8F=90=E5=8D=87=E8=83=8C=E5=8C=85UI=E5=88=87?= =?UTF-8?q?=E6=8D=A2=E5=8F=AF=E8=A7=81=E5=BA=A6=E6=97=B6=E7=9A=84=E6=95=88?= =?UTF-8?q?=E7=8E=87=E3=80=82=E4=B8=BA=E5=8D=B3=E5=B0=86=E5=88=B0=E6=9D=A5?= =?UTF-8?q?=E7=9A=84=E5=B7=A5=E4=BD=9C=E5=8F=B0UI=E5=81=9A=E5=87=86?= =?UTF-8?q?=E5=A4=87=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- prefab/roomTemplates/dungeon/initialRoom.tscn | 1 - scenes/game.tscn | 4 +- scripts/GameSceneDepend.cs | 33 +---- scripts/character/CharacterTemplate.cs | 2 +- scripts/character/Player.cs | 4 +- scripts/inventory/Packsack.cs | 23 +++- scripts/loader/sceneLoader/GameSceneLoader.cs | 2 +- scripts/loader/uiLoader/PacksackUi.cs | 3 +- scripts/utils/UiGroup.cs | 124 ++++++++++++++++++ 9 files changed, 151 insertions(+), 45 deletions(-) create mode 100644 scripts/utils/UiGroup.cs diff --git a/prefab/roomTemplates/dungeon/initialRoom.tscn b/prefab/roomTemplates/dungeon/initialRoom.tscn index 5387b44..6767cd1 100644 --- a/prefab/roomTemplates/dungeon/initialRoom.tscn +++ b/prefab/roomTemplates/dungeon/initialRoom.tscn @@ -79,5 +79,4 @@ texture = ExtResource("5_4pssd") [node name="RigidBody2D" parent="." instance=ExtResource("5_7c8bh")] position = Vector2(149, 109) -collision_layer = 256 collision_mask = 0 diff --git a/scenes/game.tscn b/scenes/game.tscn index bba6d90..115c3b5 100644 --- a/scenes/game.tscn +++ b/scenes/game.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=8 format=3 uid="uid://bnftvkj2cido7"] +[gd_scene load_steps=9 format=3 uid="uid://bnftvkj2cido7"] [ext_resource type="Script" path="res://scripts/loader/sceneLoader/GameSceneLoader.cs" id="1_mqdgt"] [ext_resource type="Texture2D" uid="uid://cs6e0af876ss5" path="res://sprites/ui/HeartEmpty.png" id="2_n1yht"] @@ -7,6 +7,7 @@ [ext_resource type="Script" path="res://scripts/FpsLabel.cs" id="5_dis4v"] [ext_resource type="PackedScene" uid="uid://c74180dtf7j7a" path="res://scenes/mapContainer.tscn" id="6_ljdj4"] [ext_resource type="PackedScene" uid="uid://bb188382q7btp" path="res://scenes/gameOverMenu.tscn" id="6_yjmrv"] +[ext_resource type="Script" path="res://scripts/utils/UiGroup.cs" id="7_p0u6a"] [node name="Game" type="Node2D"] script = ExtResource("1_mqdgt") @@ -103,6 +104,7 @@ anchor_bottom = 1.0 grow_horizontal = 2 grow_vertical = 2 mouse_filter = 2 +script = ExtResource("7_p0u6a") [node name="GameOverMenu" parent="CanvasLayer" instance=ExtResource("6_yjmrv")] visible = false diff --git a/scripts/GameSceneDepend.cs b/scripts/GameSceneDepend.cs index 2b1b4dc..5b5d5d9 100644 --- a/scripts/GameSceneDepend.cs +++ b/scripts/GameSceneDepend.cs @@ -1,6 +1,5 @@ using ColdMint.scripts.character; using ColdMint.scripts.inventory; -using ColdMint.scripts.loader.uiLoader; using ColdMint.scripts.map.miniMap; using ColdMint.scripts.utils; using Godot; @@ -101,35 +100,5 @@ public static class GameSceneDepend ///The knapsack Ui container houses the container of the knapsack ui node. When a user uses a backpack, the node to which his backpack is attached is displayed from within the backpack ui container. ///背包Ui容器内存放的是背包ui节点的容器。当用户使用背包时,会从背包ui容器内将其背包对于的节点展示出来。 /// - public static Control? BackpackUiContainer { get; set; } - - - /// - /// Hide the knapsack node in the knapsack Ui if the knapsack UI is displayed - /// 如果背包Ui处于显示状态,那么隐藏背包UI内的背包节点 - /// - public static void HideBackpackUiContainerIfVisible() - { - if (BackpackUiContainer == null) - { - return; - } - - if (!BackpackUiContainer.Visible) - { - return; - } - - NodeUtils.ForEachNode(BackpackUiContainer, node => - { - //If the child node is not visible, the traversal continues. - //如果子节点不可见,则继续遍历。 - if (!node.Visible) - return false; - //Until you find a visible node, hide it, and return true, ending the loop. - //直到找到可见的节点,隐藏该节点,然后返回true,结束遍历。 - node.Hide(); - return true; - }); - } + public static UiGroup? BackpackUiContainer { get; set; } } \ No newline at end of file diff --git a/scripts/character/CharacterTemplate.cs b/scripts/character/CharacterTemplate.cs index 5966795..553430d 100644 --- a/scripts/character/CharacterTemplate.cs +++ b/scripts/character/CharacterTemplate.cs @@ -626,7 +626,7 @@ public partial class CharacterTemplate : CharacterBody2D { if (_additionalForce != Vector2.Zero) { - throw new InvalidOperationException("AddForce called more than once"); + return; } _additionalForce = force; diff --git a/scripts/character/Player.cs b/scripts/character/Player.cs index 5bead97..6b5897b 100644 --- a/scripts/character/Player.cs +++ b/scripts/character/Player.cs @@ -89,7 +89,7 @@ public partial class Player : CharacterTemplate private void SelectedItemSlotChangeEvent(SelectedItemSlotChangeEvent selectedItemSlotChangeEvent) { var item = selectedItemSlotChangeEvent.NewItemSlotNode?.GetItem(); - GameSceneDepend.HideBackpackUiContainerIfVisible(); + GameSceneDepend.BackpackUiContainer?.HideAllControl(); if (item is Node2D node2D) { CurrentItem = node2D; @@ -303,7 +303,7 @@ public partial class Player : CharacterTemplate } ThrowItem(ItemContainer.GetSelectIndex(), 1, GetThrowVelocity()); - GameSceneDepend.HideBackpackUiContainerIfVisible(); + GameSceneDepend.BackpackUiContainer?.HideAllControl(); CurrentItem = null; } } diff --git a/scripts/inventory/Packsack.cs b/scripts/inventory/Packsack.cs index 1a36e31..1245dd7 100644 --- a/scripts/inventory/Packsack.cs +++ b/scripts/inventory/Packsack.cs @@ -14,7 +14,7 @@ public partial class Packsack : PickAbleTemplate private PackedScene? _packedScene; private PacksackUi? _packsackUi; [Export] public int NumberSlots { get; set; } - + /// /// Whether to allow backpacks /// 是否允许放置背包 @@ -23,7 +23,8 @@ public partial class Packsack : PickAbleTemplate ///Can a new backpack be placed in the slot of the backpack? ///即此背包的槽位内是否可以再放置新的背包? /// - [Export] public bool BackpackAllowed { get; set; } + [Export] + public bool BackpackAllowed { get; set; } public override bool CanPutInPack => false; @@ -40,14 +41,26 @@ public partial class Packsack : PickAbleTemplate _packsackUi = NodeUtils.InstantiatePackedScene(_packedScene); if (_packsackUi != null) { - NodeUtils.CallDeferredAddChild(NodeUtils.FindContainerNode(_packsackUi, this), _packsackUi); + var containerNode = NodeUtils.FindContainerNode(_packsackUi, this); + if (containerNode is UiGroup uiGroup) + { + uiGroup.RegisterControl(_packsackUi); + } + else + { + NodeUtils.CallDeferredAddChild(containerNode, _packsackUi); + } + _packsackUi.Title = Name; _packsackUi.ItemContainer = ItemContainer; + _packsackUi.Hide(); } } - GameSceneDepend.BackpackUiContainer?.Show(); - _packsackUi?.Show(); + if (_packsackUi != null) + { + GameSceneDepend.BackpackUiContainer?.ShowControl(_packsackUi); + } } public IItemContainer? ItemContainer { get; private set; } diff --git a/scripts/loader/sceneLoader/GameSceneLoader.cs b/scripts/loader/sceneLoader/GameSceneLoader.cs index 2db575f..551e0c7 100644 --- a/scripts/loader/sceneLoader/GameSceneLoader.cs +++ b/scripts/loader/sceneLoader/GameSceneLoader.cs @@ -31,7 +31,7 @@ public partial class GameSceneLoader : SceneLoaderTemplate GameSceneDepend.HotBar = hotBar; //Backpack Ui container //背包Ui容器 - var backpackUiContainer = GetNode("CanvasLayer/BackpackUIContainer"); + var backpackUiContainer = GetNode("CanvasLayer/BackpackUIContainer"); GameSceneDepend.BackpackUiContainer = backpackUiContainer; //Load operation prompt //加载操作提示 diff --git a/scripts/loader/uiLoader/PacksackUi.cs b/scripts/loader/uiLoader/PacksackUi.cs index ab1b998..4ad9470 100644 --- a/scripts/loader/uiLoader/PacksackUi.cs +++ b/scripts/loader/uiLoader/PacksackUi.cs @@ -107,8 +107,7 @@ public partial class PacksackUi : UiLoaderTemplate { _exitButton.Pressed += () => { - GameSceneDepend.BackpackUiContainer?.Hide(); - Hide(); + GameSceneDepend.BackpackUiContainer?.HideControl(this); }; } } diff --git a/scripts/utils/UiGroup.cs b/scripts/utils/UiGroup.cs new file mode 100644 index 0000000..6bd7d1a --- /dev/null +++ b/scripts/utils/UiGroup.cs @@ -0,0 +1,124 @@ +using System.Collections.Generic; +using Godot; + +namespace ColdMint.scripts.utils; + +/// +/// UI Group +/// UI组 +/// +public partial class UiGroup : Control +{ + private readonly HashSet _visibleControls = []; + private readonly HashSet _allControls = []; + + /// + /// How many nodes are visible + /// 有多少个节点处于可见状态 + /// + public int VisibleControlsCount => _visibleControls.Count; + + /// + /// Register nodes in the UI group. For registered nodes, do not use or to change the visible state. Call the and methods instead. + /// 注册节点到UI组内,对于已注册的节点,不要直接使用方法来改变可见状态,请调用方法来替代他们。 + /// + /// + public void RegisterControl(Control control) + { + control.TreeExited += () => { OnTreeExited(control); }; + NodeUtils.CallDeferredAddChild(this, control); + _allControls.Add(control); + } + + /// + /// Hide all nodes + /// 隐藏全部节点 + /// + public void HideAllControl() + { + if (_visibleControls.Count == 0) + { + return; + } + + foreach (var visibleControl in _visibleControls) + { + visibleControl.Hide(); + } + + _visibleControls.Clear(); + Hide(); + } + + /// + /// Hide a node + /// 隐藏某个节点 + /// + /// + /// + public bool HideControl(Control control) + { + if (!control.IsVisible()) + { + return false; + } + + if (!_allControls.Contains(control)) + { + return false; + } + + control.Hide(); + _visibleControls.Remove(control); + ChangeSelfVisibility(); + return true; + } + + /// + /// Show node + /// 显示某个节点 + /// + /// + /// + public bool ShowControl(Control control) + { + if (control.IsVisible()) + { + return false; + } + + if (!_allControls.Contains(control)) + { + return false; + } + + control.Show(); + _visibleControls.Add(control); + ChangeSelfVisibility(); + return true; + } + + /// + /// ChangeSelfVisibility + /// 改变自身的可见度 + /// + private void ChangeSelfVisibility() + { + if (_visibleControls.Count == 0) + { + Hide(); + } + else + { + Show(); + } + } + + private void OnTreeExited(Control control) + { + //The Hide method is not called when a node exits from the tree, so remove the node here to prevent empty references. + //当节点从节点树内退出时,并不会调用Hide方法,所以在这里移除节点,防止产生空引用。 + _visibleControls.Remove(control); + _allControls.Remove(control); + } +} \ No newline at end of file