Add Japanese translation to improve item picking logic.

增加日语翻译,改善物品的拾捡逻辑。
This commit is contained in:
Cold-Mint 2024-05-09 21:07:14 +08:00
parent 222d26441e
commit 5cdb720d37
Signed by: Cold-Mint
GPG Key ID: C5A9BF8A98E0CE99
39 changed files with 249 additions and 176 deletions

View File

@ -1,7 +1,9 @@
id,zh,en
Object reference not set to an instance of an object.,尝试在空对象上调用虚拟方法。,Object reference not set to an instance of an object.
missing_parameters,缺少参数。,Missing parameters.
room_root_node_must_be_node2d,房间根节点必须是 Node2D。,Room root node must be Node2D.
width_or_height_of_room_slot_must_be_1,房间槽的宽度或高度必须为1。,The width or height of the room slot must be 1.
connected_room_timeout,连接房间超时。,Connecting the room timed out.
projectiles_is_empty,未设置抛射体。,The projectile is not set.
id,zh,en,jp
Object reference not set to an instance of an object.,尝试在空对象上调用虚拟方法。,Object reference not set to an instance of an object.,空のオブジェクト上で仮想メソッドを呼び出してみます。
missing_parameters,缺少参数。,Missing parameters.,パラメータが不足しています。
room_root_node_must_be_node2d,房间根节点必须是 Node2D。,Room root node must be Node2D.,ルートードはNode2Dでなければなりません。
width_or_height_of_room_slot_must_be_1,房间槽的宽度或高度必须为1。,The width or height of the room slot must be 1.,部屋の溝の幅または高さは1でなければなりません。
connected_room_timeout,连接房间超时。,Connecting the room timed out.,接続部屋はタイムアウトです。
projectiles_is_empty,未设置抛射体。,The projectile is not set.,射出体は設置されていません。
map_generator_is_not_set_up,未设置地图生成器。,Map generator is not set up.,マップ生成器は設置されていません。
map_generator_is_not_configured,地图生成器没有有效配置。,Map Generator is not configured.,地図生成器は機能していません。
1 id zh en jp
2 Object reference not set to an instance of an object. 尝试在空对象上调用虚拟方法。 Object reference not set to an instance of an object. 空のオブジェクト上で仮想メソッドを呼び出してみます。
3 missing_parameters 缺少参数。 Missing parameters. パラメータが不足しています。
4 room_root_node_must_be_node2d 房间根节点必须是 Node2D。 Room root node must be Node2D. ルートノードはNode2Dでなければなりません。
5 width_or_height_of_room_slot_must_be_1 房间槽的宽度或高度必须为1。 The width or height of the room slot must be 1. 部屋の溝の幅または高さは1でなければなりません。
6 connected_room_timeout 连接房间超时。 Connecting the room timed out. 接続部屋はタイムアウトです。
7 projectiles_is_empty 未设置抛射体。 The projectile is not set. 射出体は設置されていません。
8 map_generator_is_not_set_up 未设置地图生成器。 Map generator is not set up. マップ生成器は設置されていません。
9 map_generator_is_not_configured 地图生成器没有有效配置。 Map Generator is not configured. 地図生成器は機能していません。

View File

@ -6,10 +6,10 @@ uid="uid://nmtkvo0t7p7n"
[deps]
files=["res://locals/Error.zh.translation", "res://locals/Error.en.translation"]
files=["res://locals/Error.zh.translation", "res://locals/Error.en.translation", "res://locals/Error.jp.translation"]
source_file="res://locals/Error.csv"
dest_files=["res://locals/Error.zh.translation", "res://locals/Error.en.translation"]
dest_files=["res://locals/Error.zh.translation", "res://locals/Error.en.translation", "res://locals/Error.jp.translation"]
[params]

Binary file not shown.

BIN
locals/Error.jp.translation Normal file

Binary file not shown.

Binary file not shown.

View File

@ -1,2 +1,2 @@
id,zh,en
Left Mouse Button,鼠标左键,Left Mouse Button
id,zh,en,jp
Left Mouse Button,鼠标左键,Left Mouse Button,マウスの左ボタンです
1 id zh en jp
2 Left Mouse Button 鼠标左键 Left Mouse Button マウスの左ボタンです

View File

@ -6,10 +6,10 @@ uid="uid://dvvc7sup2d2ii"
[deps]
files=["res://locals/InputMapping.zh.translation", "res://locals/InputMapping.en.translation"]
files=["res://locals/InputMapping.zh.translation", "res://locals/InputMapping.en.translation", "res://locals/InputMapping.jp.translation"]
source_file="res://locals/InputMapping.csv"
dest_files=["res://locals/InputMapping.zh.translation", "res://locals/InputMapping.en.translation"]
dest_files=["res://locals/InputMapping.zh.translation", "res://locals/InputMapping.en.translation", "res://locals/InputMapping.jp.translation"]
[params]

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,11 +1 @@
id,zh,en
data_packet_missing_id,位于{0}的数据包缺少Id无法加载。,"Packet at {0}, missing Id, unable to load."
index_is_up_to_date,位于{0}的数据包索引已是最新。,"The packet index at {0} is up to date."
build_an_index,为{0}构建索引。,"Build an index for {0}."
add_file_index,添加文件索引{0}。,"Add file index {0}."
index_updated,{0}索引已更新。,"{0} Index has been updated."
no_manifest_file,位于{0}的数据包,没有清单文件,无法加载。,"Packet located in {0}, no manifest file, cannot be loaded."
duplicate_at_path_id,位于{0}路径{1}的Id({2})已被占用,无法加载。,"Id({2}) in {0} path {1} is occupied and cannot be loaded."
duplicate_at_path_id,位于{0}路径{1}的Id({2})已被占用,无法加载。,"Id({2}) in {0} path {1} is occupied and cannot be loaded."
map_generator_is_not_set_up,未设置地图生成器。,Map generator is not set up.
map_generator_is_not_configured,地图生成器没有有效配置。,Map Generator is not configured.
id,zh,en,jp
1 id zh en jp
data_packet_missing_id 位于{0}的数据包,缺少Id,无法加载。 Packet at {0}, missing Id, unable to load.
index_is_up_to_date 位于{0}的数据包索引已是最新。 The packet index at {0} is up to date.
build_an_index 为{0}构建索引。 Build an index for {0}.
add_file_index 添加文件索引{0}。 Add file index {0}.
index_updated {0}索引已更新。 {0} Index has been updated.
no_manifest_file 位于{0}的数据包,没有清单文件,无法加载。 Packet located in {0}, no manifest file, cannot be loaded.
duplicate_at_path_id 位于{0}路径{1}的Id({2})已被占用,无法加载。 Id({2}) in {0} path {1} is occupied and cannot be loaded.
duplicate_at_path_id 位于{0}路径{1}的Id({2})已被占用,无法加载。 Id({2}) in {0} path {1} is occupied and cannot be loaded.
map_generator_is_not_set_up 未设置地图生成器。 Map generator is not set up.
map_generator_is_not_configured 地图生成器没有有效配置。 Map Generator is not configured.

View File

@ -6,10 +6,10 @@ uid="uid://btmjafjh5r6bk"
[deps]
files=["res://locals/Log.zh.translation", "res://locals/Log.en.translation"]
files=["res://locals/Log.zh.translation", "res://locals/Log.en.translation", "res://locals/Log.jp.translation"]
source_file="res://locals/Log.csv"
dest_files=["res://locals/Log.zh.translation", "res://locals/Log.en.translation"]
dest_files=["res://locals/Log.zh.translation", "res://locals/Log.en.translation", "res://locals/Log.jp.translation"]
[params]

Binary file not shown.

BIN
locals/Log.jp.translation Normal file

Binary file not shown.

Binary file not shown.

View File

@ -1,15 +1,14 @@
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
jump,跳跃,Jump
throw,抛出,Throw a
must_be_thrown,必须先抛出{0}才能拾捡{1},{0} must be thrown before {1} can be picked up.
use_item,使用,Use
jump_down,跳下平台,Jump off platform
de,的,'s
default_player_name,白纸,blankPaper
item_prompt_debug,ID{0}\n名称{1}\n数量{2}\n最大叠加数量{3}\n数据类型{4}\n描述{5},ID: {0}\nName: {1}\nQuantity: {2}\nMaximum stacking quantity: {3}\nData type: {4}\nDescription{5}
id,zh,en,jp
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,右に移動します
jump,跳跃,Jump,飛
throw,抛出,Throw a ,ほうしゅつ
use_item,使用,Use,しよう
jump_down,跳下平台,Jump off platform,踊り場から飛び降ります
de,的,'s,の
default_player_name,白纸,blankPaper,しらかみ
item_prompt_debug,ID{0}\n名称{1}\n数量{2}\n最大叠加数量{3}\n数据类型{4}\n描述{5},ID: {0}\nName: {1}\nQuantity: {2}\nMaximum stacking quantity: {3}\nData type: {4}\nDescription{5},id:{0}\n名称:{1}\nの数は最大{2}\nシナジー数:{3}\nデータタイプ:{4}\n述べ表わす:{5}
1 id zh en jp
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 右に移動します
8 jump 跳跃 Jump
9 throw 抛出 Throw a ほうしゅつ
10 must_be_thrown use_item 必须先抛出{0}才能拾捡{1} 使用 {0} must be thrown before {1} can be picked up. Use しよう
11 use_item jump_down 使用 跳下平台 Use Jump off platform 踊り場から飛び降ります
12 jump_down de 跳下平台 Jump off platform 's
13 de default_player_name 白纸 's blankPaper しらかみ
14 default_player_name item_prompt_debug 白纸 ID:{0}\n名称:{1}\n数量:{2}\n最大叠加数量:{3}\n数据类型:{4}\n描述:{5} blankPaper ID: {0}\nName: {1}\nQuantity: {2}\nMaximum stacking quantity: {3}\nData type: {4}\nDescription:{5} id:{0}\n名称:{1}\nの数は最大{2}\nシナジー数:{3}\nデータタイプ:{4}\n述べ表わす:{5}
item_prompt_debug ID:{0}\n名称:{1}\n数量:{2}\n最大叠加数量:{3}\n数据类型:{4}\n描述:{5} ID: {0}\nName: {1}\nQuantity: {2}\nMaximum stacking quantity: {3}\nData type: {4}\nDescription:{5}

View File

@ -6,10 +6,10 @@ uid="uid://bpdkorm7lprma"
[deps]
files=["res://locals/UI.zh.translation", "res://locals/UI.en.translation"]
files=["res://locals/UI.zh.translation", "res://locals/UI.en.translation", "res://locals/UI.jp.translation"]
source_file="res://locals/UI.csv"
dest_files=["res://locals/UI.zh.translation", "res://locals/UI.en.translation"]
dest_files=["res://locals/UI.zh.translation", "res://locals/UI.en.translation", "res://locals/UI.jp.translation"]
[params]

Binary file not shown.

BIN
locals/UI.jp.translation Normal file

Binary file not shown.

Binary file not shown.

View File

@ -1,3 +1,3 @@
id,zh,en
staff_of_the_undead,死灵法杖,StaffOfTheUndead
staff_of_the_undead_desc,发射诅咒,可将敌人转化为邪恶的怪物。,Cast a curse that transforms enemies into evil monsters.
id,zh,en,jp
staff_of_the_undead,死灵法杖,StaffOfTheUndead,ネクロポリスの杖です
staff_of_the_undead_desc,发射诅咒,可将敌人转化为邪恶的怪物。,Cast a curse that transforms enemies into evil monsters.,呪いを発射して、敵を邪悪な怪物に変えることができます。
1 id zh en jp
2 staff_of_the_undead 死灵法杖 StaffOfTheUndead ネクロポリスの杖です
3 staff_of_the_undead_desc 发射诅咒,可将敌人转化为邪恶的怪物。 Cast a curse that transforms enemies into evil monsters. 呪いを発射して、敵を邪悪な怪物に変えることができます。

View File

@ -6,10 +6,10 @@ uid="uid://dmhmjvtquyu16"
[deps]
files=["res://locals/Weapon.zh.translation", "res://locals/Weapon.en.translation"]
files=["res://locals/Weapon.zh.translation", "res://locals/Weapon.en.translation", "res://locals/Weapon.jp.translation"]
source_file="res://locals/Weapon.csv"
dest_files=["res://locals/Weapon.zh.translation", "res://locals/Weapon.en.translation"]
dest_files=["res://locals/Weapon.zh.translation", "res://locals/Weapon.en.translation", "res://locals/Weapon.jp.translation"]
[params]

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,13 +1,6 @@
id,zh,en
slogan_1,如果是你,你会选择金钱还是荣誉?,"If it were you, would you choose money or honor?"
slogan_2,游戏属于每一个人。,The game belongs to everyone.
slogan_3,如果你想要得到爱,你就播种爱。,"If you want love, you sow love."
slogan_4,作为自然法则,死亡是每一个人人生的最终归宿。,"As a law of nature, everyone will end up dead."
slogan_5,光阴似箭。,tempus fugit.
slogan_6,快乐?伤心?痛苦?,Happy? Sad? Pain?
slogan_7,在图像和音乐中酝酿感情。,Brewing emotions in images and music.
slogan_8,罪与罚。,crime and punishment.
slogan_9,高桥李依!,Rie Takahashi!
slogan_10,0001 0011 0001 0101 0100 1111 0100,0001 0011 0001 0101 0100 1111 0100
slogan_11,恋愛偏差値上昇中!-P丸様。,恋愛偏差値上昇中!-P丸様。
slogan_12,kaWaYi!,kaWaYi!
id,zh,en,jp
slogan_1,游戏属于每一个人。,The game belongs to everyone.,ゲームはすべての人のものです。
slogan_2,如果你想要得到爱,你就播种爱。,"If you want love, you sow love.",愛を手に入れたければ、愛の種をまきます。
slogan_3,快乐?伤心?痛苦?,Happy? Sad? Pain?,楽しいですか?悲しいですか?苦しいですか?
slogan_4,0001 0011 0001 0101 0100 1111 0100,0001 0011 0001 0101 0100 1111 0100,0001 0011 0001 0101 0100 1111 0100
slogan_5,kaWaYi!,kaWaYi!,kaWaYi!
1 id zh en jp
2 slogan_1 如果是你,你会选择金钱还是荣誉? 游戏属于每一个人。 If it were you, would you choose money or honor? The game belongs to everyone. ゲームはすべての人のものです。
3 slogan_2 游戏属于每一个人。 如果你想要得到爱,你就播种爱。 The game belongs to everyone. If you want love, you sow love. 愛を手に入れたければ、愛の種をまきます。
4 slogan_3 如果你想要得到爱,你就播种爱。 快乐?伤心?痛苦? If you want love, you sow love. Happy? Sad? Pain? 楽しいですか?悲しいですか?苦しいですか?
5 slogan_4 作为自然法则,死亡是每一个人人生的最终归宿。 0001 0011 0001 0101 0100 1111 0100 As a law of nature, everyone will end up dead. 0001 0011 0001 0101 0100 1111 0100 0001 0011 0001 0101 0100 1111 0100
6 slogan_5 光阴似箭。 kaWaYi! tempus fugit. kaWaYi! kaWaYi!
slogan_6 快乐?伤心?痛苦? Happy? Sad? Pain?
slogan_7 在图像和音乐中酝酿感情。 Brewing emotions in images and music.
slogan_8 罪与罚。 crime and punishment.
slogan_9 高桥李依! Rie Takahashi!
slogan_10 0001 0011 0001 0101 0100 1111 0100 0001 0011 0001 0101 0100 1111 0100
slogan_11 恋愛偏差値上昇中!-P丸様。 恋愛偏差値上昇中!-P丸様。
slogan_12 kaWaYi! kaWaYi!

View File

@ -6,10 +6,10 @@ uid="uid://cjtdm8ddsrd7e"
[deps]
files=["res://locals/slogan.zh.translation", "res://locals/slogan.en.translation"]
files=["res://locals/slogan.zh.translation", "res://locals/slogan.en.translation", "res://locals/slogan.jp.translation"]
source_file="res://locals/slogan.csv"
dest_files=["res://locals/slogan.zh.translation", "res://locals/slogan.en.translation"]
dest_files=["res://locals/slogan.zh.translation", "res://locals/slogan.en.translation", "res://locals/slogan.jp.translation"]
[params]

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -146,7 +146,8 @@ hotbar_previous={
[internationalization]
locale/translations=PackedStringArray("res://locals/UI.en.translation", "res://locals/UI.zh.translation", "res://locals/Error.zh.translation", "res://locals/Error.en.translation", "res://locals/slogan.en.translation", "res://locals/slogan.zh.translation", "res://locals/Log.en.translation", "res://locals/Log.zh.translation", "res://locals/Weapon.en.translation", "res://locals/Weapon.zh.translation", "res://locals/InputMapping.en.translation", "res://locals/InputMapping.zh.translation")
locale/translations=PackedStringArray("res://locals/UI.en.translation", "res://locals/UI.zh.translation", "res://locals/Error.zh.translation", "res://locals/Error.en.translation", "res://locals/slogan.en.translation", "res://locals/slogan.zh.translation", "res://locals/Log.en.translation", "res://locals/Log.zh.translation", "res://locals/Weapon.en.translation", "res://locals/Weapon.zh.translation", "res://locals/InputMapping.en.translation", "res://locals/InputMapping.zh.translation", "res://locals/Error.jp.translation", "res://locals/InputMapping.jp.translation", "res://locals/Log.jp.translation", "res://locals/slogan.jp.translation", "res://locals/UI.jp.translation", "res://locals/Weapon.jp.translation")
locale/test="jp"
[layer_names]

View File

@ -22,13 +22,15 @@ grow_vertical = 2
[node name="VBoxContainer" type="VBoxContainer" parent="CanvasLayer/Control"]
layout_mode = 1
anchors_preset = 2
anchors_preset = 12
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = 10.0
offset_top = -95.0
offset_right = 178.0
offset_bottom = -10.0
offset_left = 20.0
offset_top = -85.0
offset_right = -20.0
offset_bottom = -20.0
grow_horizontal = 2
grow_vertical = 0
[node name="HealthBarUi" type="HBoxContainer" parent="CanvasLayer/Control/VBoxContainer"]
@ -47,9 +49,11 @@ script = ExtResource("2_owrhq")
layout_mode = 2
texture = ExtResource("2_n1yht")
[node name="OperationTip" type="Label" parent="CanvasLayer/Control/VBoxContainer"]
[node name="OperationTip" type="RichTextLabel" parent="CanvasLayer/Control/VBoxContainer"]
layout_mode = 2
text = "32323"
bbcode_enabled = true
text = "OperationTip"
fit_content = true
[node name="ProjectileContainer" type="Node2D" parent="."]

View File

@ -80,6 +80,13 @@ public static class Config
/// </summary>
public const int MaxStackQuantity = 99;
/// <summary>
/// <para>Operation prompts, function key text color</para>
/// <para>操作提示内,功能键文本颜色</para>
/// </summary>
public const string OperationTipActionColor = "#2b8a3e";
/// <summary>
/// <para>Company/Creator name</para>
/// <para>公司/创作者名字</para>

View File

@ -26,5 +26,5 @@ public static class GameSceneNodeHolder
public static HealthBarUi? HealthBarUi { get; set; }
public static Label? OperationTipLabel { get; set; }
public static RichTextLabel? OperationTipLabel { get; set; }
}

View File

@ -12,7 +12,7 @@ public static class SloganProvider
/// <para>Define how many banners you want to display</para>
/// <para>定义共有多少条标语需要展示</para>
/// </summary>
private const int Total = 12;
private const int Total = 5;
/// <summary>
/// <para>Swipe the machine to get a slogan</para>

View File

@ -4,6 +4,7 @@ using ColdMint.scripts.camp;
using ColdMint.scripts.damage;
using ColdMint.scripts.health;
using ColdMint.scripts.inventory;
using ColdMint.scripts.utils;
using ColdMint.scripts.weapon;
using Godot;
@ -43,7 +44,29 @@ public partial class CharacterTemplate : CharacterBody2D
//Items currently held
//当前持有的物品
public Node2D? CurrentItem;
private Node2D? _currentItem;
public Node2D? CurrentItem
{
get => _currentItem;
set
{
_currentItem = value;
WhenUpdateCurrentItem(_currentItem);
}
}
/// <summary>
/// <para>When the items the character holds are updated</para>
/// <para>当角色持有的物品更新时</para>
/// </summary>
/// <param name="currentItem">
///<para>Update finished items</para>
///<para>更新完成后的物品</para>
/// </param>
protected virtual void WhenUpdateCurrentItem(Node2D? currentItem)
{
}
//Define a pick up range
//定义一个拾起范围
@ -92,9 +115,32 @@ public partial class CharacterTemplate : CharacterBody2D
/// <para>Pick up all items within range</para>
/// <para>拾捡范围内的所有物品</para>
/// </summary>
private List<Node>? _pickingRangeBodies;
protected List<Node>? PickingRangeBodiesList;
public Node[] PickingRangeBodies => _pickingRangeBodies?.ToArray() ?? Array.Empty<Node>();
public Node[] PickingRangeBodies => PickingRangeBodiesList?.ToArray() ?? Array.Empty<Node>();
/// <summary>
/// <para>Find the nearest item within the pick up area(Does not include items currently held)</para>
/// <para>在拾捡范围内查找距离最近的物品(不包括当前持有的物品)</para>
/// </summary>
/// <returns></returns>
public Node2D? FindTheNearestItem()
{
if (PickingRangeBodiesList == null || PickingRangeBodiesList.Count == 0)
{
return null;
}
HashSet<Node>? exclude = null;
if (_currentItem != null)
{
//Prevent picking up objects in your hands again.
//防止再次捡起自己手上的物品。
exclude = new HashSet<Node> { _currentItem };
}
return NodeUtils.GetTheNearestNode(this, PickingRangeBodiesList.ToArray(), exclude);
}
/// <summary>
@ -122,7 +168,7 @@ public partial class CharacterTemplate : CharacterBody2D
public override void _Ready()
{
base._Ready();
_pickingRangeBodies = new List<Node>();
PickingRangeBodiesList = new List<Node>();
CharacterName = GetMeta("Name", Name).AsString();
CampId = GetMeta("CampId", Config.CampId.Default).AsString();
MaxHp = GetMeta("MaxHp", Config.DefaultMaxHp).AsInt32();
@ -232,7 +278,7 @@ public partial class CharacterTemplate : CharacterBody2D
weaponTemplate.Sleeping = true;
}
if (itemSlotNode.GetItem() != null && itemSlotNode.GetItem() == item && CurrentItem == null)
if (itemSlotNode.GetItem() != null && itemSlotNode.GetItem() == item && _currentItem == null)
{
//If the selected item slot in the item container is a newly picked item, and there is no item in the hand, then we put the selected item into the hand.
//如果物品容器内选中的物品槽是刚刚捡到的物品,且手里没有物品持有,那么我们将选中的物品放到手上。
@ -256,12 +302,12 @@ public partial class CharacterTemplate : CharacterBody2D
/// </summary>
public bool UseItem(Vector2 position)
{
if (CurrentItem == null)
if (_currentItem == null)
{
return false;
}
if (CurrentItem is WeaponTemplate weaponTemplate)
if (_currentItem is WeaponTemplate weaponTemplate)
{
weaponTemplate.Fire(this, position);
}
@ -397,7 +443,12 @@ public partial class CharacterTemplate : CharacterBody2D
/// <param name="node"></param>
protected virtual void EnterThePickingRangeBody(Node node)
{
_pickingRangeBodies?.Add(node);
if (node is not IItem)
{
return;
}
PickingRangeBodiesList?.Add(node);
}
/// <summary>
@ -407,7 +458,12 @@ public partial class CharacterTemplate : CharacterBody2D
/// <param name="node"></param>
protected virtual void ExitThePickingRangeBody(Node node)
{
_pickingRangeBodies?.Remove(node);
if (node is not IItem)
{
return;
}
PickingRangeBodiesList?.Remove(node);
}
/// <summary>
@ -429,9 +485,9 @@ public partial class CharacterTemplate : CharacterBody2D
{
//We continuously set the position of the items to prevent them from changing as we zoom in and out of the window.
//我们持续设置物品的位置,为了防止放大缩小窗口时物品位置的变化。
if (CurrentItem != null)
if (_currentItem != null)
{
CurrentItem.Position = Vector2.Zero;
_currentItem.Position = Vector2.Zero;
}
var velocity = Velocity;
@ -453,7 +509,7 @@ public partial class CharacterTemplate : CharacterBody2D
/// </summary>
public void AimTheCurrentItemAtAPoint(Vector2 position)
{
if (CurrentItem == null)
if (_currentItem == null)
{
//Do not currently hold any items.
//当前没有持有任何物品。
@ -462,7 +518,7 @@ public partial class CharacterTemplate : CharacterBody2D
// Apply the rotation Angle to the node
// 将旋转角度应用于节点
CurrentItem.LookAt(position);
_currentItem.LookAt(position);
}

View File

@ -26,13 +26,9 @@ public partial class Player : CharacterTemplate
//用于检测玩家是否站在平台上的射线
private RayCast2D? _platformDetectionRayCast2D;
//在拾捡范围内,可拾起的物品数量
private int _totalNumberOfPickups;
private const float PromptTextDistance = 50;
//玩家可拾捡的物品
private Node2D? _pickAbleItem;
//抛出物品的飞行速度
private float _throwingVelocity = Config.CellSize * 13;
@ -77,99 +73,73 @@ public partial class Player : CharacterTemplate
}
var operationTipBuilder = new StringBuilder();
if (_totalNumberOfPickups > 0)
{
//If there's anything around to pick up
//如果周围有能捡的东西
if (CurrentItem == null)
{
if (_pickAbleItem != null)
{
string? name = null;
if (_pickAbleItem is WeaponTemplate weaponTemplate)
{
//When the weapon has no owner, a pick up prompt is displayed.
//当武器没有主人时,显示捡起提示。
if (weaponTemplate.Owner == null || weaponTemplate.Owner == this)
{
name = TranslationServer.Translate(weaponTemplate.Name);
}
}
if (name != null)
{
operationTipBuilder.Append(
TranslationServer.Translate(InputMap.ActionGetEvents("pick_up")[0].AsText()));
operationTipBuilder.Append(TranslationServer.Translate("pick_up"));
operationTipBuilder.Append(name);
}
}
}
else
{
string? pickAbleItemName = null;
string? currentItemName = null;
string mustBeThrown = TranslationServer.Translate("must_be_thrown");
if (_pickAbleItem != null)
{
//可捡的物品是武器
if (_pickAbleItem is WeaponTemplate weaponTemplate)
{
pickAbleItemName = TranslationServer.Translate(weaponTemplate.Name);
}
}
if (CurrentItem != null)
{
//当前持有的物品是武器
if (CurrentItem is WeaponTemplate weaponTemplate)
{
currentItemName = TranslationServer.Translate(weaponTemplate.Name);
}
}
if (pickAbleItemName != null && currentItemName != null && mustBeThrown != "must_be_thrown")
{
operationTipBuilder.Append(string.Format(mustBeThrown, currentItemName, pickAbleItemName));
operationTipBuilder.Append(' ');
operationTipBuilder.Append(
TranslationServer.Translate(InputMap.ActionGetEvents("throw")[0].AsText()));
operationTipBuilder.Append(TranslationServer.Translate("throw"));
operationTipBuilder.Append(currentItemName);
}
}
operationTipLabel.Text = operationTipBuilder.ToString();
return;
}
operationTipBuilder.Append("[color=");
operationTipBuilder.Append(Config.OperationTipActionColor);
operationTipBuilder.Append(']');
operationTipBuilder.Append(TranslationServer.Translate(InputMap.ActionGetEvents("ui_left")[0].AsText()));
operationTipBuilder.Append("[/color]");
operationTipBuilder.Append(TranslationServer.Translate("move_left"));
operationTipBuilder.Append(' ');
operationTipBuilder.Append("[color=");
operationTipBuilder.Append(Config.OperationTipActionColor);
operationTipBuilder.Append(']');
operationTipBuilder.Append(TranslationServer.Translate(InputMap.ActionGetEvents("ui_right")[0].AsText()));
operationTipBuilder.Append("[/color]");
operationTipBuilder.Append(TranslationServer.Translate("move_right"));
operationTipBuilder.Append(' ');
operationTipBuilder.Append("[color=");
operationTipBuilder.Append(Config.OperationTipActionColor);
operationTipBuilder.Append(']');
operationTipBuilder.Append(TranslationServer.Translate(InputMap.ActionGetEvents("ui_up")[0].AsText()));
operationTipBuilder.Append("[/color]");
operationTipBuilder.Append(TranslationServer.Translate("jump"));
if (_collidingWithPlatform)
{
operationTipBuilder.Append(' ');
operationTipBuilder.Append("[color=");
operationTipBuilder.Append(Config.OperationTipActionColor);
operationTipBuilder.Append(']');
operationTipBuilder.Append(TranslationServer.Translate(InputMap.ActionGetEvents("ui_down")[0].AsText()));
operationTipBuilder.Append("[/color]");
operationTipBuilder.Append(TranslationServer.Translate("jump_down"));
}
//If the PickingRangeBodiesList is not null and the length is greater than 0
//如果PickingRangeBodiesList不是null且长度大于0
if (PickingRangeBodiesList is { Count: > 0 })
{
operationTipBuilder.Append(' ');
operationTipBuilder.Append("[color=");
operationTipBuilder.Append(Config.OperationTipActionColor);
operationTipBuilder.Append(']');
operationTipBuilder.Append(
TranslationServer.Translate(InputMap.ActionGetEvents("pick_up")[0].AsText()));
operationTipBuilder.Append("[/color]");
operationTipBuilder.Append(TranslationServer.Translate("pick_up"));
operationTipLabel.Text = operationTipBuilder.ToString();
}
if (CurrentItem != null)
{
operationTipBuilder.Append(' ');
operationTipBuilder.Append("[color=");
operationTipBuilder.Append(Config.OperationTipActionColor);
operationTipBuilder.Append(']');
operationTipBuilder.Append(TranslationServer.Translate(InputMap.ActionGetEvents("throw")[0].AsText()));
operationTipBuilder.Append("[/color]");
operationTipBuilder.Append(TranslationServer.Translate("throw"));
if (CurrentItem is WeaponTemplate weaponTemplate)
{
operationTipBuilder.Append(TranslationServer.Translate(weaponTemplate.Name));
//提示武器攻击
operationTipBuilder.Append(' ');
operationTipBuilder.Append("[color=");
operationTipBuilder.Append(Config.OperationTipActionColor);
operationTipBuilder.Append(']');
operationTipBuilder.Append(
TranslationServer.Translate(InputMap.ActionGetEvents("use_item")[0].AsText()));
operationTipBuilder.Append("[/color]");
operationTipBuilder.Append(TranslationServer.Translate("use_item"));
operationTipBuilder.Append(TranslationServer.Translate(weaponTemplate.Name));
}
@ -212,18 +182,20 @@ public partial class Player : CharacterTemplate
//捡起物品
if (Input.IsActionJustPressed("pick_up"))
{
var success = PickItem(_pickAbleItem);
var pickAbleItem = FindTheNearestItem();
var success = PickItem(pickAbleItem);
if (success)
{
_pickAbleItem = null;
_totalNumberOfPickups--;
if (pickAbleItem != null)
{
PickingRangeBodiesList?.Remove(pickAbleItem);
}
if (_floatLabel != null)
{
_floatLabel.QueueFree();
_floatLabel = null;
}
UpdateOperationTip();
}
}
@ -278,6 +250,7 @@ public partial class Player : CharacterTemplate
{
return;
}
if (_parabola != null)
{
_parabola.Points = new[] { Vector2.Zero };
@ -319,16 +292,16 @@ public partial class Player : CharacterTemplate
rigidBody2D.LinearVelocity = GetThrowVelocity();
break;
}
CurrentItem = null;
_totalNumberOfPickups++;
var hotBar = GameSceneNodeHolder.HotBar;
hotBar?.RemoveItemFromItemSlotBySelectIndex(1);
UpdateOperationTip();
}
}
protected override void WhenUpdateCurrentItem(Node2D? currentItem)
{
UpdateOperationTip();
}
private Vector2 GetThrowVelocity()
{
@ -392,6 +365,7 @@ public partial class Player : CharacterTemplate
protected override void EnterThePickingRangeBody(Node node)
{
base.EnterThePickingRangeBody(node);
if (CurrentItem == node)
{
//If the node entering the pick range is the node held by the player, then return.
@ -404,8 +378,6 @@ public partial class Player : CharacterTemplate
return;
}
_totalNumberOfPickups++;
_pickAbleItem = node2D;
if (_floatLabelPackedScene != null)
{
//If there is a scene of floating text, then we generate floating text.
@ -440,19 +412,12 @@ public partial class Player : CharacterTemplate
protected override void ExitThePickingRangeBody(Node node)
{
base.ExitThePickingRangeBody(node);
if (node is not Node2D)
{
return;
}
_totalNumberOfPickups--;
if (_totalNumberOfPickups == 0)
{
//Set to null if there are no more items to pick up
//如果没有可捡的物品了设置为null
_pickAbleItem = null;
}
if (_floatLabel != null)
{
_floatLabel.QueueFree();

View File

@ -27,7 +27,7 @@ public partial class GameSceneLoader : SceneLoaderTemplate
var hotBar = GetNode<HotBar>("CanvasLayer/Control/VBoxContainer/HotBar");
GameSceneNodeHolder.HotBar = hotBar;
//加载操作提示
var operationTip = GetNode<Label>("CanvasLayer/Control/VBoxContainer/OperationTip");
var operationTip = GetNode<RichTextLabel>("CanvasLayer/Control/VBoxContainer/OperationTip");
GameSceneNodeHolder.OperationTipLabel = operationTip;
//加载武器容器
var weaponContainer = GetNode<Node2D>("WeaponContainer");

View File

@ -1,4 +1,5 @@
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Threading.Tasks;
using Godot;
namespace ColdMint.scripts.utils;
@ -36,4 +37,59 @@ public class NodeUtils
{
return await Task.Run(() => DeleteAllChild(parent));
}
/// <summary>
/// <para>Gets the node closest to the origin</para>
/// <para>获取距离原点最近的节点</para>
/// </summary>
/// <param name="origin">
///<para>origin</para>
///<para>原点</para>
/// </param>
/// <param name="array">
///<para>Node array</para>
///<para>节点数组</para>
/// </param>
/// <param name="exclude">
///<para>Which nodes are excluded</para>
///<para>排除哪些节点</para>
/// </param>
/// <param name="excludeInvisibleNodes">
///<para>Whether or not unseen nodes should be excluded</para>
///<para>是否排除不可见的节点</para>
/// </param>
/// <returns></returns>
public static Node2D? GetTheNearestNode(Node2D origin, Node[] array, HashSet<Node>? exclude = null,
bool excludeInvisibleNodes = true)
{
var closestDistance = float.MaxValue;
Node2D? closestNode = null;
foreach (var node in array)
{
if (node is not Node2D node2D) continue;
if (excludeInvisibleNodes && !node2D.Visible)
{
//If invisible nodes are excluded and the current node is invisible, then the next.
//如果排除不可见的节点,且当前节点就是不可见的,那么下一个。
continue;
}
if (exclude != null && exclude.Contains(node))
{
//If the current node, is within our exclusion project. So the next one.
//如果当前节点,在我们的排除项目内。那么下一个。
continue;
}
var distance = node2D.GlobalPosition - origin.GlobalPosition;
var distanceLength = distance.Length();
if (distanceLength < closestDistance)
{
closestDistance = distanceLength;
closestNode = node2D;
}
}
return closestNode;
}
}