From 39ca716e3dd7d431c5f025c7ca2a6afaf105eed8 Mon Sep 17 00:00:00 2001 From: Cold-Mint Date: Wed, 5 Jun 2024 21:38:45 +0800 Subject: [PATCH] =?UTF-8?q?Conduct=20code=20reviews.=20=E8=BF=9B=E8=A1=8C?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E5=AE=A1=E6=9F=A5=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- prefab/projectile/curseOfTheUndead.tscn | 2 +- scripts/Config.cs | 58 ++- scripts/EventManager.cs | 6 +- scripts/FpsLabel.cs | 4 +- scripts/GameSceneNodeHolder.cs | 19 +- scripts/HealthBarUi.cs | 14 +- scripts/SloganProvider.cs | 3 +- scripts/camp/Camp.cs | 2 +- scripts/character/CharacterTemplate.cs | 10 +- scripts/damage/DamageNumberNodeSpawn.cs | 49 ++- scripts/loader/sceneLoader/GameSceneLoader.cs | 2 +- scripts/map/AiCharacterSpawn.cs | 4 +- scripts/map/MapGenerator.cs | 7 +- scripts/map/RoomAreaDetector.cs | 15 - scripts/projectile/ProjectileTemplate.cs | 399 +++++++++--------- scripts/serialization/JsonSerialization.cs | 14 +- scripts/utils/CoordinateUtils.cs | 6 +- scripts/utils/ExplorerUtils.cs | 23 +- scripts/utils/GuidUtils.cs | 6 +- scripts/utils/HashCodeUtils.cs | 8 +- scripts/utils/Md5Utils.cs | 20 +- scripts/utils/NodeUtils.cs | 13 +- scripts/utils/ParabolicUtils.cs | 4 +- scripts/utils/StrUtils.cs | 6 +- scripts/utils/TileMapUtils.cs | 4 + scripts/utils/TimeUtils.cs | 4 + scripts/utils/TranslationServerUtils.cs | 4 + scripts/weapon/ProjectileWeapon.cs | 38 +- scripts/weapon/WeaponTemplate.cs | 15 +- 29 files changed, 422 insertions(+), 337 deletions(-) delete mode 100644 scripts/map/RoomAreaDetector.cs diff --git a/prefab/projectile/curseOfTheUndead.tscn b/prefab/projectile/curseOfTheUndead.tscn index 86ba92a..ba4ffa5 100644 --- a/prefab/projectile/curseOfTheUndead.tscn +++ b/prefab/projectile/curseOfTheUndead.tscn @@ -13,10 +13,10 @@ collision_layer = 0 collision_mask = 0 script = ExtResource("1_ib3qh") metadata/Speed = 500.0 -metadata/Life = 10.0 metadata/Durability = 1.0 metadata/DamageType = 2 metadata/Knockback = Vector2(2, -3) +metadata/Life = 5000 [node name="CurseOfTheUndead" type="Sprite2D" parent="."] texture = ExtResource("1_k8el6") diff --git a/scripts/Config.cs b/scripts/Config.cs index 228e419..8244ef3 100644 --- a/scripts/Config.cs +++ b/scripts/Config.cs @@ -8,7 +8,11 @@ namespace ColdMint.scripts; public static class Config { - public class BehaviorTreeId + /// + /// ID of the behavior tree + /// 行为树的ID + /// + public static class BehaviorTreeId { /// /// 巡逻 @@ -21,7 +25,7 @@ public static class Config /// BehaviorTreeResult /// 行为树的结果 /// - public class BehaviorTreeResult + public static class BehaviorTreeResult { /// /// Running @@ -149,20 +153,25 @@ public static class Config return OS.HasFeature("editor"); } - public class RoomInjectionProcessorId + /// + /// Room Injector ID + /// 房间注入器ID + /// + public static class RoomInjectionProcessorId { /// /// Chance /// 概率的 /// public const string Chance = "Chance"; + /// /// TimeInterval /// 时间范围的 /// public const string TimeInterval = "TimeInterval"; } - + public enum OsEnum { //unknown @@ -191,11 +200,7 @@ public static class Config //The host operating system is a web browser //宿主操作系统是网页浏览器 - Web, - - //Editor - //编辑器 - // Editor + Web } /// @@ -205,11 +210,6 @@ public static class Config /// public static OsEnum GetOs() { - // if (OS.HasFeature("editor")) - // { - // return OsEnum.Editor; - // } - if (OS.HasFeature("windows")) { return OsEnum.Windows; @@ -239,9 +239,15 @@ public static class Config { return OsEnum.Ios; } + return OsEnum.Unknown; } + /// + /// Get the game version + /// 获取游戏版本 + /// + /// public static string GetVersion() { var stringBuilder = new StringBuilder(); @@ -347,7 +353,7 @@ public static class Config /// Physical collision layer number /// 物理碰撞层 序号 /// - public class LayerNumber + public static class LayerNumber { public const int RoomArea = 1; public const int Ground = 2; @@ -357,24 +363,8 @@ public static class Config public const int Platform = 6; public const int Mob = 7; } - - /// - /// The event of entering the room - /// 进入房间的事件 - /// - public class EnterRoomEventId - { - } - - /// - /// Exit the room event - /// 退出房间的事件 - /// - public class ExitRoomEventId - { - } - - public class RoomDataTag + + public static class RoomDataTag { /// /// Mark the starting room @@ -387,7 +377,7 @@ public static class Config /// Specify the type of damage used in the game /// 指定游戏内使用的伤害类型 /// - public class DamageType + public static class DamageType { /// /// physical injury diff --git a/scripts/EventManager.cs b/scripts/EventManager.cs index e22d7af..6f68d25 100644 --- a/scripts/EventManager.cs +++ b/scripts/EventManager.cs @@ -3,7 +3,11 @@ using ColdMint.scripts.map.events; namespace ColdMint.scripts; -public class EventManager +/// +/// EventManager +/// 事件管理器 +/// +public static class EventManager { /// /// Event when the AI character is generated diff --git a/scripts/FpsLabel.cs b/scripts/FpsLabel.cs index 415aed1..cd018bb 100644 --- a/scripts/FpsLabel.cs +++ b/scripts/FpsLabel.cs @@ -8,12 +8,14 @@ namespace ColdMint.scripts; /// public partial class FpsLabel : Label { - bool _enable; + private bool _enable; private LabelSettings? _labelSettings; public override void _Ready() { Text = null; + //Enabled only in debug mode. + //仅在调试模式启用。 if (Config.IsDebug()) { _labelSettings = new LabelSettings(); diff --git a/scripts/GameSceneNodeHolder.cs b/scripts/GameSceneNodeHolder.cs index ea387a7..762cf8a 100644 --- a/scripts/GameSceneNodeHolder.cs +++ b/scripts/GameSceneNodeHolder.cs @@ -22,17 +22,34 @@ public static class GameSceneNodeHolder /// public static Node2D? WeaponContainer { get; set; } + /// + /// PlayerContainer + /// 玩家容器 + /// public static Node2D? PlayerContainer { get; set; } /// /// AICharacterContainer /// AICharacter角色 /// - public static Node2D? AICharacterContainer { get; set; } + public static Node2D? AiCharacterContainer { get; set; } + /// + /// HotBar + /// 快捷栏 + /// public static HotBar? HotBar { get; set; } + /// + /// Health Bar UI + /// 健康条UI + /// public static HealthBarUi? HealthBarUi { get; set; } + + /// + /// operation tip + /// 操作提示 + /// public static RichTextLabel? OperationTipLabel { get; set; } } \ No newline at end of file diff --git a/scripts/HealthBarUi.cs b/scripts/HealthBarUi.cs index 3eb3ea8..a664ca1 100644 --- a/scripts/HealthBarUi.cs +++ b/scripts/HealthBarUi.cs @@ -3,10 +3,19 @@ using Godot; namespace ColdMint.scripts; +/// +/// HealthBarUi +/// 健康条UI +/// public partial class HealthBarUi : HBoxContainer { private int _maxHp; private int _currentHp; + private Texture2D? _heartFull; + private Texture2D? _heartEmpty; + private Texture2D? _heartHalf; + private Texture2D? _heartQuarter; + private Texture2D? _heartThreeFourths; public int CurrentHp { @@ -139,11 +148,6 @@ public partial class HealthBarUi : HBoxContainer } } - private Texture2D? _heartFull; - private Texture2D? _heartEmpty; - private Texture2D? _heartHalf; - private Texture2D? _heartQuarter; - private Texture2D? _heartThreeFourths; public override void _Ready() { diff --git a/scripts/SloganProvider.cs b/scripts/SloganProvider.cs index 10f46ca..81359fc 100644 --- a/scripts/SloganProvider.cs +++ b/scripts/SloganProvider.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; -using ColdMint.scripts.utils; +using ColdMint.scripts.utils; using Godot; namespace ColdMint.scripts; diff --git a/scripts/camp/Camp.cs b/scripts/camp/Camp.cs index eb47ae6..5e21b74 100644 --- a/scripts/camp/Camp.cs +++ b/scripts/camp/Camp.cs @@ -8,7 +8,7 @@ namespace ColdMint.scripts.camp; /// public class Camp { - private string _id; + private readonly string _id; private readonly List _friendlyCampIdList; public Camp(string id) diff --git a/scripts/character/CharacterTemplate.cs b/scripts/character/CharacterTemplate.cs index 5fc984f..088413b 100644 --- a/scripts/character/CharacterTemplate.cs +++ b/scripts/character/CharacterTemplate.cs @@ -146,7 +146,9 @@ public partial class CharacterTemplate : CharacterBody2D return; } - CurrentHp = newHp; + //Check whether the new Hp is greater than the maximum Hp. If yes, set the current Hp to the maximum Hp. If no, set the current Hp to the new HP + //判断新的Hp是否大于最大Hp,若大于那么将当前Hp设置为最大Hp,否则设置为新的Hp + CurrentHp = newHp > MaxHp ? MaxHp : newHp; Visible = true; } @@ -352,10 +354,10 @@ public partial class CharacterTemplate : CharacterBody2D //If the time difference between the last injury and the current time is greater than the time displayed in the health bar, the health bar is hidden //如果上次受到伤害的时间与当前时间的时间差大于健康条显示时间,则隐藏健康条 - var timeSpan = DateTime.Now - _lastDamageTime; - if (timeSpan > Config.HealthBarDisplaysTime) + if (_healthBar is { Visible: true }) { - if (_healthBar != null) + var timeSpan = DateTime.Now - _lastDamageTime; + if (timeSpan > Config.HealthBarDisplaysTime) { _healthBar.Visible = false; } diff --git a/scripts/damage/DamageNumberNodeSpawn.cs b/scripts/damage/DamageNumberNodeSpawn.cs index e8a2ae3..3482ce9 100644 --- a/scripts/damage/DamageNumberNodeSpawn.cs +++ b/scripts/damage/DamageNumberNodeSpawn.cs @@ -12,22 +12,16 @@ public partial class DamageNumberNodeSpawn : Marker2D private Node2D? _rootNode; /// - /// The horizontal velocity is in the X positive direction - /// 水平速度的X正方向 + /// The vector in the negative direction + /// 负方向的向量 /// - private int _horizontalVelocityPositiveDirection; + private Vector2 _negativeVector; /// - /// Horizontal velocity in the negative X direction - /// 水平速度的X负方向 + /// Vector in the positive direction + /// 正方向的向量 /// - private int _horizontalVelocityNegativeDirection; - - /// - /// vertical height - /// 垂直高度 - /// - private int _verticalHeight; + private Vector2 _positiveVector; /// /// 物理渐变色 @@ -53,18 +47,31 @@ public partial class DamageNumberNodeSpawn : Marker2D base._Ready(); _damageNumberPackedScene = GD.Load("res://prefab/ui/DamageNumber.tscn") as PackedScene; _rootNode = GetNode("/root/Game/DamageNumberContainer"); - _horizontalVelocityPositiveDirection = Config.CellSize * Config.HorizontalSpeedOfDamageNumbers; - _horizontalVelocityNegativeDirection = -_horizontalVelocityPositiveDirection; - _verticalHeight = -Config.CellSize * Config.VerticalVelocityOfDamageNumbers; + //The horizontal velocity is in the X positive direction + //水平速度的X正方向 + var horizontalVelocityPositiveDirection = Config.CellSize * Config.HorizontalSpeedOfDamageNumbers; + //Horizontal velocity in the negative X direction + //水平速度的X负方向 + var horizontalVelocityNegativeDirection = -horizontalVelocityPositiveDirection; + //vertical height + //垂直高度 + var verticalHeight = -Config.CellSize * Config.VerticalVelocityOfDamageNumbers; + //Compute left and right vectors + //计算左右向量 + _negativeVector = new Vector2(horizontalVelocityNegativeDirection, verticalHeight); + _positiveVector = new Vector2(horizontalVelocityPositiveDirection, verticalHeight); _physicalGradient = new Gradient(); + //Physical color from OpenColor2 to OpenColor6 (red) //物理色 从OpenColor2 到 OpenColor6(红色) _physicalGradient.SetColor(0, new Color("#ffc9c9")); _physicalGradient.SetColor(1, new Color("#fa5252")); _magicGradient = new Gradient(); + //Magic Color from OpenColor2 to OpenColor6(Purple) //魔法色 从OpenColor2 到 OpenColor6(紫色) _magicGradient.SetColor(0, new Color("#d0bfff")); _magicGradient.SetColor(1, new Color("#7950f2")); _defaultGradient = new Gradient(); + //default behavior //默认行为 _defaultGradient.SetColor(0, new Color("#ff8787")); _defaultGradient.SetColor(1, new Color("#fa5252")); @@ -87,7 +94,7 @@ public partial class DamageNumberNodeSpawn : Marker2D /// public void Display(DamageTemplate damageTemplate) { - if (_damageNumberPackedScene == null) + if (_rootNode == null || _damageNumberPackedScene == null) { return; } @@ -98,18 +105,22 @@ public partial class DamageNumberNodeSpawn : Marker2D } CallDeferred("AddDamageNumberNode", damageNumber); - damageNumber.Position = GlobalPosition; if (damageTemplate.MoveLeft) { - damageNumber.SetVelocity(new Vector2(_horizontalVelocityNegativeDirection, _verticalHeight)); + damageNumber.SetVelocity(_negativeVector); } else { - damageNumber.SetVelocity(new Vector2(_horizontalVelocityPositiveDirection, _verticalHeight)); + damageNumber.SetVelocity(_positiveVector); } var damageLabel = damageNumber.GetNode public partial class ProjectileTemplate : CharacterBody2D { - protected Timer? Timer; + protected long Life; - protected double Life; + //The durability of the projectile + //抛射体的耐久度 + //When the projectile hits the object, the durability will be reduced, and when the durability is less than or equal to 0, the projectile will be destroyed + //当抛射体撞击到物体时,会减少耐久度,当耐久度小于等于0时,销毁抛射体 + protected double Durability; - //The durability of the projectile - //抛射体的耐久度 - //When the projectile hits the object, the durability will be reduced, and when the durability is less than or equal to 0, the projectile will be destroyed - //当抛射体撞击到物体时,会减少耐久度,当耐久度小于等于0时,销毁抛射体 - protected double Durability; + protected int MaxDamage; + protected int MinDamage; + protected int DamageType; - protected int MaxDamage; - protected int MinDamage; - protected int DamageType; - - //We use the Time node to specify when to destroy the projectile - //我们用Time节点来指定何时销毁抛射体 - private Timer? _timer; - - /// - /// The impact area of the bullet - /// 子弹的碰撞区域 - /// - protected Area2D? Area2D; - - /// - /// knockback - /// 击退 - /// - /// - ///How much force does it have when hitting the character? Unit: Number of cells,The X direction of the force is inferred automatically. - ///当击中角色时带有多大的力?单位:格数,力的X方向是自动推断的。 - /// - protected Vector2 KnockbackForce; - - public float Speed - { - get => GetMeta("Speed", "15").AsSingle(); - } - - /// - /// The master of the weapon - /// 武器的主人 - /// - public new Node2D? Owner { get; set; } - - public override void _Ready() - { - //子弹的碰撞检测区域 - Area2D = GetNode("CollisionDetectionArea"); - Area2D.Monitoring = true; - Area2D.BodyEntered += OnBodyEnter; - Area2D.BodyExited += OnBodyExited; - Durability = GetMeta("Durability", "1").AsDouble(); - MaxDamage = GetMeta("MaxDamage", "7").AsInt32(); - MinDamage = GetMeta("MinDamage", "5").AsInt32(); - DamageType = GetMeta("DamageType", Config.DamageType.Physical).AsInt32(); - KnockbackForce = GetMeta("Knockback", Vector2.Zero).AsVector2(); - //子弹的存在时间 - Life = GetMeta("Life", "10").AsDouble(); - //如果存在时间小于等于0,那么设置为存在10秒,禁止无限期存在的抛射体 - if (Life <= 0) - { - Life = 10; - } - - Timer = new Timer(); - AddChild(Timer); - Timer.WaitTime = Life; - Timer.OneShot = true; - Timer.Start(); - Timer.Timeout += OnTimeOut; - } + /// + /// After this time destroy the projectile + /// 超过此时刻销毁抛射体 + /// + private DateTime? _destructionTime; - /// - /// Detect whether harm is allowed - /// 检测是否允许造成伤害 - /// - /// - /// - /// - private bool CanCauseHarm(Node2D? owner, Node2D target) - { - //We must know who the owner of the bullet is in order to determine whether it should cause damage or not - //我们必须知道子弹的主人是谁,才能判断是否应该造成伤害 - if (owner == null) - { - return false; - } + /// + /// The impact area of the bullet + /// 子弹的碰撞区域 + /// + protected Area2D? Area2D; - if (owner is not CharacterTemplate ownerCharacterTemplate) - { - return false; - } + /// + /// knockback + /// 击退 + /// + /// + ///How much force does it have when hitting the character? Unit: Number of cells,The X direction of the force is inferred automatically. + ///当击中角色时带有多大的力?单位:格数,力的X方向是自动推断的。 + /// + protected Vector2 KnockbackForce; - if (target is TileMap) - { - //When we hit the tile, we return true in order to place the bullet through the tile. - //撞击到瓦片时,我们返回true,是为了放置子弹穿透瓦片。 - return true; - } + public float Speed => GetMeta("Speed", "15").AsSingle(); - if (target is not CharacterTemplate characterTemplate) - { - return false; - } + /// + /// The master of the weapon + /// 武器的主人 + /// + public new Node2D? Owner { get; set; } - //First get the owner's camp and compare it with the target camp - //先获取主人的阵营与目标阵营进行比较 - var canCauseHarm = CampManager.CanCauseHarm(CampManager.GetCamp(ownerCharacterTemplate.CampId), - CampManager.GetCamp(characterTemplate.CampId)); - return canCauseHarm; - } + public override void _Ready() + { + //The bullet's impact detection area + //子弹的碰撞检测区域 + Area2D = GetNode("CollisionDetectionArea"); + Area2D.Monitoring = true; + Area2D.BodyEntered += OnBodyEnter; + Area2D.BodyExited += OnBodyExited; + Durability = GetMeta("Durability", "1").AsDouble(); + MaxDamage = GetMeta("MaxDamage", "7").AsInt32(); + MinDamage = GetMeta("MinDamage", "5").AsInt32(); + DamageType = GetMeta("DamageType", Config.DamageType.Physical).AsInt32(); + KnockbackForce = GetMeta("Knockback", Vector2.Zero).AsVector2(); + //life(ms) + //子弹的存在时间(毫秒) + Life = GetMeta("Life", "10000").AsInt64(); + //If the existence time is less than or equal to 0, then it is set to exist for 10 seconds, and projectiles that exist indefinitely are prohibited + //如果存在时间小于等于0,那么设置为存在10秒,禁止无限期存在的抛射体 + if (Life <= 0) + { + Life = 10000; + } - /// - /// Executive injury treatment - /// 执行伤害处理 - /// - /// - /// - private void DoDamage(Node2D? owner, Node2D target) - { - if (target is not CharacterTemplate characterTemplate) - { - return; - } - - //Allow damage to be caused - //允许造成伤害 - var damage = new Damage(); - damage.Attacker = owner; - damage.MaxDamage = MaxDamage; - damage.MinDamage = MinDamage; - damage.CreateDamage(); - damage.MoveLeft = Velocity.X < 0; - damage.Type = DamageType; - characterTemplate.Damage(damage); - if (KnockbackForce != Vector2.Zero) - { - //If we set the attack force, then apply the force to the object - //如果我们设置了攻退力,那么将力应用到对象上 - var force = new Vector2(); - var forceX = Math.Abs(KnockbackForce.X); - if (Velocity.X < 0) - { - //Beat back to port - //向左击退 - forceX = -forceX; - } - - force.X = forceX * Config.CellSize; - force.Y = KnockbackForce.Y * Config.CellSize; - characterTemplate.AddForce(force); - } - } - - /// - /// When the bullet is in contact with the node - /// 当子弹与节点接触时 - /// - /// - protected virtual void OnBodyEnter(Node2D node) - { - //Here we test whether harm is allowed, notice that for TileMap, we directly allow harm. - //这里我们检测是否允许造成伤害,注意对于TileMap,我们直接允许造成伤害。 - var canCauseHarm = CanCauseHarm(Owner, node); - if (!canCauseHarm) - { - return; - } - DoDamage(Owner, node); - //Please specify in the Mask who the bullet will collide with - //请在Mask内配置子弹会和谁碰撞 - //When a bullet hits an object, its durability decreases - //子弹撞击到物体时,耐久度减少 - Durability--; - if (Durability <= 0) - { - //When the durability is less than or equal to 0, destroy the bullet - //当耐久度小于等于0时,销毁子弹 - QueueFree(); - } - } - - /// - /// When the bullet leaves the node - /// 当子弹离开节点时 - /// - /// - protected virtual void OnBodyExited(Node2D node) - { - } + _destructionTime = DateTime.Now.AddMilliseconds(Life); + } - /// - /// When beyond the time of existence - /// 当超过存在时间 - /// - private void OnTimeOut() - { - QueueFree(); - } + /// + /// Detect whether harm is allowed + /// 检测是否允许造成伤害 + /// + /// + /// + /// + private bool CanCauseHarm(Node2D? owner, Node2D target) + { + //We must know who the owner of the bullet is in order to determine whether it should cause damage or not + //我们必须知道子弹的主人是谁,才能判断是否应该造成伤害 + if (owner == null) + { + return false; + } - public override void _PhysicsProcess(double delta) - { - MoveAndSlide(); - } -} + if (owner is not CharacterTemplate ownerCharacterTemplate) + { + return false; + } + + if (target is TileMap) + { + //When we hit the tile, we return true in order to place the bullet through the tile. + //撞击到瓦片时,我们返回true,是为了放置子弹穿透瓦片。 + return true; + } + + if (target is not CharacterTemplate characterTemplate) + { + return false; + } + + //First get the owner's camp and compare it with the target camp + //先获取主人的阵营与目标阵营进行比较 + var canCauseHarm = CampManager.CanCauseHarm(CampManager.GetCamp(ownerCharacterTemplate.CampId), + CampManager.GetCamp(characterTemplate.CampId)); + return canCauseHarm; + } + + /// + /// Executive injury treatment + /// 执行伤害处理 + /// + /// + /// + private void DoDamage(Node2D? owner, Node2D target) + { + if (target is not CharacterTemplate characterTemplate) + { + return; + } + + //Allow damage to be caused + //允许造成伤害 + var damage = new Damage + { + Attacker = owner, + MaxDamage = MaxDamage, + MinDamage = MinDamage + }; + damage.CreateDamage(); + damage.MoveLeft = Velocity.X < 0; + damage.Type = DamageType; + characterTemplate.Damage(damage); + if (KnockbackForce != Vector2.Zero) + { + //If we set the attack force, then apply the force to the object + //如果我们设置了攻退力,那么将力应用到对象上 + var force = new Vector2(); + var forceX = Math.Abs(KnockbackForce.X); + if (Velocity.X < 0) + { + //Beat back to port + //向左击退 + forceX = -forceX; + } + + force.X = forceX * Config.CellSize; + force.Y = KnockbackForce.Y * Config.CellSize; + characterTemplate.AddForce(force); + } + } + + /// + /// When the bullet is in contact with the node + /// 当子弹与节点接触时 + /// + /// + protected virtual void OnBodyEnter(Node2D node) + { + //Here we test whether harm is allowed, notice that for TileMap, we directly allow harm. + //这里我们检测是否允许造成伤害,注意对于TileMap,我们直接允许造成伤害。 + var canCauseHarm = CanCauseHarm(Owner, node); + if (!canCauseHarm) + { + return; + } + + DoDamage(Owner, node); + //Please specify in the Mask who the bullet will collide with + //请在Mask内配置子弹会和谁碰撞 + //When a bullet hits an object, its durability decreases + //子弹撞击到物体时,耐久度减少 + Durability--; + if (Durability <= 0) + { + //When the durability is less than or equal to 0, destroy the bullet + //当耐久度小于等于0时,销毁子弹 + QueueFree(); + } + } + + /// + /// When the bullet leaves the node + /// 当子弹离开节点时 + /// + /// + protected virtual void OnBodyExited(Node2D node) + { + } + + + /// + /// When beyond the time of existence + /// 当超过存在时间 + /// + private void OnTimeOut() + { + QueueFree(); + } + + public override void _Process(double delta) + { + //If the existence time is exceeded, the projectile is destroyed + //如果超过了存在时间,那么销毁抛射体 + if (DateTime.Now >= _destructionTime) + { + OnTimeOut(); + } + } + + public override void _PhysicsProcess(double delta) + { + MoveAndSlide(); + } +} \ No newline at end of file diff --git a/scripts/serialization/JsonSerialization.cs b/scripts/serialization/JsonSerialization.cs index 8dfa329..a626571 100644 --- a/scripts/serialization/JsonSerialization.cs +++ b/scripts/serialization/JsonSerialization.cs @@ -5,9 +5,13 @@ using System.Threading.Tasks; namespace ColdMint.scripts.serialization; +/// +/// JsonSerialization +/// Json序列化工具 +/// public static class JsonSerialization { - private static JsonSerializerOptions _options = new JsonSerializerOptions + private static readonly JsonSerializerOptions Options = new() { //Case-insensitive attribute matching //不区分大小写的属性匹配 @@ -30,7 +34,7 @@ public static class JsonSerialization public static async Task ReadJsonFileToObj(string path) { await using var openStream = File.OpenRead(path); - return await JsonSerializer.DeserializeAsync(openStream, _options); + return await JsonSerializer.DeserializeAsync(openStream, Options); } /// @@ -41,7 +45,7 @@ public static class JsonSerialization /// public static string Serialize(object obj) { - return JsonSerializer.Serialize(obj, _options); + return JsonSerializer.Serialize(obj, Options); } /// @@ -53,11 +57,11 @@ public static class JsonSerialization /// public static T? Deserialize(string json) { - return JsonSerializer.Deserialize(json, _options); + return JsonSerializer.Deserialize(json, Options); } public static async Task ReadJsonFileToObj(Stream openStream) { - return await JsonSerializer.DeserializeAsync(openStream, _options); + return await JsonSerializer.DeserializeAsync(openStream, Options); } } \ No newline at end of file diff --git a/scripts/utils/CoordinateUtils.cs b/scripts/utils/CoordinateUtils.cs index af6ab18..a07f079 100644 --- a/scripts/utils/CoordinateUtils.cs +++ b/scripts/utils/CoordinateUtils.cs @@ -2,7 +2,11 @@ namespace ColdMint.scripts.utils; -public class CoordinateUtils +/// +/// CoordinateUtils +/// 坐标工具类 +/// +public static class CoordinateUtils { /// /// 方向描述 diff --git a/scripts/utils/ExplorerUtils.cs b/scripts/utils/ExplorerUtils.cs index bdb75cb..473da55 100644 --- a/scripts/utils/ExplorerUtils.cs +++ b/scripts/utils/ExplorerUtils.cs @@ -1,4 +1,5 @@ -using System.Diagnostics; +using System; +using System.Diagnostics; namespace ColdMint.scripts.utils; @@ -6,7 +7,7 @@ namespace ColdMint.scripts.utils; /// Explorer Utils /// 资源管理器工具 /// -public class ExplorerUtils +public static class ExplorerUtils { /// /// Call Explorer to open the directory @@ -53,6 +54,12 @@ public class ExplorerUtils }; Process.Start(startInfoAndroid); break; + case Config.OsEnum.Unknown: + case Config.OsEnum.Macos: + case Config.OsEnum.Ios: + case Config.OsEnum.Web: + default: + throw new ArgumentOutOfRangeException(); } } @@ -64,14 +71,10 @@ public class ExplorerUtils public static bool SupportOpenDirectory() { var osEnum = Config.GetOs(); - switch (osEnum) + return osEnum switch { - case Config.OsEnum.Windows: - case Config.OsEnum.Linux: - case Config.OsEnum.Android: - return true; - default: - return false; - } + Config.OsEnum.Windows or Config.OsEnum.Linux or Config.OsEnum.Android => true, + _ => false + }; } } \ No newline at end of file diff --git a/scripts/utils/GuidUtils.cs b/scripts/utils/GuidUtils.cs index 9d2408d..c5d313a 100644 --- a/scripts/utils/GuidUtils.cs +++ b/scripts/utils/GuidUtils.cs @@ -2,7 +2,11 @@ namespace ColdMint.scripts.utils; -public class GuidUtils +/// +/// GuidUtils +/// Guid工具 +/// +public static class GuidUtils { /// /// Get the new GUID diff --git a/scripts/utils/HashCodeUtils.cs b/scripts/utils/HashCodeUtils.cs index db479f6..5b8bd22 100644 --- a/scripts/utils/HashCodeUtils.cs +++ b/scripts/utils/HashCodeUtils.cs @@ -2,7 +2,11 @@ namespace ColdMint.scripts.utils; -public class HashCodeUtils +/// +/// Hash code utils +/// 哈希码工具 +/// +public static class HashCodeUtils { /// /// Gets the hash code for a string @@ -15,6 +19,8 @@ public class HashCodeUtils /// public static uint GetFixedHashCode(string str) { + //Turn off overflow checking to improve performance + //关闭溢出检查,以提高性能 unchecked { return str.Aggregate(2166136261, (current, c) => (current ^ c) * 16777619); diff --git a/scripts/utils/Md5Utils.cs b/scripts/utils/Md5Utils.cs index 63be004..8f98262 100644 --- a/scripts/utils/Md5Utils.cs +++ b/scripts/utils/Md5Utils.cs @@ -15,14 +15,10 @@ public class Md5Utils /// public static string GetFileMd5(string filePath) { - using (var md5 = MD5.Create()) - { - using (var stream = File.OpenRead(filePath)) - { - var hash = md5.ComputeHash(stream); - return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant(); - } - } + using var md5 = MD5.Create(); + using var stream = File.OpenRead(filePath); + var hash = md5.ComputeHash(stream); + return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant(); } /// @@ -33,10 +29,8 @@ public class Md5Utils /// public static string GetStringMd5(string str) { - using (var md5 = MD5.Create()) - { - var hash = md5.ComputeHash(Encoding.UTF8.GetBytes(str)); - return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant(); - } + using var md5 = MD5.Create(); + var hash = md5.ComputeHash(Encoding.UTF8.GetBytes(str)); + return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant(); } } \ No newline at end of file diff --git a/scripts/utils/NodeUtils.cs b/scripts/utils/NodeUtils.cs index 694e25c..3d6dd29 100644 --- a/scripts/utils/NodeUtils.cs +++ b/scripts/utils/NodeUtils.cs @@ -4,7 +4,11 @@ using Godot; namespace ColdMint.scripts.utils; -public class NodeUtils +/// +/// Node Utils +/// 节点工具 +/// +public static class NodeUtils { /// /// Delete all child nodes @@ -81,11 +85,10 @@ public class NodeUtils continue; } - var distance = node2D.GlobalPosition - origin.GlobalPosition; - var distanceLength = distance.Length(); - if (distanceLength < closestDistance) + var distance = node2D.GlobalPosition.DistanceTo(origin.GlobalPosition); + if (distance < closestDistance) { - closestDistance = distanceLength; + closestDistance = distance; closestNode = node2D; } } diff --git a/scripts/utils/ParabolicUtils.cs b/scripts/utils/ParabolicUtils.cs index 1ec4ecb..eaac153 100644 --- a/scripts/utils/ParabolicUtils.cs +++ b/scripts/utils/ParabolicUtils.cs @@ -6,7 +6,7 @@ namespace ColdMint.scripts.utils; /// ParabolicUtils /// 抛物线工具 /// -public class ParabolicUtils +public static class ParabolicUtils { /// /// Calculated parabola @@ -40,7 +40,7 @@ public class ParabolicUtils // 初始化结果数组 var points = new Vector2[numSteps]; // 计算每个采样点的位置 - for (int i = 0; i < numSteps; i++) + for (var i = 0; i < numSteps; i++) { // 计算当前时间 var t = i * steps; diff --git a/scripts/utils/StrUtils.cs b/scripts/utils/StrUtils.cs index 8141d15..2918257 100644 --- a/scripts/utils/StrUtils.cs +++ b/scripts/utils/StrUtils.cs @@ -1,6 +1,10 @@ namespace ColdMint.scripts.utils; -public class StrUtils +/// +/// StrUtils +/// 字符串工具 +/// +public static class StrUtils { /// diff --git a/scripts/utils/TileMapUtils.cs b/scripts/utils/TileMapUtils.cs index 45659a4..09399a6 100644 --- a/scripts/utils/TileMapUtils.cs +++ b/scripts/utils/TileMapUtils.cs @@ -2,6 +2,10 @@ namespace ColdMint.scripts.utils; +/// +/// TileMapUtils +/// TileMap工具 +/// public static class TileMapUtils { /// diff --git a/scripts/utils/TimeUtils.cs b/scripts/utils/TimeUtils.cs index 52bfc43..85e7e30 100644 --- a/scripts/utils/TimeUtils.cs +++ b/scripts/utils/TimeUtils.cs @@ -3,6 +3,10 @@ using ColdMint.scripts.debug; namespace ColdMint.scripts.utils; +/// +/// Time Utils +/// 时间工具 +/// public static class TimeUtils { /// diff --git a/scripts/utils/TranslationServerUtils.cs b/scripts/utils/TranslationServerUtils.cs index be74b66..2bb9e84 100644 --- a/scripts/utils/TranslationServerUtils.cs +++ b/scripts/utils/TranslationServerUtils.cs @@ -2,6 +2,10 @@ namespace ColdMint.scripts.utils; +/// +/// Translation server utils +/// 翻译服务器工具 +/// public static class TranslationServerUtils { /// diff --git a/scripts/weapon/ProjectileWeapon.cs b/scripts/weapon/ProjectileWeapon.cs index b5a4cca..71ea042 100644 --- a/scripts/weapon/ProjectileWeapon.cs +++ b/scripts/weapon/ProjectileWeapon.cs @@ -5,9 +5,26 @@ using Godot; namespace ColdMint.scripts.weapon; +/// +/// Projectile weapons +/// 抛射体武器 +/// +/// +///These weapons can fire projectiles to attack the enemy.For example: guns and scepters.Generate a bullet to attack the enemy. +///这类武器可发射抛射体,攻击敌人。例如:枪支和法杖。生成一个子弹攻击敌人。 +/// public partial class ProjectileWeapon : WeaponTemplate { + /// + /// The formation position of the projectile + /// 抛射体的生成位置 + /// private Marker2D? _marker2D; + + /// + /// List of projectiles + /// 抛射体列表 + /// private string[]? _projectiles; private Dictionary? _projectileCache; private Node2D? _projectileContainer; @@ -21,6 +38,10 @@ public partial class ProjectileWeapon : WeaponTemplate foreach (var projectileItem in _projectiles) { var packedScene = GD.Load(projectileItem); + if (packedScene == null) + { + continue; + } _projectileCache.Add(projectileItem, packedScene); } @@ -30,26 +51,25 @@ public partial class ProjectileWeapon : WeaponTemplate protected override void DoFire(Node2D? owner, Vector2 enemyGlobalPosition) { - if (_projectiles.IsEmpty()) - { - LogCat.LogError("projectiles_is_empty"); - return; - } - if (_projectileCache == null || _projectiles == null || owner == null || _projectileContainer == null || _marker2D == null) { return; } - + + if (_projectiles.IsEmpty()) + { + LogCat.LogError("projectiles_is_empty"); + return; + } //Get the first projectile + //获取第一个抛射体 var projectileScene = _projectileCache[_projectiles[0]]; var projectile = projectileScene.Instantiate() as ProjectileTemplate; if (projectile != null) { projectile.Owner = owner; - var vector2 = (enemyGlobalPosition - _marker2D.GlobalPosition).Normalized() * projectile.Speed; - projectile.Velocity = vector2; + projectile.Velocity = (enemyGlobalPosition - _marker2D.GlobalPosition).Normalized() * projectile.Speed; projectile.Position = _marker2D.GlobalPosition; } diff --git a/scripts/weapon/WeaponTemplate.cs b/scripts/weapon/WeaponTemplate.cs index d4d15d2..c3c27be 100644 --- a/scripts/weapon/WeaponTemplate.cs +++ b/scripts/weapon/WeaponTemplate.cs @@ -13,7 +13,7 @@ namespace ColdMint.scripts.weapon; /// public partial class WeaponTemplate : RigidBody2D, IItem { - public float Gravity = ProjectSettings.GetSetting("physics/2d/default_gravity").AsSingle(); + private float _gravity = ProjectSettings.GetSetting("physics/2d/default_gravity").AsSingle(); public string? Id { get; set; } public int Quantity { get; set; } @@ -42,7 +42,10 @@ public partial class WeaponTemplate : RigidBody2D, IItem private DateTime? _lastFiringTime; - //开火间隔 + /// + /// Firing interval + /// 开火间隔 + /// private TimeSpan _firingInterval; @@ -56,6 +59,10 @@ public partial class WeaponTemplate : RigidBody2D, IItem /// private Vector2 _recoil; + /// + /// This area represents the collision range of the weapon, and when other nodes enter this area, they will deal damage. + /// 这个区域表示武器的碰撞范围,当其他节点进入此区域时,会造成伤害。 + /// private Area2D? _area2D; protected RayCast2D? RayCast2D; @@ -117,7 +124,6 @@ public partial class WeaponTemplate : RigidBody2D, IItem //If allowed to cause harm //如果允许造成伤害 - Owner = null; var damage = new Damage { MaxDamage = Math.Abs(_maxContactInjury), @@ -128,6 +134,9 @@ public partial class WeaponTemplate : RigidBody2D, IItem damage.MoveLeft = LinearVelocity.X < 0; damage.Type = Config.DamageType.Physical; characterTemplate.Damage(damage); + //Can only cause one collision damage. + //仅能造成一次碰撞伤害。 + EnableContactInjury = false; } ///