Improved the collision logic of bullets.

改进子弹的碰撞逻辑。
This commit is contained in:
Cold-Mint 2024-08-12 22:30:13 +08:00
parent ef58f3885b
commit 3b2ba7440c
Signed by: Cold-Mint
GPG Key ID: C5A9BF8A98E0CE99
8 changed files with 87 additions and 75 deletions

View File

@ -24,7 +24,9 @@ animations = [{
[node name="Player" type="CharacterBody2D"]
collision_layer = 4
collision_mask = 34
collision_mask = 162
platform_floor_layers = 4294967042
platform_wall_layers = 128
script = ExtResource("1_1dlls")
MaxHp = 32
CampId = "Default"

View File

@ -9,16 +9,20 @@
radius = 11.0
[node name="curseOfTheUndead" type="CharacterBody2D"]
collision_layer = 0
collision_mask = 0
collision_layer = 16
collision_mask = 102
slide_on_ceiling = false
platform_floor_layers = 4294967042
platform_wall_layers = 32
script = ExtResource("1_ib3qh")
Life = 5000
Durability = 1.0
Durability = 3.0
MaxDamage = 3
MinDamage = 10
DamageType = 2
KnockbackForce = Vector2(2, -3)
Speed = 500.0
Speed = 300.0
EnableBounce = true
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
shape = SubResource("CircleShape2D_dgro2")

View File

@ -28,7 +28,7 @@ shape = SubResource("CircleShape2D_dgro2")
[node name="CollisionDetectionArea" type="Area2D" parent="."]
collision_layer = 16
collision_mask = 78
collision_mask = 206
[node name="CollisionShape2D" type="CollisionShape2D" parent="CollisionDetectionArea"]
shape = SubResource("CircleShape2D_8117d")

View File

@ -151,12 +151,13 @@ locale/translations=PackedStringArray("res://locals/DeathInfo.en.translation", "
[layer_names]
2d_physics/layer_1="RoomArea"
2d_physics/layer_2="Ground"
2d_physics/layer_2="Floor"
2d_physics/layer_3="Player"
2d_physics/layer_4="PickAbleItem"
2d_physics/layer_5="Projectile"
2d_physics/layer_6="Platform"
2d_physics/layer_7="Mob"
2d_physics/layer_8="Wall"
[physics]

View File

@ -425,12 +425,13 @@ public static class Config
public static class LayerNumber
{
public const int RoomArea = 1;
public const int Ground = 2;
public const int Floor = 2;
public const int Player = 3;
public const int PickAbleItem = 4;
public const int Projectile = 5;
public const int Platform = 6;
public const int Mob = 7;
public const int Wall = 8;
}
/// <summary>

View File

@ -286,7 +286,6 @@ public partial class CharacterTemplate : CharacterBody2D
_healthBar.MaxValue = MaxHp;
}
ItemMarker2D = GetNode<Marker2D>("ItemMarker2D");
_itemMarkerOriginalX = ItemMarker2D.Position.X;
_animatedSprite2D = GetNode<AnimatedSprite2D>("AnimatedSprite2D");
@ -303,6 +302,11 @@ public partial class CharacterTemplate : CharacterBody2D
_pickingArea.BodyEntered += EnterThePickingRangeBody;
_pickingArea.BodyExited += ExitThePickingRangeBody;
}
//The character cannot pass through the wall and floor
//角色不能穿过墙壁和地板
SetCollisionMaskValue(Config.LayerNumber.Wall, true);
SetCollisionMaskValue(Config.LayerNumber.Floor, true);
}
/// <summary>
@ -389,7 +393,8 @@ public partial class CharacterTemplate : CharacterBody2D
pickAbleTemplate.Owner = this;
pickAbleTemplate.Picked = true;
pickAbleTemplate.SetCollisionMaskValue(Config.LayerNumber.Platform, false);
pickAbleTemplate.SetCollisionMaskValue(Config.LayerNumber.Ground, false);
pickAbleTemplate.SetCollisionMaskValue(Config.LayerNumber.Floor, false);
pickAbleTemplate.SetCollisionMaskValue(Config.LayerNumber.Wall, false);
LogCat.Log("item_pickup_disables_collision_damage", LogCat.LogLabel.ContactInjury);
pickAbleTemplate.EnableContactInjury = false;
pickAbleTemplate.Sleeping = true;
@ -759,7 +764,8 @@ public partial class CharacterTemplate : CharacterBody2D
//仍出武器时,我们不能立即恢复物理碰撞,立即恢复会导致武器更早的与地面和平台碰撞,阻止武器的飞行。
pickAbleTemplate.EnableContactInjury = true;
LogCat.Log("item_thrown_restore_collision_damage", LogCat.LogLabel.ContactInjury);
pickAbleTemplate.SetCollisionMaskValue(Config.LayerNumber.Ground, true);
pickAbleTemplate.SetCollisionMaskValue(Config.LayerNumber.Floor, true);
pickAbleTemplate.SetCollisionMaskValue(Config.LayerNumber.Wall, true);
pickAbleTemplate.SetCollisionMaskValue(Config.LayerNumber.Platform, true);
timer.QueueFree();
};

View File

@ -19,8 +19,7 @@ public partial class Projectile : CharacterBody2D
/// <para>life(ms)</para>
/// <para>子弹的存在时间(毫秒)</para>
/// </summary>
[Export]
public long Life;
[Export] public long Life;
//The durability of the projectile
//抛射体的耐久度
@ -38,13 +37,6 @@ public partial class Projectile : CharacterBody2D
/// </summary>
private DateTime? _destructionTime;
/// <summary>
/// <para>The impact area of the bullet</para>
/// <para>子弹的碰撞区域</para>
/// </summary>
private Area2D? _area2D;
/// <summary>
/// <para>knockback</para>
/// <para>击退</para>
@ -53,11 +45,22 @@ public partial class Projectile : CharacterBody2D
///<para>How much force does it have when hitting the character? Unit: Number of cellsThe X direction of the force is inferred automatically.</para>
///<para>当击中角色时带有多大的力单位格数力的X方向是自动推断的。</para>
/// </remarks>
[Export]
public Vector2 KnockbackForce;
[Export] public Vector2 KnockbackForce;
[Export] public float Speed;
/// <summary>
/// <para>Whether it bounces back after hitting an enemy or a wall</para>
/// <para>是否撞到敌人或墙壁后反弹</para>
/// </summary>
[Export] public bool EnableBounce;
/// <summary>
/// <para>Can it penetrate the wall</para>
/// <para>是否可以穿透墙壁</para>
/// </summary>
[Export] public bool IgnoreWall;
private List<IProjectileDecorator>? _projectileDecorators;
@ -69,12 +72,6 @@ public partial class Projectile : CharacterBody2D
public override void _Ready()
{
//The bullet's impact detection area
//子弹的碰撞检测区域
_area2D = GetNode<Area2D>("CollisionDetectionArea");
_area2D.Monitoring = true;
_area2D.BodyEntered += OnBodyEnter;
_area2D.BodyExited += OnBodyExited;
//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)
@ -83,6 +80,11 @@ public partial class Projectile : CharacterBody2D
}
_destructionTime = DateTime.Now.AddMilliseconds(Life);
SetCollisionMaskValue(Config.LayerNumber.Wall, !IgnoreWall);
SetCollisionMaskValue(Config.LayerNumber.Floor, !IgnoreWall);
//Platform collision layer is not allowed to collide
//平台碰撞层不可碰撞
SetCollisionMaskValue(Config.LayerNumber.Platform, false);
}
/// <summary>
@ -140,7 +142,7 @@ public partial class Projectile : CharacterBody2D
//撞击到瓦片时我们返回true是为了防止子弹穿透瓦片。
return true;
}
if (target is PickAbleTemplate pickAbleTemplate)
{
//The picked-up item cannot resist the bullet.
@ -247,45 +249,6 @@ public partial class Projectile : CharacterBody2D
}
}
/// <summary>
/// <para>When the bullet is in contact with the node</para>
/// <para>当子弹与节点接触时</para>
/// </summary>
/// <param name="node"></param>
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();
}
}
/// <summary>
/// <para>When the bullet leaves the node</para>
/// <para>当子弹离开节点时</para>
/// </summary>
/// <param name="node"></param>
protected virtual void OnBodyExited(Node2D node)
{
}
/// <summary>
/// <para>When beyond the time of existence</para>
/// <para>当超过存在时间</para>
@ -307,6 +270,38 @@ public partial class Projectile : CharacterBody2D
public override void _PhysicsProcess(double delta)
{
MoveAndSlide();
var collisionInfo = MoveAndCollide(Velocity * (float)delta);
if (collisionInfo != null)
{
//Bump into other objects.
//撞到其他对象。
if (EnableBounce)
{
Velocity = Velocity.Bounce(collisionInfo.GetNormal());
}
//Here we test whether harm is allowed, notice that for TileMap, we directly allow harm.
//这里我们检测是否允许造成伤害注意对于TileMap我们直接允许造成伤害。
var godotObject = collisionInfo.GetCollider();
var node = (Node2D)godotObject;
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();
}
}
}
}

View File

@ -6,14 +6,14 @@
texture = ExtResource("1_4c2am")
texture_region_size = Vector2i(32, 32)
0:0/0 = 0
0:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-16, -16, 16, -16, 16, 16, -16, 16)
0:0/0/physics_layer_2/polygon_0/points = PackedVector2Array(-16, -16, 16, -16, 16, 16, -16, 16)
1:0/0 = 0
1:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-16, -16, 16, -16, 16, 16, -16, 16)
1:1/0 = 0
2:1/0 = 0
2:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-16, -16, 16, -16, 16, 16, -16, 16)
2:1/0/physics_layer_2/polygon_0/points = PackedVector2Array(-16, -16, 16, -16, 16, 16, -16, 16)
2:2/0 = 0
2:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-16, -16, 16, -16, 16, 16, -16, 16)
2:2/0/physics_layer_2/polygon_0/points = PackedVector2Array(-16, -16, 16, -16, 16, 16, -16, 16)
3:2/0 = 0
3:4/0 = 0
3:4/0/physics_layer_1/polygon_0/points = PackedVector2Array(-16, -16, 16, -16, 16, -6.75, 8.25, -6, 7, -2.25, 1, -2, -16, 16)
@ -27,17 +27,18 @@ texture_region_size = Vector2i(32, 32)
1:3/0 = 0
1:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-16, -16, 16, -16, 16, 16, -16, 16)
1:2/0 = 0
1:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-16, -16, 16, -16, 16, 16, -16, 16)
1:2/0/physics_layer_2/polygon_0/points = PackedVector2Array(-16, -16, 16, -16, 16, 16, -16, 16)
0:2/0 = 0
0:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-16, -16, 16, -16, 16, 16, -16, 16)
0:2/0/physics_layer_2/polygon_0/points = PackedVector2Array(-16, -16, 16, -16, 16, 16, -16, 16)
0:1/0 = 0
0:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-16, -16, 16, -16, 16, 16, -16, 16)
0:1/0/physics_layer_2/polygon_0/points = PackedVector2Array(-16, -16, 16, -16, 16, 16, -16, 16)
2:3/0 = 0
2:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-16, -16, 16, -16, 16, 16, -16, 16)
3:1/0 = 0
3:0/0 = 0
2:0/0 = 0
2:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-16, -16, 16, -16, 16, 16, -16, 16)
2:0/0/physics_layer_2/polygon_0/points = PackedVector2Array(-16, -16, 16, -16, 16, 16, -16, 16)
4:0/0 = 0
4:1/0 = 0
5:0/0 = 0
@ -86,4 +87,6 @@ physics_layer_0/collision_layer = 2
physics_layer_0/collision_mask = 0
physics_layer_1/collision_layer = 32
physics_layer_1/collision_mask = 0
physics_layer_2/collision_layer = 128
physics_layer_2/collision_mask = 0
sources/1 = SubResource("TileSetAtlasSource_abxy2")