近战攻击动画
1 parent 976d2ab commit c6a2bc5b2e15fc629afe1c863fd7ce237be0e361
@小李xl 小李xl authored on 13 Sep 2023
Showing 6 changed files
View
3
■■
DungeonShooting_Godot/prefab/role/Role0001.tscn
[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)
View
2
■■■
DungeonShooting_Godot/prefab/role/RoleTemplate.tscn
position = Vector2(0, -5)
shape = SubResource("RectangleShape2D_n68nu")
 
[node name="MountPoint" type="Marker2D" parent="."]
position = Vector2(1, -6)
position = Vector2(2, -8)
script = ExtResource("2_5ddpw")
View
65
DungeonShooting_Godot/src/game/activity/role/Role.cs
/// 互动区域碰撞器
/// </summary>
[Export, ExportFillNode]
public CollisionShape2D InteractiveCollision { get; set; }
 
/// <summary>
/// 武器挂载点是否始终指向目标
/// </summary>
public bool MountLookTarget { get; set; } = true;
/// <summary>
/// 脸的朝向
/// </summary>
/// <summary>
/// 是否可以翻滚
/// </summary>
public bool CanRoll => _rollCoolingTimer <= 0;
 
/// <summary>
/// 是否处于近战攻击中
/// </summary>
public bool IsMeleeAttack { get; private set; }
//翻滚冷却计时器
private float _rollCoolingTimer = 0;
//初始缩放
else if (pos.X < gPos.X && Face == FaceDirection.Right)
{
Face = FaceDirection.Left;
}
//枪口跟随目标
MountPoint.SetLookAt(pos);
 
if (MountLookTarget)
{
//枪口跟随目标
MountPoint.SetLookAt(pos);
}
}
//检查可互动的物体
bool findFlag = false;
/// <summary>
/// 使角色看向指定的坐标,
/// 注意, 调用该函数会清空 LookTarget, 因为拥有 LookTarget 时也会每帧更新玩家视野位置
/// </summary>
/// <param name="pos"></param>
public void LookTargetPosition(Vector2 pos)
{
LookTarget = null;
//脸的朝向
else if (pos.X < gPos.X && Face == FaceDirection.Right)
{
Face = FaceDirection.Left;
}
//枪口跟随目标
MountPoint.SetLookAt(pos);
 
if (MountLookTarget)
{
//枪口跟随目标
MountPoint.SetLookAt(pos);
}
}
/// <summary>
/// 判断指定坐标是否在角色视野方向
/// 触发攻击
/// </summary>
public virtual void Attack()
{
if (!IsMeleeAttack && WeaponPack.ActiveItem != null)
{
WeaponPack.ActiveItem.Trigger(this);
}
}
 
/// <summary>
/// 触发近战攻击
/// </summary>
public virtual void MeleeAttack()
{
if (IsMeleeAttack)
{
return;
}
 
if (WeaponPack.ActiveItem != null)
{
WeaponPack.ActiveItem.Trigger(this);
IsMeleeAttack = true;
WeaponPack.ActiveItem.TriggerMeleeAttack(this);
//播放近战动画
PlayAnimation_MeleeAttack(() =>
{
IsMeleeAttack = false;
});
}
}
 
/// <summary>
View
53
DungeonShooting_Godot/src/game/activity/role/Role_Animation.cs 0 → 100644
 
using System;
using Godot;
using Vector2 = Godot.Vector2;
 
public partial class Role
{
/// <summary>
/// 播放近战攻击动画
/// </summary>
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();
}
}
View
DungeonShooting_Godot/src/game/activity/role/player/Player.cs
View
DungeonShooting_Godot/src/game/activity/weapon/Weapon.cs