Improve the efficiency of backpack UI toggle visibility. Prepare for the upcoming workbench UI.
提升背包UI切换可见度时的效率。为即将到来的工作台UI做准备。
This commit is contained in:
parent
ba11bf06da
commit
c25d985f87
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|||
///<para>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.</para>
|
||||
///<para>背包Ui容器内存放的是背包ui节点的容器。当用户使用背包时,会从背包ui容器内将其背包对于的节点展示出来。</para>
|
||||
/// </remarks>
|
||||
public static Control? BackpackUiContainer { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// <para>Hide the knapsack node in the knapsack Ui if the knapsack UI is displayed</para>
|
||||
/// <para>如果背包Ui处于显示状态,那么隐藏背包UI内的背包节点</para>
|
||||
/// </summary>
|
||||
public static void HideBackpackUiContainerIfVisible()
|
||||
{
|
||||
if (BackpackUiContainer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!BackpackUiContainer.Visible)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
NodeUtils.ForEachNode<PacksackUi>(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; }
|
||||
}
|
|
@ -626,7 +626,7 @@ public partial class CharacterTemplate : CharacterBody2D
|
|||
{
|
||||
if (_additionalForce != Vector2.Zero)
|
||||
{
|
||||
throw new InvalidOperationException("AddForce called more than once");
|
||||
return;
|
||||
}
|
||||
|
||||
_additionalForce = force;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,8 @@ public partial class Packsack : PickAbleTemplate
|
|||
///<para>Can a new backpack be placed in the slot of the backpack?</para>
|
||||
///<para>即此背包的槽位内是否可以再放置新的背包?</para>
|
||||
/// </remarks>
|
||||
[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<PacksackUi>(_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; }
|
||||
|
|
|
@ -31,7 +31,7 @@ public partial class GameSceneLoader : SceneLoaderTemplate
|
|||
GameSceneDepend.HotBar = hotBar;
|
||||
//Backpack Ui container
|
||||
//背包Ui容器
|
||||
var backpackUiContainer = GetNode<Control>("CanvasLayer/BackpackUIContainer");
|
||||
var backpackUiContainer = GetNode<UiGroup>("CanvasLayer/BackpackUIContainer");
|
||||
GameSceneDepend.BackpackUiContainer = backpackUiContainer;
|
||||
//Load operation prompt
|
||||
//加载操作提示
|
||||
|
|
|
@ -107,8 +107,7 @@ public partial class PacksackUi : UiLoaderTemplate
|
|||
{
|
||||
_exitButton.Pressed += () =>
|
||||
{
|
||||
GameSceneDepend.BackpackUiContainer?.Hide();
|
||||
Hide();
|
||||
GameSceneDepend.BackpackUiContainer?.HideControl(this);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
124
scripts/utils/UiGroup.cs
Normal file
124
scripts/utils/UiGroup.cs
Normal file
|
@ -0,0 +1,124 @@
|
|||
using System.Collections.Generic;
|
||||
using Godot;
|
||||
|
||||
namespace ColdMint.scripts.utils;
|
||||
|
||||
/// <summary>
|
||||
/// <para>UI Group</para>
|
||||
/// <para>UI组</para>
|
||||
/// </summary>
|
||||
public partial class UiGroup : Control
|
||||
{
|
||||
private readonly HashSet<Control> _visibleControls = [];
|
||||
private readonly HashSet<Control> _allControls = [];
|
||||
|
||||
/// <summary>
|
||||
/// <para>How many nodes are visible</para>
|
||||
/// <para>有多少个节点处于可见状态</para>
|
||||
/// </summary>
|
||||
public int VisibleControlsCount => _visibleControls.Count;
|
||||
|
||||
/// <summary>
|
||||
/// <para>Register nodes in the UI group. For registered nodes, do not use <see cref="Godot.CanvasItem.Show"/> or <see cref="Godot.CanvasItem.Hide"/> to change the visible state. Call the <see cref="ShowControl"/> and <see cref="HideControl"/> methods instead.</para>
|
||||
/// <para>注册节点到UI组内,对于已注册的节点,不要直接使用<see cref="Godot.CanvasItem.Show"/>或<see cref="Godot.CanvasItem.Hide"/>方法来改变可见状态,请调用<see cref="ShowControl"/>和<see cref="HideControl"/>方法来替代他们。</para>
|
||||
/// </summary>
|
||||
/// <param name="control"></param>
|
||||
public void RegisterControl(Control control)
|
||||
{
|
||||
control.TreeExited += () => { OnTreeExited(control); };
|
||||
NodeUtils.CallDeferredAddChild(this, control);
|
||||
_allControls.Add(control);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Hide all nodes</para>
|
||||
/// <para>隐藏全部节点</para>
|
||||
/// </summary>
|
||||
public void HideAllControl()
|
||||
{
|
||||
if (_visibleControls.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var visibleControl in _visibleControls)
|
||||
{
|
||||
visibleControl.Hide();
|
||||
}
|
||||
|
||||
_visibleControls.Clear();
|
||||
Hide();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Hide a node</para>
|
||||
/// <para>隐藏某个节点</para>
|
||||
/// </summary>
|
||||
/// <param name="control"></param>
|
||||
/// <returns></returns>
|
||||
public bool HideControl(Control control)
|
||||
{
|
||||
if (!control.IsVisible())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_allControls.Contains(control))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
control.Hide();
|
||||
_visibleControls.Remove(control);
|
||||
ChangeSelfVisibility();
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Show node</para>
|
||||
/// <para>显示某个节点</para>
|
||||
/// </summary>
|
||||
/// <param name="control"></param>
|
||||
/// <returns></returns>
|
||||
public bool ShowControl(Control control)
|
||||
{
|
||||
if (control.IsVisible())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_allControls.Contains(control))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
control.Show();
|
||||
_visibleControls.Add(control);
|
||||
ChangeSelfVisibility();
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>ChangeSelfVisibility</para>
|
||||
/// <para>改变自身的可见度</para>
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user