Projectiles can now track enemies.
抛射体可以跟踪敌人了。
This commit is contained in:
parent
8c02a0548c
commit
2a5629fc86
|
@ -98,3 +98,11 @@ collision_mask = 76
|
||||||
|
|
||||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="ScoutArea2D"]
|
[node name="CollisionShape2D" type="CollisionShape2D" parent="ScoutArea2D"]
|
||||||
shape = SubResource("CircleShape2D_fowd5")
|
shape = SubResource("CircleShape2D_fowd5")
|
||||||
|
|
||||||
|
[node name="TipLabel" type="Label" parent="."]
|
||||||
|
offset_left = -20.0
|
||||||
|
offset_top = 46.0
|
||||||
|
offset_right = 15.0
|
||||||
|
offset_bottom = 71.0
|
||||||
|
text = "name"
|
||||||
|
horizontal_alignment = 1
|
||||||
|
|
|
@ -99,3 +99,14 @@ collision_mask = 76
|
||||||
|
|
||||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="ScoutArea2D"]
|
[node name="CollisionShape2D" type="CollisionShape2D" parent="ScoutArea2D"]
|
||||||
shape = SubResource("CircleShape2D_fowd5")
|
shape = SubResource("CircleShape2D_fowd5")
|
||||||
|
|
||||||
|
[node name="TipLabel" type="Label" parent="."]
|
||||||
|
anchors_preset = 5
|
||||||
|
anchor_left = 0.5
|
||||||
|
anchor_right = 0.5
|
||||||
|
offset_left = -57.0
|
||||||
|
offset_top = 57.0
|
||||||
|
offset_right = 61.0
|
||||||
|
offset_bottom = 82.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
horizontal_alignment = 1
|
||||||
|
|
|
@ -16,8 +16,6 @@ platform_floor_layers = 4294967042
|
||||||
platform_wall_layers = 32
|
platform_wall_layers = 32
|
||||||
script = ExtResource("1_ib3qh")
|
script = ExtResource("1_ib3qh")
|
||||||
Speed = 300.0
|
Speed = 300.0
|
||||||
IgnoreWall = true
|
|
||||||
EnableTracking = true
|
|
||||||
|
|
||||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
|
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
|
||||||
shape = SubResource("CircleShape2D_dgro2")
|
shape = SubResource("CircleShape2D_dgro2")
|
||||||
|
|
|
@ -14,8 +14,10 @@ _durability = 1.0
|
||||||
_maxDamage = 10
|
_maxDamage = 10
|
||||||
_minDamage = 1
|
_minDamage = 1
|
||||||
_damageType = 2
|
_damageType = 2
|
||||||
_knockbackForce = Vector2(60, 0)
|
_knockBackForce = Vector2(0, 1)
|
||||||
Speed = 500.0
|
Speed = 500.0
|
||||||
|
_enableTracking = true
|
||||||
|
_targetDiesDestroyProjectile = true
|
||||||
|
|
||||||
[node name="CurseOfTheUndead" type="Sprite2D" parent="."]
|
[node name="CurseOfTheUndead" type="Sprite2D" parent="."]
|
||||||
texture = ExtResource("1_k8el6")
|
texture = ExtResource("1_k8el6")
|
||||||
|
|
|
@ -12,8 +12,3 @@ texture_under = ExtResource("1_sc0v3")
|
||||||
texture_over = ExtResource("2_ay5vh")
|
texture_over = ExtResource("2_ay5vh")
|
||||||
texture_progress = ExtResource("2_s0gle")
|
texture_progress = ExtResource("2_s0gle")
|
||||||
script = ExtResource("4_84gre")
|
script = ExtResource("4_84gre")
|
||||||
|
|
||||||
[node name="Label" type="Label" parent="."]
|
|
||||||
layout_mode = 0
|
|
||||||
offset_right = 40.0
|
|
||||||
offset_bottom = 23.0
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ anchor_right = 1.0
|
||||||
anchor_bottom = 1.0
|
anchor_bottom = 1.0
|
||||||
grow_horizontal = 2
|
grow_horizontal = 2
|
||||||
grow_vertical = 2
|
grow_vertical = 2
|
||||||
|
mouse_filter = 2
|
||||||
|
|
||||||
[node name="VBoxContainer" type="VBoxContainer" parent="CanvasLayer/Control"]
|
[node name="VBoxContainer" type="VBoxContainer" parent="CanvasLayer/Control"]
|
||||||
layout_mode = 1
|
layout_mode = 1
|
||||||
|
@ -34,25 +35,31 @@ offset_right = -20.0
|
||||||
offset_bottom = -20.0
|
offset_bottom = -20.0
|
||||||
grow_horizontal = 2
|
grow_horizontal = 2
|
||||||
grow_vertical = 0
|
grow_vertical = 0
|
||||||
|
mouse_filter = 2
|
||||||
|
|
||||||
[node name="HealthBarUi" type="HBoxContainer" parent="CanvasLayer/Control/VBoxContainer"]
|
[node name="HealthBarUi" type="HBoxContainer" parent="CanvasLayer/Control/VBoxContainer"]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
|
mouse_filter = 2
|
||||||
script = ExtResource("2_xrm3v")
|
script = ExtResource("2_xrm3v")
|
||||||
|
|
||||||
[node name="TextureRect3" type="TextureRect" parent="CanvasLayer/Control/VBoxContainer/HealthBarUi"]
|
[node name="TextureRect3" type="TextureRect" parent="CanvasLayer/Control/VBoxContainer/HealthBarUi"]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
|
mouse_filter = 2
|
||||||
texture = ExtResource("2_n1yht")
|
texture = ExtResource("2_n1yht")
|
||||||
|
|
||||||
[node name="HotBar" type="HBoxContainer" parent="CanvasLayer/Control/VBoxContainer"]
|
[node name="HotBar" type="HBoxContainer" parent="CanvasLayer/Control/VBoxContainer"]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
|
mouse_filter = 2
|
||||||
script = ExtResource("2_owrhq")
|
script = ExtResource("2_owrhq")
|
||||||
|
|
||||||
[node name="TextureRect3" type="TextureRect" parent="CanvasLayer/Control/VBoxContainer/HotBar"]
|
[node name="TextureRect3" type="TextureRect" parent="CanvasLayer/Control/VBoxContainer/HotBar"]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
|
mouse_filter = 2
|
||||||
texture = ExtResource("2_n1yht")
|
texture = ExtResource("2_n1yht")
|
||||||
|
|
||||||
[node name="OperationTip" type="RichTextLabel" parent="CanvasLayer/Control/VBoxContainer"]
|
[node name="OperationTip" type="RichTextLabel" parent="CanvasLayer/Control/VBoxContainer"]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
|
mouse_filter = 2
|
||||||
bbcode_enabled = true
|
bbcode_enabled = true
|
||||||
fit_content = true
|
fit_content = true
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ anchor_right = 1.0
|
||||||
anchor_bottom = 1.0
|
anchor_bottom = 1.0
|
||||||
grow_horizontal = 2
|
grow_horizontal = 2
|
||||||
grow_vertical = 2
|
grow_vertical = 2
|
||||||
|
mouse_filter = 2
|
||||||
script = ExtResource("1_vj6du")
|
script = ExtResource("1_vj6du")
|
||||||
|
|
||||||
[node name="ColorRect" type="ColorRect" parent="."]
|
[node name="ColorRect" type="ColorRect" parent="."]
|
||||||
|
@ -18,6 +19,7 @@ anchor_right = 1.0
|
||||||
anchor_bottom = 1.0
|
anchor_bottom = 1.0
|
||||||
grow_horizontal = 2
|
grow_horizontal = 2
|
||||||
grow_vertical = 2
|
grow_vertical = 2
|
||||||
|
mouse_filter = 2
|
||||||
color = Color(0.941176, 0.243137, 0.243137, 0.258824)
|
color = Color(0.941176, 0.243137, 0.243137, 0.258824)
|
||||||
|
|
||||||
[node name="CenterContainer" type="CenterContainer" parent="."]
|
[node name="CenterContainer" type="CenterContainer" parent="."]
|
||||||
|
@ -27,12 +29,15 @@ anchor_right = 1.0
|
||||||
anchor_bottom = 1.0
|
anchor_bottom = 1.0
|
||||||
grow_horizontal = 2
|
grow_horizontal = 2
|
||||||
grow_vertical = 2
|
grow_vertical = 2
|
||||||
|
mouse_filter = 2
|
||||||
|
|
||||||
[node name="VBoxContainer" type="VBoxContainer" parent="CenterContainer"]
|
[node name="VBoxContainer" type="VBoxContainer" parent="CenterContainer"]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
|
mouse_filter = 2
|
||||||
|
|
||||||
[node name="CenterContainer" type="CenterContainer" parent="CenterContainer/VBoxContainer"]
|
[node name="CenterContainer" type="CenterContainer" parent="CenterContainer/VBoxContainer"]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
|
mouse_filter = 2
|
||||||
|
|
||||||
[node name="GameOverLabel" type="Label" parent="CenterContainer/VBoxContainer/CenterContainer"]
|
[node name="GameOverLabel" type="Label" parent="CenterContainer/VBoxContainer/CenterContainer"]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
|
@ -41,10 +46,12 @@ text = "ui_game_over_title"
|
||||||
|
|
||||||
[node name="MarginContainer" type="MarginContainer" parent="CenterContainer/VBoxContainer"]
|
[node name="MarginContainer" type="MarginContainer" parent="CenterContainer/VBoxContainer"]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
|
mouse_filter = 2
|
||||||
theme_override_constants/margin_top = 18
|
theme_override_constants/margin_top = 18
|
||||||
|
|
||||||
[node name="CenterContainer2" type="CenterContainer" parent="CenterContainer/VBoxContainer/MarginContainer"]
|
[node name="CenterContainer2" type="CenterContainer" parent="CenterContainer/VBoxContainer/MarginContainer"]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
|
mouse_filter = 2
|
||||||
|
|
||||||
[node name="DeathInfoLabel" type="Label" parent="CenterContainer/VBoxContainer/MarginContainer/CenterContainer2"]
|
[node name="DeathInfoLabel" type="Label" parent="CenterContainer/VBoxContainer/MarginContainer/CenterContainer2"]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
|
@ -52,6 +59,7 @@ text = "ui_death_info_describe"
|
||||||
|
|
||||||
[node name="MarginContainer2" type="MarginContainer" parent="CenterContainer/VBoxContainer"]
|
[node name="MarginContainer2" type="MarginContainer" parent="CenterContainer/VBoxContainer"]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
|
mouse_filter = 2
|
||||||
theme_override_constants/margin_top = 10
|
theme_override_constants/margin_top = 10
|
||||||
theme_override_constants/margin_bottom = 150
|
theme_override_constants/margin_bottom = 150
|
||||||
|
|
||||||
|
|
|
@ -35,12 +35,18 @@ public static class GameSceneNodeHolder
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <para>When the mouse enters the scope of a character, it is considered a target</para>
|
||||||
|
/// <para>鼠标进入到某个角色的范围内时,会将其视作目标</para>
|
||||||
|
/// </summary>
|
||||||
|
public static Node2D? TemporaryTargetNode { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// <para>ProjectileContainer</para>
|
/// <para>ProjectileContainer</para>
|
||||||
/// <para>抛射体容器</para>
|
/// <para>抛射体容器</para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static Node2D? ProjectileContainer { get; set; }
|
public static Node2D? ProjectileContainer { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// <para>WeaponContainer</para>
|
/// <para>WeaponContainer</para>
|
||||||
/// <para>武器容器</para>
|
/// <para>武器容器</para>
|
||||||
|
@ -113,16 +119,14 @@ public static class GameSceneNodeHolder
|
||||||
|
|
||||||
NodeUtils.ForEachNode<PacksackUi>(BackpackUiContainer, node =>
|
NodeUtils.ForEachNode<PacksackUi>(BackpackUiContainer, node =>
|
||||||
{
|
{
|
||||||
|
|
||||||
//If the child node is not visible, the traversal continues.
|
//If the child node is not visible, the traversal continues.
|
||||||
//如果子节点不可见,则继续遍历。
|
//如果子节点不可见,则继续遍历。
|
||||||
if (!node.Visible)
|
if (!node.Visible)
|
||||||
return false;
|
return false;
|
||||||
//Until you find a visible node, hide it, and return true, ending the loop.
|
//Until you find a visible node, hide it, and return true, ending the loop.
|
||||||
//直到找到可见的节点,隐藏该节点,然后返回true,结束遍历。
|
//直到找到可见的节点,隐藏该节点,然后返回true,结束遍历。
|
||||||
node.Hide();
|
node.Hide();
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -178,6 +178,7 @@ public partial class CharacterTemplate : CharacterBody2D
|
||||||
[Export] public string LootListId { get; private set; } = "";
|
[Export] public string LootListId { get; private set; } = "";
|
||||||
|
|
||||||
private HealthBar? _healthBar;
|
private HealthBar? _healthBar;
|
||||||
|
private Label? _tipLabel;
|
||||||
private DateTime _lastDamageTime;
|
private DateTime _lastDamageTime;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -291,6 +292,7 @@ public partial class CharacterTemplate : CharacterBody2D
|
||||||
_animatedSprite2D = GetNode<AnimatedSprite2D>("AnimatedSprite2D");
|
_animatedSprite2D = GetNode<AnimatedSprite2D>("AnimatedSprite2D");
|
||||||
_pickingArea = GetNode<Area2D>("Area2DPickingArea");
|
_pickingArea = GetNode<Area2D>("Area2DPickingArea");
|
||||||
_damageNumber = GetNode<Marker2D>("DamageNumber") as DamageNumberNodeSpawn;
|
_damageNumber = GetNode<Marker2D>("DamageNumber") as DamageNumberNodeSpawn;
|
||||||
|
_tipLabel = GetNodeOrNull<Label>("TipLabel");
|
||||||
if (_pickingArea != null)
|
if (_pickingArea != null)
|
||||||
{
|
{
|
||||||
//If true, the zone will detect objects or areas entering and leaving the zone.
|
//If true, the zone will detect objects or areas entering and leaving the zone.
|
||||||
|
@ -307,6 +309,52 @@ public partial class CharacterTemplate : CharacterBody2D
|
||||||
//角色不能穿过墙壁和地板
|
//角色不能穿过墙壁和地板
|
||||||
SetCollisionMaskValue(Config.LayerNumber.Wall, true);
|
SetCollisionMaskValue(Config.LayerNumber.Wall, true);
|
||||||
SetCollisionMaskValue(Config.LayerNumber.Floor, true);
|
SetCollisionMaskValue(Config.LayerNumber.Floor, true);
|
||||||
|
InputPickable = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void _ExitTree()
|
||||||
|
{
|
||||||
|
base._ExitTree();
|
||||||
|
if (GameSceneNodeHolder.TemporaryTargetNode == this)
|
||||||
|
{
|
||||||
|
GameSceneNodeHolder.TemporaryTargetNode = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private bool _mouseEntered;
|
||||||
|
|
||||||
|
public override void _InputEvent(Viewport viewport, InputEvent @event, int shapeIdx)
|
||||||
|
{
|
||||||
|
if (!_mouseEntered)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void _MouseEnter()
|
||||||
|
{
|
||||||
|
_mouseEntered = true;
|
||||||
|
GameSceneNodeHolder.TemporaryTargetNode = this;
|
||||||
|
if (_tipLabel != null)
|
||||||
|
{
|
||||||
|
_tipLabel.Visible = true;
|
||||||
|
_tipLabel.Text = CharacterName;
|
||||||
|
//Vertical Centering Tip
|
||||||
|
//垂直居中提示
|
||||||
|
var oldPosition = _tipLabel.Position;
|
||||||
|
oldPosition.X = -_tipLabel.Size.X / 2;
|
||||||
|
_tipLabel.Position = oldPosition;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void _MouseExit()
|
||||||
|
{
|
||||||
|
_mouseEntered = false;
|
||||||
|
if (_tipLabel != null)
|
||||||
|
{
|
||||||
|
_tipLabel.Visible = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -67,11 +67,17 @@ public partial class Projectile : CharacterBody2D
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Export] private bool _enableTracking;
|
[Export] private bool _enableTracking;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <para>The target dies and destroys the projectile at the same time</para>
|
||||||
|
/// <para>在目标死亡后销毁抛射体</para>
|
||||||
|
/// </summary>
|
||||||
|
[Export]private bool _targetDiesDestroyProjectile;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// <para>The target</para>
|
/// <para>The target</para>
|
||||||
/// <para>设置目标</para>
|
/// <para>设置目标</para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private Node2D? Target { get; set; }
|
public Node2D? TargetNode { get; set; }
|
||||||
|
|
||||||
private List<IProjectileDecorator>? _projectileDecorators;
|
private List<IProjectileDecorator>? _projectileDecorators;
|
||||||
|
|
||||||
|
@ -100,6 +106,19 @@ public partial class Projectile : CharacterBody2D
|
||||||
//Platform collision layer is not allowed to collide
|
//Platform collision layer is not allowed to collide
|
||||||
//平台碰撞层不可碰撞
|
//平台碰撞层不可碰撞
|
||||||
SetCollisionMaskValue(Config.LayerNumber.Platform, false);
|
SetCollisionMaskValue(Config.LayerNumber.Platform, false);
|
||||||
|
if (TargetNode != null)
|
||||||
|
{
|
||||||
|
TargetNode.TreeExiting += () =>
|
||||||
|
{
|
||||||
|
//Clear the trace when the target is destroyed.
|
||||||
|
//在目标被销毁的时候清空跟踪。
|
||||||
|
TargetNode = null;
|
||||||
|
if (_targetDiesDestroyProjectile)
|
||||||
|
{
|
||||||
|
OnTimeOut();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -290,13 +309,13 @@ public partial class Projectile : CharacterBody2D
|
||||||
{
|
{
|
||||||
//No collision.
|
//No collision.
|
||||||
//没有撞到任何东西。
|
//没有撞到任何东西。
|
||||||
if (_enableTracking && Target != null)
|
if (_enableTracking && TargetNode != null)
|
||||||
{
|
{
|
||||||
//Track the target
|
//Track the target
|
||||||
//追踪目标
|
//追踪目标
|
||||||
//Gets a vector of the projectile pointing at the enemy's position.
|
//Gets a vector of the projectile pointing at the enemy's position.
|
||||||
//得到抛射体指向敌人位置的向量。
|
//得到抛射体指向敌人位置的向量。
|
||||||
var desiredVelocity = GlobalPosition.DirectionTo(Target.GlobalPosition) * Speed;
|
var desiredVelocity = GlobalPosition.DirectionTo(TargetNode.GlobalPosition) * Speed;
|
||||||
//The weight is smaller, the circle is larger.
|
//The weight is smaller, the circle is larger.
|
||||||
//weight越小,子弹绕的圈越大。
|
//weight越小,子弹绕的圈越大。
|
||||||
Velocity = Velocity.Lerp(desiredVelocity, 0.1f);
|
Velocity = Velocity.Lerp(desiredVelocity, 0.1f);
|
||||||
|
|
|
@ -169,6 +169,7 @@ public partial class ProjectileWeapon : WeaponTemplate
|
||||||
|
|
||||||
NodeUtils.CallDeferredAddChild(GameSceneNodeHolder.ProjectileContainer, projectile);
|
NodeUtils.CallDeferredAddChild(GameSceneNodeHolder.ProjectileContainer, projectile);
|
||||||
projectile.Owner = owner;
|
projectile.Owner = owner;
|
||||||
|
projectile.TargetNode = GameSceneNodeHolder.TemporaryTargetNode;
|
||||||
projectile.Velocity =
|
projectile.Velocity =
|
||||||
(_marker2D.GlobalPosition.DirectionTo(enemyGlobalPosition) * projectile.Speed)
|
(_marker2D.GlobalPosition.DirectionTo(enemyGlobalPosition) * projectile.Speed)
|
||||||
.Rotated(GetRandomAngle());
|
.Rotated(GetRandomAngle());
|
||||||
|
|
Loading…
Reference in New Issue
Block a user