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")]
|
[node name="RigidBody2D" parent="." instance=ExtResource("5_7c8bh")]
|
||||||
position = Vector2(149, 109)
|
position = Vector2(149, 109)
|
||||||
collision_layer = 256
|
|
||||||
collision_mask = 0
|
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="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"]
|
[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="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://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="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"]
|
[node name="Game" type="Node2D"]
|
||||||
script = ExtResource("1_mqdgt")
|
script = ExtResource("1_mqdgt")
|
||||||
|
@ -103,6 +104,7 @@ anchor_bottom = 1.0
|
||||||
grow_horizontal = 2
|
grow_horizontal = 2
|
||||||
grow_vertical = 2
|
grow_vertical = 2
|
||||||
mouse_filter = 2
|
mouse_filter = 2
|
||||||
|
script = ExtResource("7_p0u6a")
|
||||||
|
|
||||||
[node name="GameOverMenu" parent="CanvasLayer" instance=ExtResource("6_yjmrv")]
|
[node name="GameOverMenu" parent="CanvasLayer" instance=ExtResource("6_yjmrv")]
|
||||||
visible = false
|
visible = false
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
using ColdMint.scripts.character;
|
using ColdMint.scripts.character;
|
||||||
using ColdMint.scripts.inventory;
|
using ColdMint.scripts.inventory;
|
||||||
using ColdMint.scripts.loader.uiLoader;
|
|
||||||
using ColdMint.scripts.map.miniMap;
|
using ColdMint.scripts.map.miniMap;
|
||||||
using ColdMint.scripts.utils;
|
using ColdMint.scripts.utils;
|
||||||
using Godot;
|
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>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>
|
///<para>背包Ui容器内存放的是背包ui节点的容器。当用户使用背包时,会从背包ui容器内将其背包对于的节点展示出来。</para>
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public static Control? BackpackUiContainer { get; set; }
|
public static UiGroup? 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;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -626,7 +626,7 @@ public partial class CharacterTemplate : CharacterBody2D
|
||||||
{
|
{
|
||||||
if (_additionalForce != Vector2.Zero)
|
if (_additionalForce != Vector2.Zero)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException("AddForce called more than once");
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_additionalForce = force;
|
_additionalForce = force;
|
||||||
|
|
|
@ -89,7 +89,7 @@ public partial class Player : CharacterTemplate
|
||||||
private void SelectedItemSlotChangeEvent(SelectedItemSlotChangeEvent selectedItemSlotChangeEvent)
|
private void SelectedItemSlotChangeEvent(SelectedItemSlotChangeEvent selectedItemSlotChangeEvent)
|
||||||
{
|
{
|
||||||
var item = selectedItemSlotChangeEvent.NewItemSlotNode?.GetItem();
|
var item = selectedItemSlotChangeEvent.NewItemSlotNode?.GetItem();
|
||||||
GameSceneDepend.HideBackpackUiContainerIfVisible();
|
GameSceneDepend.BackpackUiContainer?.HideAllControl();
|
||||||
if (item is Node2D node2D)
|
if (item is Node2D node2D)
|
||||||
{
|
{
|
||||||
CurrentItem = node2D;
|
CurrentItem = node2D;
|
||||||
|
@ -303,7 +303,7 @@ public partial class Player : CharacterTemplate
|
||||||
}
|
}
|
||||||
|
|
||||||
ThrowItem(ItemContainer.GetSelectIndex(), 1, GetThrowVelocity());
|
ThrowItem(ItemContainer.GetSelectIndex(), 1, GetThrowVelocity());
|
||||||
GameSceneDepend.HideBackpackUiContainerIfVisible();
|
GameSceneDepend.BackpackUiContainer?.HideAllControl();
|
||||||
CurrentItem = null;
|
CurrentItem = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ public partial class Packsack : PickAbleTemplate
|
||||||
private PackedScene? _packedScene;
|
private PackedScene? _packedScene;
|
||||||
private PacksackUi? _packsackUi;
|
private PacksackUi? _packsackUi;
|
||||||
[Export] public int NumberSlots { get; set; }
|
[Export] public int NumberSlots { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// <para>Whether to allow backpacks</para>
|
/// <para>Whether to allow backpacks</para>
|
||||||
/// <para>是否允许放置背包</para>
|
/// <para>是否允许放置背包</para>
|
||||||
|
@ -23,7 +23,8 @@ public partial class Packsack : PickAbleTemplate
|
||||||
///<para>Can a new backpack be placed in the slot of the backpack?</para>
|
///<para>Can a new backpack be placed in the slot of the backpack?</para>
|
||||||
///<para>即此背包的槽位内是否可以再放置新的背包?</para>
|
///<para>即此背包的槽位内是否可以再放置新的背包?</para>
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[Export] public bool BackpackAllowed { get; set; }
|
[Export]
|
||||||
|
public bool BackpackAllowed { get; set; }
|
||||||
|
|
||||||
public override bool CanPutInPack => false;
|
public override bool CanPutInPack => false;
|
||||||
|
|
||||||
|
@ -40,14 +41,26 @@ public partial class Packsack : PickAbleTemplate
|
||||||
_packsackUi = NodeUtils.InstantiatePackedScene<PacksackUi>(_packedScene);
|
_packsackUi = NodeUtils.InstantiatePackedScene<PacksackUi>(_packedScene);
|
||||||
if (_packsackUi != null)
|
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.Title = Name;
|
||||||
_packsackUi.ItemContainer = ItemContainer;
|
_packsackUi.ItemContainer = ItemContainer;
|
||||||
|
_packsackUi.Hide();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GameSceneDepend.BackpackUiContainer?.Show();
|
if (_packsackUi != null)
|
||||||
_packsackUi?.Show();
|
{
|
||||||
|
GameSceneDepend.BackpackUiContainer?.ShowControl(_packsackUi);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IItemContainer? ItemContainer { get; private set; }
|
public IItemContainer? ItemContainer { get; private set; }
|
||||||
|
|
|
@ -31,7 +31,7 @@ public partial class GameSceneLoader : SceneLoaderTemplate
|
||||||
GameSceneDepend.HotBar = hotBar;
|
GameSceneDepend.HotBar = hotBar;
|
||||||
//Backpack Ui container
|
//Backpack Ui container
|
||||||
//背包Ui容器
|
//背包Ui容器
|
||||||
var backpackUiContainer = GetNode<Control>("CanvasLayer/BackpackUIContainer");
|
var backpackUiContainer = GetNode<UiGroup>("CanvasLayer/BackpackUIContainer");
|
||||||
GameSceneDepend.BackpackUiContainer = backpackUiContainer;
|
GameSceneDepend.BackpackUiContainer = backpackUiContainer;
|
||||||
//Load operation prompt
|
//Load operation prompt
|
||||||
//加载操作提示
|
//加载操作提示
|
||||||
|
|
|
@ -107,8 +107,7 @@ public partial class PacksackUi : UiLoaderTemplate
|
||||||
{
|
{
|
||||||
_exitButton.Pressed += () =>
|
_exitButton.Pressed += () =>
|
||||||
{
|
{
|
||||||
GameSceneDepend.BackpackUiContainer?.Hide();
|
GameSceneDepend.BackpackUiContainer?.HideControl(this);
|
||||||
Hide();
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
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