diff --git a/DungeonShooting_Godot/prefab/role/Role0001.tscn b/DungeonShooting_Godot/prefab/role/Role0001.tscn index 196f400..b8e436d 100644 --- a/DungeonShooting_Godot/prefab/role/Role0001.tscn +++ b/DungeonShooting_Godot/prefab/role/Role0001.tscn @@ -44,6 +44,3 @@ [node name="AnimatedSprite" parent="." index="2"] material = SubResource("ShaderMaterial_8hgu2") sprite_frames = ExtResource("4_galcc") - -[node name="MountPoint" parent="." index="6"] -position = Vector2(2, -8) diff --git a/DungeonShooting_Godot/prefab/role/RoleTemplate.tscn b/DungeonShooting_Godot/prefab/role/RoleTemplate.tscn index d55de02..2217fee 100644 --- a/DungeonShooting_Godot/prefab/role/RoleTemplate.tscn +++ b/DungeonShooting_Godot/prefab/role/RoleTemplate.tscn @@ -69,5 +69,5 @@ shape = SubResource("RectangleShape2D_n68nu") [node name="MountPoint" type="Marker2D" parent="."] -position = Vector2(1, -6) +position = Vector2(2, -8) script = ExtResource("2_5ddpw") diff --git a/DungeonShooting_Godot/src/game/activity/role/Role.cs b/DungeonShooting_Godot/src/game/activity/role/Role.cs index 034de62..c2ce92b 100644 --- a/DungeonShooting_Godot/src/game/activity/role/Role.cs +++ b/DungeonShooting_Godot/src/game/activity/role/Role.cs @@ -81,6 +81,11 @@ /// [Export, ExportFillNode] public CollisionShape2D InteractiveCollision { get; set; } + + /// + /// 武器挂载点是否始终指向目标 + /// + public bool MountLookTarget { get; set; } = true; /// /// 脸的朝向 @@ -226,6 +231,11 @@ /// 是否可以翻滚 /// public bool CanRoll => _rollCoolingTimer <= 0; + + /// + /// 是否处于近战攻击中 + /// + public bool IsMeleeAttack { get; private set; } //翻滚冷却计时器 private float _rollCoolingTimer = 0; @@ -409,8 +419,12 @@ { Face = FaceDirection.Left; } - //枪口跟随目标 - MountPoint.SetLookAt(pos); + + if (MountLookTarget) + { + //枪口跟随目标 + MountPoint.SetLookAt(pos); + } } //检查可互动的物体 @@ -582,7 +596,6 @@ /// 使角色看向指定的坐标, /// 注意, 调用该函数会清空 LookTarget, 因为拥有 LookTarget 时也会每帧更新玩家视野位置 /// - /// public void LookTargetPosition(Vector2 pos) { LookTarget = null; @@ -596,8 +609,12 @@ { Face = FaceDirection.Left; } - //枪口跟随目标 - MountPoint.SetLookAt(pos); + + if (MountLookTarget) + { + //枪口跟随目标 + MountPoint.SetLookAt(pos); + } } /// @@ -866,13 +883,35 @@ /// public virtual void Attack() { - if (WeaponPack.ActiveItem != null) + if (!IsMeleeAttack && WeaponPack.ActiveItem != null) { WeaponPack.ActiveItem.Trigger(this); } } /// + /// 触发近战攻击 + /// + public virtual void MeleeAttack() + { + if (IsMeleeAttack) + { + return; + } + + if (WeaponPack.ActiveItem != null) + { + IsMeleeAttack = true; + WeaponPack.ActiveItem.TriggerMeleeAttack(this); + //播放近战动画 + PlayAnimation_MeleeAttack(() => + { + IsMeleeAttack = false; + }); + } + } + + /// /// 触发使用道具 /// public virtual void UseActiveProp() diff --git a/DungeonShooting_Godot/src/game/activity/role/Role_Animation.cs b/DungeonShooting_Godot/src/game/activity/role/Role_Animation.cs new file mode 100644 index 0000000..fc3e853 --- /dev/null +++ b/DungeonShooting_Godot/src/game/activity/role/Role_Animation.cs @@ -0,0 +1,53 @@ + +using System; +using Godot; +using Vector2 = Godot.Vector2; + +public partial class Role +{ + /// + /// 播放近战攻击动画 + /// + public virtual void PlayAnimation_MeleeAttack(Action finish) + { + MountLookTarget = false; + var r = MountPoint.RotationDegrees; + var p1 = MountPoint.Position; + var p2 = p1 + new Vector2(6, 0).Rotated(Mathf.DegToRad(r - 60)); + var p3 = p1 + new Vector2(6, 0).Rotated(Mathf.DegToRad(r + 60)); + + var tween = CreateTween(); + tween.SetParallel(); + + tween.TweenProperty(MountPoint, "rotation_degrees", r - 60, 0.15); + tween.TweenProperty(MountPoint, "position", p2, 0.15); + tween.Chain(); + + tween.TweenCallback(Callable.From(() => + { + MountPoint.RotationDegrees = r + 60; + MountPoint.Position = p3; + //创建屏幕抖动 + if (Face == FaceDirection.Right) + { + GameCamera.Main.DirectionalShake(Vector2.FromAngle(Mathf.DegToRad(r - 90)) * 5); + } + else + { + GameCamera.Main.DirectionalShake(Vector2.FromAngle(Mathf.DegToRad(270 - r)) * 5); + } + })); + tween.Chain(); + + tween.TweenProperty(MountPoint, "rotation_degrees", r, 0.3); + tween.TweenProperty(MountPoint, "position", p1, 0.3); + tween.Chain(); + + tween.TweenCallback(Callable.From(() => + { + MountLookTarget = true; + finish(); + })); + tween.Play(); + } +} \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/activity/role/player/Player.cs b/DungeonShooting_Godot/src/game/activity/role/player/Player.cs index 89e806c..0227a42 100644 --- a/DungeonShooting_Godot/src/game/activity/role/player/Player.cs +++ b/DungeonShooting_Godot/src/game/activity/role/player/Player.cs @@ -84,8 +84,12 @@ { Face = FaceDirection.Left; } - //枪口跟随鼠标 - MountPoint.SetLookAt(mousePos); + + if (MountLookTarget) + { + //枪口跟随鼠标 + MountPoint.SetLookAt(mousePos); + } } if (InputManager.ExchangeWeapon) //切换武器 @@ -121,7 +125,14 @@ Reload(); } - if (InputManager.Fire) //开火 + if (InputManager.MeleeAttack) //近战攻击 + { + if (StateController.CurrState != PlayerStateEnum.Roll) //不能是翻滚状态 + { + MeleeAttack(); + } + } + else if (InputManager.Fire) //正常开火 { if (StateController.CurrState != PlayerStateEnum.Roll) //不能是翻滚状态 { diff --git a/DungeonShooting_Godot/src/game/activity/weapon/Weapon.cs b/DungeonShooting_Godot/src/game/activity/weapon/Weapon.cs index f8d877d..5ec5fd3 100644 --- a/DungeonShooting_Godot/src/game/activity/weapon/Weapon.cs +++ b/DungeonShooting_Godot/src/game/activity/weapon/Weapon.cs @@ -981,6 +981,14 @@ } /// + /// 触发武器的近战攻击 + /// + public void TriggerMeleeAttack(Role trigger) + { + + } + + /// /// 获取武器攻击的目标层级 /// ///