diff --git a/DungeonShooting_Godot/prefab/role/Enemy.tscn b/DungeonShooting_Godot/prefab/role/Enemy.tscn index afc628f..c4fd32f 100644 --- a/DungeonShooting_Godot/prefab/role/Enemy.tscn +++ b/DungeonShooting_Godot/prefab/role/Enemy.tscn @@ -23,7 +23,7 @@ [node name="AnimatedSprite" parent="." index="2"] material = SubResource( 2 ) -frame = 3 +frame = 0 [node name="ViewRay" type="RayCast2D" parent="." index="7"] position = Vector2( 0, -8 ) diff --git a/DungeonShooting_Godot/prefab/role/Role.tscn b/DungeonShooting_Godot/prefab/role/Role.tscn index 28ad803..4fd8304 100644 --- a/DungeonShooting_Godot/prefab/role/Role.tscn +++ b/DungeonShooting_Godot/prefab/role/Role.tscn @@ -129,7 +129,7 @@ position = Vector2( 0, -12 ) frames = SubResource( 6 ) animation = "idle" -frame = 1 +frame = 3 playing = true [node name="Collision" type="CollisionShape2D" parent="."] diff --git a/DungeonShooting_Godot/src/game/item/weapon/Weapon.cs b/DungeonShooting_Godot/src/game/item/weapon/Weapon.cs index d2619ed..438910a 100644 --- a/DungeonShooting_Godot/src/game/item/weapon/Weapon.cs +++ b/DungeonShooting_Godot/src/game/item/weapon/Weapon.cs @@ -17,7 +17,7 @@ public event Action FireEvent; /// - /// 属性数据 + /// 武器属性数据 /// public WeaponAttribute Attribute { get; private set; } @@ -101,6 +101,27 @@ } } + /// + /// 返回是否在蓄力中, + /// 注意, 属性仅在 Attribute.LooseShoot == false 时有正确的返回值, 否则返回 false + /// + public bool IsCharging => _looseShootFlag; + + /// + /// 返回武器是否在武器袋中 + /// + public bool IsInHolster => Master != null; + + /// + /// 返回是否真正使用该武器 + /// + public bool IsActive => Master != null && Master.Holster.ActiveWeapon == this; + + + + + //-------------------------------------------------------------------------------------------- + //是否按下 private bool _triggerFlag = false; @@ -142,6 +163,9 @@ //是否需要重置武器数据 private bool _dirtyFlag = false; + + //当前后坐力导致的偏移长度 + private float _currBacklashLength = 0; /// /// 根据属性创建一把武器 @@ -206,6 +230,14 @@ } /// + /// 开始蓄力时调用, + /// 注意, 该函数仅在 Attribute.LooseShoot == false 时才能被调用 + /// + protected virtual void OnStartCharge() + { + } + + /// /// 当开始换弹时调用 /// protected virtual void OnReload() @@ -301,6 +333,28 @@ } } + // 攻击的计时器 + if (_attackTimer > 0) + { + _attackTimer -= delta; + if (_attackTimer < 0) + { + _delayedTime += _attackTimer; + _attackTimer = 0; + //枪口默认角度 + RotationDegrees = -Attribute.DefaultAngle; + } + } + else if (_delayedTime > 0) //攻击延时 + { + _delayedTime -= delta; + if (_attackTimer < 0) + { + _delayedTime = 0; + } + } + + //扳机判定 if (_triggerFlag) { if (_looseShootFlag) //蓄力时长 @@ -325,25 +379,6 @@ } } - // 攻击的计时器 - if (_attackTimer > 0) - { - _attackTimer -= delta; - if (_attackTimer < 0) - { - _delayedTime += _attackTimer; - _attackTimer = 0; - } - } - else if (_delayedTime > 0) //攻击延时 - { - _delayedTime -= delta; - if (_attackTimer < 0) - { - _delayedTime = 0; - } - } - //连发判断 if (!_looseShootFlag && _continuousCount > 0 && _delayedTime <= 0 && _attackTimer <= 0) { @@ -360,16 +395,17 @@ _triggerTimer = _triggerTimer > 0 ? _triggerTimer - delta : 0; _triggerFlag = false; _attackFlag = false; - + //武器身回归 - Position = Position.MoveToward(Vector2.Zero, 35 * delta); - if (_fireInterval == 0) + //Position = Position.MoveToward(Vector2.Zero, Attribute.BacklashRegressionSpeed * delta).Rotated(Rotation); + _currBacklashLength = Mathf.MoveToward(_currBacklashLength, 0, Attribute.BacklashRegressionSpeed * delta); + Position = new Vector2(_currBacklashLength, 0).Rotated(Rotation); + if (_attackTimer > 0) { - RotationDegrees = -Attribute.DefaultAngle; - } - else - { - RotationDegrees = Mathf.Lerp(-Attribute.DefaultAngle, _fireAngle, _attackTimer / _fireInterval); + RotationDegrees = Mathf.Lerp( + _fireAngle, -Attribute.DefaultAngle, + Mathf.Clamp((_fireInterval - _attackTimer) * Attribute.UpliftAngleRestore / _fireInterval, 0, 1) + ); } } } @@ -405,7 +441,7 @@ } else //半自动 { - if (justDown && _triggerTimer <= 0) + if (justDown && _triggerTimer <= 0 && _attackTimer <= 0) { flag = true; } @@ -455,6 +491,7 @@ if (Attribute.LooseShoot) //松发开火 { _looseShootFlag = true; + OnStartCharge(); } else { @@ -520,7 +557,14 @@ if (_looseShootFlag) { _looseShootFlag = false; - TriggerFire(); + if (_chargeTime >= Attribute.MinChargeTime) //判断蓄力是否够了 + { + TriggerFire(); + } + else //不能攻击 + { + _continuousCount = 0; + } _chargeTime = 0; } @@ -569,10 +613,14 @@ tempAngle -= Attribute.UpliftAngle; RotationDegrees = tempAngle; _fireAngle = tempAngle; + //武器身位置 - Position = new Vector2( - Mathf.Max(-Attribute.MaxBacklash, - Position.x - Utils.RandRange(Attribute.MinBacklash, Attribute.MaxBacklash)), Position.y); + var max = Mathf.Abs(Mathf.Max(Attribute.MaxBacklash, Attribute.MinBacklash)); + _currBacklashLength = Mathf.Clamp( + _currBacklashLength - Utils.RandRange(Attribute.MinBacklash, Attribute.MaxBacklash), + -max, max + ); + Position = new Vector2(_currBacklashLength, 0).Rotated(Rotation); if (FireEvent != null) { diff --git a/DungeonShooting_Godot/src/game/item/weapon/WeaponAttribute.cs b/DungeonShooting_Godot/src/game/item/weapon/WeaponAttribute.cs index 0de7747..4a6c8aa 100644 --- a/DungeonShooting_Godot/src/game/item/weapon/WeaponAttribute.cs +++ b/DungeonShooting_Godot/src/game/item/weapon/WeaponAttribute.cs @@ -58,6 +58,10 @@ /// public bool LooseShoot = false; /// + /// 最少需要蓄力多久才能开火, 必须将 'LooseShoot' 设置为 true + /// + public float MinChargeTime = 0f; + /// /// 连续发射最小次数, 仅当 ContinuousShoot 为 false 时生效 /// public int MinContinuousCount = 1; @@ -66,15 +70,15 @@ /// public int MaxContinuousCount = 1; /// - /// 按下一次扳机后需要多长时间才能再次按下 + /// 按下一次扳机后需要多长时间才能再次感应按下 /// public float TriggerInterval = 0; /// - /// 初始射速, 初始每秒分钟能发射多少发子弹 + /// 初始射速, 初始每分钟能开火次数 /// public float StartFiringSpeed = 300; /// - /// 最终射速, 最终每秒分钟能发射多少发子弹 + /// 最终射速, 最终每分钟能开火次数 /// public float FinalFiringSpeed = 300; /// @@ -146,6 +150,10 @@ /// public float MinBacklash = 2; /// + /// 后坐力偏移回归回归速度 + /// + public float BacklashRegressionSpeed = 35f; + /// /// 开火后武器口上抬角度 /// public float UpliftAngle = 30; @@ -156,5 +164,5 @@ /// /// 开火后武器口角度恢复速度倍数 /// - public float UpliftAngleRestore = 1; + public float UpliftAngleRestore = 1f; } \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/item/weapon/knife/Knife.cs b/DungeonShooting_Godot/src/game/item/weapon/knife/Knife.cs index 7388162..994cac5 100644 --- a/DungeonShooting_Godot/src/game/item/weapon/knife/Knife.cs +++ b/DungeonShooting_Godot/src/game/item/weapon/knife/Knife.cs @@ -4,29 +4,30 @@ [RegisterWeapon("1004", typeof(KnifeAttribute))] public class Knife : Weapon { - private class KnifeAttribute : WeaponAttribute { public KnifeAttribute() { Sprite = ResourcePath.resource_sprite_gun_knife1_png; WeaponPrefab = ResourcePath.prefab_weapon_Knife_tscn; - //连发关闭 + //攻速设置 + StartFiringSpeed = 180; + FinalFiringSpeed = StartFiringSpeed; + //关闭连发 ContinuousShoot = false; - //松发开火 + //设置成松发开火 LooseShoot = true; - //弹药量 + //弹药量, 可以理解为耐久度 AmmoCapacity = 180; - MaxAmmoCapacity = 180; + MaxAmmoCapacity = AmmoCapacity; //握把位置 HoldPosition = new Vector2(10, 0); - //关闭后坐力 - MaxBacklash = 0; - MinBacklash = 0; - //我们需要自己来控制角度 - UpliftAngleRestore = 3; - UpliftAngle = -80; - DefaultAngle = 20; + //后坐力改为向前, 模拟手伸长的效果 + MaxBacklash = -8; + MinBacklash = -8; + BacklashRegressionSpeed = 24; + //UpliftAngleRestore = 2; + UpliftAngle = -90; } } @@ -35,9 +36,26 @@ } + public override void _Process(float delta) + { + base._Process(delta); + + } + + protected override void OnStartCharge() + { + RotationDegrees = -120; + } + protected override void OnFire() { GD.Print("蓄力时长: " + GetTriggerChargeTime() + ", 扳机按下时长: " + GetTriggerDownTime()); + + if (Master == GameApplication.Instance.Room.Player) + { + //创建抖动 + //GameCamera.Main.ProcessDirectionalShake(Vector2.Right.Rotated(GlobalRotation - Mathf.Pi * 0.5f) * 1.5f); + } } protected override void OnShoot(float fireRotation) diff --git a/DungeonShooting_Godot/src/game/role/MountRotation.cs b/DungeonShooting_Godot/src/game/role/MountRotation.cs index 2d09637..8cd9054 100644 --- a/DungeonShooting_Godot/src/game/role/MountRotation.cs +++ b/DungeonShooting_Godot/src/game/role/MountRotation.cs @@ -17,14 +17,13 @@ public Role Master { get; set; } /// - /// 当前节点真实的旋转角度 + /// 当前节点真实的旋转角度, 角度制 /// public float RealAngle { get; private set; } /// /// 设置看向的目标点 /// - /// public void SetLookAt(Vector2 target) { var myPos = GlobalPosition;