Supports the use of mouse wheel and keyboard number keys to adjust HotBar selected items.

支持使用鼠标滚轮和键盘数字键调整HotBar选中的项目了。
This commit is contained in:
Cold-Mint 2024-05-03 22:35:54 +08:00
parent a1d40d09b1
commit b7939af5d0
Signed by: Cold-Mint
GPG Key ID: C5A9BF8A98E0CE99
10 changed files with 345 additions and 107 deletions

View File

@ -1,6 +1,7 @@
id,zh,en
product_name,异界旅人,A traveler from another world
start_game,开始游戏,Start game
settings,设置,Settings
pick_up,拾捡,Pick up
move_left,向左移动,Move left
move_right,向右移动,Move right

1 id zh en
2 product_name 异界旅人 A traveler from another world
3 start_game 开始游戏 Start game
4 settings 设置 Settings
5 pick_up 拾捡 Pick up
6 move_left 向左移动 Move left
7 move_right 向右移动 Move right

Binary file not shown.

Binary file not shown.

View File

@ -24,9 +24,8 @@ grow_horizontal = 2
grow_vertical = 2
scale = Vector2(0.2, 0.2)
[node name="IconTextureRect" type="TextureButton" parent="BackgroundTexture/CenterContainer"]
[node name="IconTextureRect" type="TextureRect" parent="BackgroundTexture/CenterContainer"]
layout_mode = 2
tooltip_text = "老婆"
[node name="Control" type="Control" parent="."]
layout_mode = 2

View File

@ -88,6 +88,66 @@ use_item={
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":1,"position":Vector2(211, 16),"global_position":Vector2(215, 57),"factor":1.0,"button_index":1,"canceled":false,"pressed":true,"double_click":false,"script":null)
]
}
hotbar_1={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":49,"physical_keycode":0,"key_label":0,"unicode":49,"echo":false,"script":null)
]
}
hotbar_2={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":50,"physical_keycode":0,"key_label":0,"unicode":50,"echo":false,"script":null)
]
}
hotbar_3={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":51,"physical_keycode":0,"key_label":0,"unicode":51,"echo":false,"script":null)
]
}
hotbar_4={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":52,"physical_keycode":0,"key_label":0,"unicode":52,"echo":false,"script":null)
]
}
hotbar_5={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":53,"physical_keycode":0,"key_label":0,"unicode":53,"echo":false,"script":null)
]
}
hotbar_6={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":54,"physical_keycode":0,"key_label":0,"unicode":54,"echo":false,"script":null)
]
}
hotbar_7={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":55,"physical_keycode":0,"key_label":0,"unicode":55,"echo":false,"script":null)
]
}
hotbar_8={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":56,"physical_keycode":0,"key_label":0,"unicode":56,"echo":false,"script":null)
]
}
hotbar_9={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":57,"physical_keycode":0,"key_label":0,"unicode":57,"echo":false,"script":null)
]
}
hotbar_10={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":48,"physical_keycode":0,"key_label":0,"unicode":48,"echo":false,"script":null)
]
}
hotbar_next={
"deadzone": 0.5,
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":16,"position":Vector2(241, 17),"global_position":Vector2(245, 58),"factor":1.0,"button_index":5,"canceled":false,"pressed":true,"double_click":false,"script":null)
]
}
hotbar_previous={
"deadzone": 0.5,
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":8,"position":Vector2(169, 17),"global_position":Vector2(173, 58),"factor":1.0,"button_index":4,"canceled":false,"pressed":true,"double_click":false,"script":null)
]
}
[internationalization]

View File

@ -25,6 +25,18 @@ offset_bottom = 201.0
grow_horizontal = 2
text = "start_game"
[node name="SettingsButton" type="Button" parent="."]
layout_mode = 1
anchors_preset = 5
anchor_left = 0.5
anchor_right = 0.5
offset_left = -44.5
offset_top = 215.0
offset_right = 50.5
offset_bottom = 248.0
grow_horizontal = 2
text = "settings"
[node name="VBoxContainer" type="VBoxContainer" parent="."]
layout_mode = 1
anchors_preset = 2
@ -38,11 +50,13 @@ grow_vertical = 0
[node name="GithubLink" type="LinkButton" parent="VBoxContainer"]
layout_mode = 2
focus_mode = 2
text = "Github"
uri = "https://github.com/Cold-Mint/Traveller"
[node name="BiliBiliLink" type="LinkButton" parent="VBoxContainer"]
layout_mode = 2
focus_mode = 2
text = "Bilibili"
uri = "https://space.bilibili.com/1383759192"

View File

@ -85,7 +85,13 @@ public static class Config
/// <para>公司/创作者名字</para>
/// </summary>
public const string CompanyName = "ColdMint";
/// <summary>
/// <para>How many item slots are there on the shortcut bar</para>
/// <para>快捷栏上有多少个物品槽</para>
/// </summary>
public const int HotBarSize = 10;
/// <summary>
/// <para>UserID</para>
@ -127,7 +133,7 @@ public static class Config
stringBuilder.Append(IsDebug() ? "_debug" : "_release");
return stringBuilder.ToString();
}
/// <summary>
/// <para>GetGameDataDirectory</para>
/// <para>获取游戏数据目录</para>

View File

@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using ColdMint.scripts.debug;
using Godot;
namespace ColdMint.scripts.inventory;
@ -8,18 +9,143 @@ public partial class HotBar : HBoxContainer
{
private PackedScene _itemSlotPackedScene;
private List<ItemSlotNode> _itemSlotNodes;
private int selectIndex = 0;
public override void _Ready()
{
base._Ready();
_itemSlotNodes = new List<ItemSlotNode>();
_itemSlotPackedScene = GD.Load<PackedScene>("res://prefab/ui/ItemSlot.tscn");
for (int i = 0; i < 10; i++)
for (var i = 0; i < Config.HotBarSize; i++)
{
AddItemSlot();
AddItemSlot(i);
}
}
public override void _Process(double delta)
{
base._Process(delta);
if (Input.IsActionJustPressed("hotbar_next"))
{
var count = _itemSlotNodes.Count;
if (count == 0)
{
return;
}
//Mouse wheel down
//鼠标滚轮向下
var oldSelectIndex = selectIndex;
selectIndex++;
if (selectIndex >= count)
{
selectIndex = 0;
}
SelectItemSlot(oldSelectIndex, selectIndex);
}
if (Input.IsActionJustPressed("hotbar_previous"))
{
var count = _itemSlotNodes.Count;
if (count == 0)
{
return;
}
//Mouse wheel up
//鼠标滚轮向上
var oldSelectIndex = selectIndex;
selectIndex--;
if (selectIndex < 0)
{
selectIndex = count - 1;
}
SelectItemSlot(oldSelectIndex, selectIndex);
}
if (Input.IsActionJustPressed("hotbar_1"))
{
SelectItemSlotByHotBarShortcutKey(0);
}
if (Input.IsActionJustPressed("hotbar_2"))
{
SelectItemSlotByHotBarShortcutKey(1);
}
if (Input.IsActionJustPressed("hotbar_3"))
{
SelectItemSlotByHotBarShortcutKey(2);
}
if (Input.IsActionJustPressed("hotbar_4"))
{
SelectItemSlotByHotBarShortcutKey(3);
}
if (Input.IsActionJustPressed("hotbar_5"))
{
SelectItemSlotByHotBarShortcutKey(4);
}
if (Input.IsActionJustPressed("hotbar_6"))
{
SelectItemSlotByHotBarShortcutKey(5);
}
if (Input.IsActionJustPressed("hotbar_7"))
{
SelectItemSlotByHotBarShortcutKey(6);
}
if (Input.IsActionJustPressed("hotbar_8"))
{
SelectItemSlotByHotBarShortcutKey(7);
}
if (Input.IsActionJustPressed("hotbar_9"))
{
SelectItemSlotByHotBarShortcutKey(8);
}
if (Input.IsActionJustPressed("hotbar_10"))
{
SelectItemSlotByHotBarShortcutKey(9);
}
}
/// <summary>
/// <para>Select the HotBar project using the shortcut keys</para>
/// <para>通过快捷键选择HotBar项目</para>
/// </summary>
/// <para>The Pc version of the shortcut key index is 0-9</para>
/// <para>Pc版本的快捷键索引为0-9</para>
/// <param name="shortcutKeyIndex"></param>
private void SelectItemSlotByHotBarShortcutKey(int shortcutKeyIndex)
{
var count = _itemSlotNodes.Count;
if (count == 0)
{
//Prevents the dividend from being 0
//防止被除数为0
return;
}
var newIndex = shortcutKeyIndex % count;
SelectItemSlot(selectIndex, newIndex);
selectIndex = newIndex;
}
/// <summary>
/// <para>Select an item slot</para>
/// <para>选中某个物品槽</para>
/// </summary>
private void SelectItemSlot(int oldSelectIndex, int newSelectIndex)
{
_itemSlotNodes[oldSelectIndex].IsSelect = false;
_itemSlotNodes[newSelectIndex].IsSelect = true;
}
/// <summary>
/// <para>Add an item to the HotBar</para>
/// <para>在HotBar内添加一个物品</para>
@ -36,10 +162,16 @@ public partial class HotBar : HBoxContainer
/// <para>Add items tank</para>
/// <para>添加物品槽</para>
/// </summary>
private void AddItemSlot()
private void AddItemSlot(int index)
{
var node = _itemSlotPackedScene.Instantiate();
AddChild(node);
_itemSlotNodes.Add(node as ItemSlotNode);
var itemSlotNode = _itemSlotPackedScene.Instantiate() as ItemSlotNode;
if (itemSlotNode == null)
{
return;
}
AddChild(itemSlotNode);
itemSlotNode.IsSelect = index == selectIndex;
_itemSlotNodes.Add(itemSlotNode);
}
}

View File

@ -8,107 +8,132 @@ namespace ColdMint.scripts.inventory;
/// </summary>
public partial class ItemSlotNode : MarginContainer
{
private IItem? _item;
private TextureRect _backgroundTextureRect;
private TextureButton _iconTextureRect;
private Label _quantityLabel;
private Control _control;
private IItem? _item;
private TextureRect _backgroundTextureRect;
private TextureRect _iconTextureRect;
private Label _quantityLabel;
private Control _control;
private bool _isSelect;
private Texture2D _backgroundTexture;
private Texture2D _backgroundTextureWhenSelect;
/// <summary>
/// <para>Sets items for the item slot</para>
/// <para>为物品槽设置物品</para>
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
public bool SetItem(IItem item)
{
if (_item == null)
{
if (item.Icon != null)
{
_iconTextureRect.TextureNormal = item.Icon;
}
public bool IsSelect
{
get => _isSelect;
set
{
if (value)
{
_backgroundTextureRect.Texture = _backgroundTextureWhenSelect;
}
else
{
_backgroundTextureRect.Texture = _backgroundTexture;
}
_isSelect = value;
}
}
_item = item;
UpdateTooltipText(item);
UpdateQuantityLabel(item.Quantity);
return true;
}
else
{
//This inventory already has items, but the items in this inventory are not the same as the incoming items
//这个物品栏已经有物品了,但是这个物品栏的物品和传入的物品不一样
if (_item.Id != item.Id)
{
return false;
}
public TextureRect BackgroundTextureRect => _backgroundTextureRect;
var newQuantity = _item.Quantity + item.Quantity;
if (newQuantity > item.MaxStackQuantity)
{
//If the amount of the current item exceeds the maximum stack amount after placing it in this inventory
//如果将当前物品放置到这个物品栏后,数量超过了最大叠加数量
return false;
}
/// <summary>
/// <para>Sets items for the item slot</para>
/// <para>为物品槽设置物品</para>
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
public bool SetItem(IItem item)
{
if (_item == null)
{
if (item.Icon != null)
{
_iconTextureRect.Texture = item.Icon;
}
_item.Quantity = newQuantity;
UpdateTooltipText(item);
UpdateQuantityLabel(newQuantity);
return true;
}
}
_item = item;
UpdateTooltipText(item);
UpdateQuantityLabel(item.Quantity);
return true;
}
else
{
//This inventory already has items, but the items in this inventory are not the same as the incoming items
//这个物品栏已经有物品了,但是这个物品栏的物品和传入的物品不一样
if (_item.Id != item.Id)
{
return false;
}
/// <summary>
/// <para>Update item tips</para>
/// <para>更新物品的提示内容</para>
/// </summary>
/// <param name="item"></param>
private void UpdateTooltipText(IItem item)
{
if (Config.IsDebug())
{
_control.TooltipText = string.Format(TranslationServer.Translate("item_prompt_debug"), item.Id,
TranslationServer.Translate(item.Name),
item.Quantity, item.MaxStackQuantity, item.GetType().Name, TranslationServer.Translate(item.Description));
}
else
{
_control.TooltipText = TranslationServer.Translate(item.Name) + "\n" +
TranslationServer.Translate(item.Description);
}
}
var newQuantity = _item.Quantity + item.Quantity;
if (newQuantity > item.MaxStackQuantity)
{
//If the amount of the current item exceeds the maximum stack amount after placing it in this inventory
//如果将当前物品放置到这个物品栏后,数量超过了最大叠加数量
return false;
}
/// <summary>
/// <para>Update quantity label</para>
/// <para>更新数量标签</para>
/// </summary>
/// <param name="quantity"></param>
private void UpdateQuantityLabel(int? quantity)
{
switch (quantity)
{
case null:
_quantityLabel.Visible = false;
return;
case > 1:
//When the quantity is greater than 1, we display the quantity.
//当数量大于1时我们显示数量
_quantityLabel.Text = quantity.ToString();
_quantityLabel.Visible = true;
break;
default:
_quantityLabel.Visible = false;
break;
}
}
_item.Quantity = newQuantity;
UpdateTooltipText(item);
UpdateQuantityLabel(newQuantity);
return true;
}
}
public override void _Ready()
{
_backgroundTextureRect =
GetNode<TextureRect>("BackgroundTexture");
_iconTextureRect = GetNode<TextureButton>("BackgroundTexture/CenterContainer/IconTextureRect");
_quantityLabel = GetNode<Label>("Control/QuantityLabel");
_control = GetNode<Control>("Control");
_quantityLabel.Visible = false;
}
}
/// <summary>
/// <para>Update item tips</para>
/// <para>更新物品的提示内容</para>
/// </summary>
/// <param name="item"></param>
private void UpdateTooltipText(IItem item)
{
if (Config.IsDebug())
{
_control.TooltipText = string.Format(TranslationServer.Translate("item_prompt_debug"), item.Id,
TranslationServer.Translate(item.Name),
item.Quantity, item.MaxStackQuantity, item.GetType().Name,
TranslationServer.Translate(item.Description));
}
else
{
_control.TooltipText = TranslationServer.Translate(item.Name) + "\n" +
TranslationServer.Translate(item.Description);
}
}
/// <summary>
/// <para>Update quantity label</para>
/// <para>更新数量标签</para>
/// </summary>
/// <param name="quantity"></param>
private void UpdateQuantityLabel(int? quantity)
{
switch (quantity)
{
case null:
_quantityLabel.Visible = false;
return;
case > 1:
//When the quantity is greater than 1, we display the quantity.
//当数量大于1时我们显示数量
_quantityLabel.Text = quantity.ToString();
_quantityLabel.Visible = true;
break;
default:
_quantityLabel.Visible = false;
break;
}
}
public override void _Ready()
{
_backgroundTexture = GD.Load<Texture2D>("res://sprites/ui/ItemBarEmpty.png");
_backgroundTextureWhenSelect = GD.Load<Texture2D>("res://sprites/ui/ItemBarFocus.png");
_backgroundTextureRect =
GetNode<TextureRect>("BackgroundTexture");
_iconTextureRect = GetNode<TextureRect>("BackgroundTexture/CenterContainer/IconTextureRect");
_quantityLabel = GetNode<Label>("Control/QuantityLabel");
_control = GetNode<Control>("Control");
_quantityLabel.Visible = false;
}
}

View File

@ -53,6 +53,7 @@ public partial class MainMenuLoader : UiLoaderTemplate
public override void InitializeUI()
{
_startGameButton = GetNode<Button>("StartGameButton");
_startGameButton.GrabFocus();
_versionLabel = GetNode<Label>("VBoxContainer2/VersionLabel");
//Generative copyright
//生成版权