diff --git a/DungeonShooting_Godot/src/game/activity/bullet/explode/Explode.cs b/DungeonShooting_Godot/src/game/activity/bullet/explode/Explode.cs index 34cfd7f..c74d189 100644 --- a/DungeonShooting_Godot/src/game/activity/bullet/explode/Explode.cs +++ b/DungeonShooting_Godot/src/game/activity/bullet/explode/Explode.cs @@ -26,11 +26,6 @@ public CircleShape2D CircleShape { get; private set; } /// <summary> - /// 爆炸攻击的层级 - /// </summary> - public uint AttackLayer { get; private set; } - - /// <summary> /// 产生爆炸的子弹数据 /// </summary> public BulletData BulletData { get; private set; } @@ -40,7 +35,12 @@ private int _harm; private float _repelledRadius; private float _maxRepelled; - + + public override void _Ready() + { + CollisionMask = Role.AttackLayer; + } + public void Destroy() { if (IsDestroyed) @@ -56,12 +56,11 @@ /// 初始化爆炸数据 /// </summary> /// <param name="bulletData">产生爆炸的子弹数据</param> - /// <param name="attackLayer">攻击的层级</param> /// <param name="hitRadius">伤害半径</param> /// <param name="harm">造成的伤害</param> /// <param name="repelledRadius">击退半径</param> /// <param name="maxRepelled">最大击退速度</param> - public void Init(BulletData bulletData, uint attackLayer, float hitRadius, int harm, float repelledRadius, float maxRepelled) + public void Init(BulletData bulletData, float hitRadius, int harm, float repelledRadius, float maxRepelled) { if (!_init) { @@ -75,12 +74,10 @@ } BulletData = bulletData; - AttackLayer = attackLayer; _hitRadius = hitRadius; _harm = harm; _repelledRadius = repelledRadius; _maxRepelled = maxRepelled; - CollisionMask = attackLayer | PhysicsLayer.Prop | PhysicsLayer.Debris; CircleShape.Radius = Mathf.Max(hitRadius, maxRepelled); //冲击波 @@ -162,22 +159,22 @@ var len = temp.Length(); var angle = temp.Angle(); - if (len <= _hitRadius) //在伤害半径内 + var target = BulletData.TriggerRole.IsDestroyed ? null : BulletData.TriggerRole; + if (hurt.CanHurt(target)) { - var target = BulletData.TriggerRole.IsDestroyed ? null : BulletData.TriggerRole; - if (hurt.CanHurt(target)) + if (len <= _hitRadius) //在伤害半径内 { hurt.Hurt(target, _harm, angle); } - } - if (len <= _repelledRadius) //击退半径内 - { - var o = hurt.GetActivityObject(); - if (o != null) + if (len <= _repelledRadius) //击退半径内 { - var repelled = (_repelledRadius - len) / _repelledRadius * _maxRepelled; - o.AddRepelForce(Vector2.FromAngle(angle) * repelled); + var o = hurt.GetActivityObject(); + if (o != null) + { + var repelled = (_repelledRadius - len) / _repelledRadius * _maxRepelled; + o.AddRepelForce(Vector2.FromAngle(angle) * repelled); + } } } } diff --git a/DungeonShooting_Godot/src/game/activity/bullet/laser/Laser.cs b/DungeonShooting_Godot/src/game/activity/bullet/laser/Laser.cs index 70e2787..6870c12 100644 --- a/DungeonShooting_Godot/src/game/activity/bullet/laser/Laser.cs +++ b/DungeonShooting_Godot/src/game/activity/bullet/laser/Laser.cs @@ -24,18 +24,14 @@ public Sprite2D LineSprite { get; private set; } public RectangleShape2D Shape { get; private set; } + public CampEnum Camp { get; set; } + public event Action OnReclaimEvent; public event Action OnLeavePoolEvent; public bool IsRecycled { get; set; } public string Logotype { get; set; } - public uint AttackLayer - { - get => CollisionMask; - set => CollisionMask = value; - } - public BulletData BulletData { get; private set; } public BulletStateEnum State { get; protected set; } = BulletStateEnum.Normal; @@ -49,12 +45,17 @@ private Tween _tween; private bool _init = false; - public void InitData(BulletData data, uint attackLayer) + public override void _Ready() { - InitData(data, attackLayer, LaserDefaultWidth); + CollisionMask = Role.AttackLayer; } - public void InitData(BulletData data, uint attackLayer, float width) + public void InitData(BulletData data, CampEnum camp) + { + InitData(data, camp, LaserDefaultWidth); + } + + public void InitData(BulletData data, CampEnum camp, float width) { if (!_init) { @@ -70,9 +71,9 @@ _init = true; } + Camp = camp; ZIndex = 1; BulletData = data; - AttackLayer = attackLayer; Position = data.Position; Rotation = data.Rotation; @@ -103,7 +104,7 @@ LineSprite.Scale = new Vector2(0, width * _pixelScale); //如果子弹会对玩家造成伤害, 则显示成红色 - if (BulletData.World.Player.CollisionWithMask(attackLayer)) + if (BulletData.TriggerRole != null && BulletData.TriggerRole.IsEnemyWithPlayer()) { LineSprite.Modulate = new Color(2.5f, 0.5f, 0.5f); } @@ -191,7 +192,7 @@ bulletData.BounceCount -= 1; bulletData.MaxDistance = newDistance; bulletData.Rotation = rotation; - FireManager.ShootBullet(bulletData, AttackLayer); + FireManager.ShootBullet(bulletData, Camp); } } } @@ -214,19 +215,19 @@ private void HandlerCollision(IHurt hurt) { - if (BulletData.Repel != 0) - { - var o = hurt.GetActivityObject(); - if (o != null && o is not Player) //目标不是玩家才会触发击退 - { - o.AddRepelForce(Vector2.FromAngle(Rotation) * BulletData.Repel); - } - } - - //造成伤害 var target = BulletData.TriggerRole.IsDestroyed ? null : BulletData.TriggerRole; if (hurt.CanHurt(target)) { + if (BulletData.Repel != 0) + { + var o = hurt.GetActivityObject(); + if (o != null && o is not Player) //目标不是玩家才会触发击退 + { + o.AddRepelForce(Vector2.FromAngle(Rotation) * BulletData.Repel); + } + } + + //造成伤害 hurt.Hurt(target, BulletData.Harm, Rotation); } } diff --git a/DungeonShooting_Godot/src/game/activity/bullet/normal/Arrow.cs b/DungeonShooting_Godot/src/game/activity/bullet/normal/Arrow.cs index 3f1ad52..dc53286 100644 --- a/DungeonShooting_Godot/src/game/activity/bullet/normal/Arrow.cs +++ b/DungeonShooting_Godot/src/game/activity/bullet/normal/Arrow.cs @@ -10,9 +10,9 @@ [Export, ExportFillNode] public AnimatedSprite2D HalfSprite { get; set; } - public override void InitData(BulletData data, uint attackLayer) + public override void InitData(BulletData data, CampEnum camp) { - base.InitData(data, attackLayer); + base.InitData(data, camp); SetEnableMovement(true); EnableVerticalMotion = false; DefaultLayer = RoomLayerEnum.NormalLayer; diff --git a/DungeonShooting_Godot/src/game/activity/bullet/normal/BoomBullet.cs b/DungeonShooting_Godot/src/game/activity/bullet/normal/BoomBullet.cs index 79174e7..e2ea57e 100644 --- a/DungeonShooting_Godot/src/game/activity/bullet/normal/BoomBullet.cs +++ b/DungeonShooting_Godot/src/game/activity/bullet/normal/BoomBullet.cs @@ -59,7 +59,7 @@ explode.Position = pos; explode.RotationDegrees = Utils.Random.RandomRangeInt(0, 360); explode.AddToActivityRootDeferred(RoomLayerEnum.YSortLayer); - explode.Init(BulletData, AttackLayer, 25, BulletData.Harm, 50, BulletData.Repel); + explode.Init(BulletData, 25, BulletData.Harm, 50, BulletData.Repel); explode.RunPlay(BulletData.TriggerRole); if (AffiliationArea != null) { diff --git a/DungeonShooting_Godot/src/game/activity/bullet/normal/Bullet.cs b/DungeonShooting_Godot/src/game/activity/bullet/normal/Bullet.cs index 9b95710..c74ee7a 100644 --- a/DungeonShooting_Godot/src/game/activity/bullet/normal/Bullet.cs +++ b/DungeonShooting_Godot/src/game/activity/bullet/normal/Bullet.cs @@ -12,9 +12,12 @@ { public event Action OnReclaimEvent; public event Action OnLeavePoolEvent; + public bool IsRecycled { get; set; } public string Logotype { get; set; } + public CampEnum Camp { get; set; } + /// <summary> /// 子弹伤害碰撞区域 /// </summary> @@ -34,15 +37,6 @@ public Array<GpuParticles2D> Particles2D { get; set; } /// <summary> - /// 攻击的层级 - /// </summary> - public uint AttackLayer - { - get => CollisionArea.CollisionMask; - set => CollisionArea.CollisionMask = value; - } - - /// <summary> /// 子弹使用的数据 /// </summary> public BulletData BulletData { get; private set; } @@ -77,9 +71,11 @@ base.OnInit(); OutlineColor = new Color(2.5f, 0, 0); SetBlendColor(new Color(2.5f, 2.5f, 2.5f)); + + CollisionArea.CollisionMask = Role.AttackLayer; } - public virtual void InitData(BulletData data, uint attackLayer) + public virtual void InitData(BulletData data, CampEnum camp) { if (!_init) { @@ -87,13 +83,13 @@ CollisionArea.BodyEntered += OnBodyEntered; _init = true; } - + + Camp = camp; CurrentBounce = 0; CurrentPenetration = 0; CurrFlyDistance = 0; BulletData = data; - AttackLayer = attackLayer; Rotation = data.Rotation; var triggerRole = data.TriggerRole; @@ -120,7 +116,7 @@ MoveController.AddForce(new Vector2(data.FlySpeed, 0).Rotated(Rotation)); //如果子弹会对玩家造成伤害, 则显示红色描边 - if (World.Player != null && World.Player.CollisionWithMask(attackLayer)) + if (triggerRole != null && triggerRole.IsEnemyWithPlayer()) { if (!IsEnemyBullet) { @@ -193,29 +189,29 @@ /// </summary> public virtual void OnCollisionTarget(IHurt hurt) { - OnPlayDisappearEffect(); - if (BulletData.Repel != 0) - { - var o = hurt.GetActivityObject(); - if (o != null && o is not Player) //目标不是玩家才会触发击退 - { - o.AddRepelForce(Velocity.Normalized() * BulletData.Repel); - } - } - - //造成伤害 var target = BulletData.TriggerRole.IsDestroyed ? null : BulletData.TriggerRole; if (hurt.CanHurt(target)) { + OnPlayDisappearEffect(); + if (BulletData.Repel != 0) + { + var o = hurt.GetActivityObject(); + if (o != null && o is not Player) //目标不是玩家才会触发击退 + { + o.AddRepelForce(Velocity.Normalized() * BulletData.Repel); + } + } + + //造成伤害 hurt.Hurt(target, BulletData.Harm, Rotation); - } - - //穿透次数 - CurrentPenetration++; - if (CurrentPenetration > BulletData.Penetration) - { - State = BulletStateEnum.CollisionTarget; - CallDeferred(nameof(LogicalFinish)); + + //穿透次数 + CurrentPenetration++; + if (CurrentPenetration > BulletData.Penetration) + { + State = BulletStateEnum.CollisionTarget; + CallDeferred(nameof(LogicalFinish)); + } } } diff --git a/DungeonShooting_Godot/src/game/activity/bullet/normal/IBullet.cs b/DungeonShooting_Godot/src/game/activity/bullet/normal/IBullet.cs index a642541..0e2df83 100644 --- a/DungeonShooting_Godot/src/game/activity/bullet/normal/IBullet.cs +++ b/DungeonShooting_Godot/src/game/activity/bullet/normal/IBullet.cs @@ -14,9 +14,10 @@ event Action OnLeavePoolEvent; /// <summary> - /// 攻击的层级 + /// 子弹所在阵营 /// </summary> - uint AttackLayer { get; set; } + CampEnum Camp { get; set; } + /// <summary> /// 子弹数据 /// </summary> @@ -30,7 +31,8 @@ /// <summary> /// 初始化子弹数据 /// </summary> - void InitData(BulletData data, uint attackLayer); + void InitData(BulletData data, CampEnum camp); + /// <summary> /// 子弹运行逻辑执行完成 /// </summary> diff --git a/DungeonShooting_Godot/src/game/activity/bullet/normal/TrailBullet.cs b/DungeonShooting_Godot/src/game/activity/bullet/normal/TrailBullet.cs index 67f6da9..d459b56 100644 --- a/DungeonShooting_Godot/src/game/activity/bullet/normal/TrailBullet.cs +++ b/DungeonShooting_Godot/src/game/activity/bullet/normal/TrailBullet.cs @@ -8,9 +8,9 @@ private static Color EnemyTerrainColor = new Color(1.5f, 0, 0, 0.7f); private Trail trail; - public override void InitData(BulletData data, uint attackLayer) + public override void InitData(BulletData data, CampEnum camp) { - base.InitData(data, attackLayer); + base.InitData(data, camp); trail = ObjectManager.GetPoolItem<Trail>(ResourcePath.prefab_effect_common_Trail0001_tscn); trail.SetTarget(AnimatedSprite); diff --git a/DungeonShooting_Godot/src/game/activity/role/Role.cs b/DungeonShooting_Godot/src/game/activity/role/Role.cs index 01ff94c..246dafc 100644 --- a/DungeonShooting_Godot/src/game/activity/role/Role.cs +++ b/DungeonShooting_Godot/src/game/activity/role/Role.cs @@ -1001,6 +1001,19 @@ return true; } + + /// <summary> + /// 返回指定阵营是否是敌人 + /// </summary> + public bool IsEnemy(CampEnum otherCamp) + { + if (otherCamp == Camp || otherCamp == CampEnum.Peace || Camp == CampEnum.Peace) + { + return false; + } + + return true; + } /// <summary> /// 是否是玩家的敌人 @@ -1399,8 +1412,7 @@ } else if (body is Bullet bullet) //攻击子弹 { - var attackLayer = bullet.AttackLayer; - if (CollisionWithMask(attackLayer)) //是攻击玩家的子弹 + if (IsEnemy(bullet.BulletData.TriggerRole)) { bullet.OnPlayDisappearEffect(); bullet.Destroy(); @@ -1410,22 +1422,22 @@ private void HandlerCollision(IHurt hurt, Weapon activeWeapon) { - var damage = Utils.Random.RandomConfigRange(activeWeapon.Attribute.MeleeAttackHarmRange); - damage = RoleState.CalcDamage(damage); - - var o = hurt.GetActivityObject(); - var pos = hurt.GetPosition(); - if (o != null && o is not Player) //不是玩家才能被击退 - { - var attr = IsAi ? activeWeapon.AiUseAttribute : activeWeapon.PlayerUseAttribute; - var repel = Utils.Random.RandomConfigRange(attr.MeleeAttackRepelRange); - var position = pos - MountPoint.GlobalPosition; - var v2 = position.Normalized() * repel; - o.AddRepelForce(v2); - } - if (hurt.CanHurt(this)) { + var damage = Utils.Random.RandomConfigRange(activeWeapon.Attribute.MeleeAttackHarmRange); + damage = RoleState.CalcDamage(damage); + + var o = hurt.GetActivityObject(); + var pos = hurt.GetPosition(); + if (o != null && o is not Player) //不是玩家才能被击退 + { + var attr = IsAi ? activeWeapon.AiUseAttribute : activeWeapon.PlayerUseAttribute; + var repel = Utils.Random.RandomConfigRange(attr.MeleeAttackRepelRange); + var position = pos - MountPoint.GlobalPosition; + var v2 = position.Normalized() * repel; + o.AddRepelForce(v2); + } + hurt.Hurt(this, damage, (pos - GlobalPosition).Angle()); } } diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/NoWeaponEnemy.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/NoWeaponEnemy.cs index 89d9ccc..3dd5f63 100644 --- a/DungeonShooting_Godot/src/game/activity/role/enemy/NoWeaponEnemy.cs +++ b/DungeonShooting_Godot/src/game/activity/role/enemy/NoWeaponEnemy.cs @@ -56,7 +56,7 @@ var data = bulletData.Clone(); var tempPos = new Vector2(targetPosition.X + Utils.Random.RandomRangeInt(-30, 30), targetPosition.Y + Utils.Random.RandomRangeInt(-30, 30)); FireManager.SetParabolaTarget(data, tempPos); - FireManager.ShootBullet(data, AttackLayer); + FireManager.ShootBullet(data, Camp); } } diff --git a/DungeonShooting_Godot/src/game/activity/weapon/Weapon.cs b/DungeonShooting_Godot/src/game/activity/weapon/Weapon.cs index 065bced..e3378db 100644 --- a/DungeonShooting_Godot/src/game/activity/weapon/Weapon.cs +++ b/DungeonShooting_Godot/src/game/activity/weapon/Weapon.cs @@ -27,11 +27,6 @@ private ExcelConfig.WeaponBase _playerWeaponAttribute; private ExcelConfig.WeaponBase _aiWeaponAttribute; - /// <summary> - /// 攻击目标层级 - /// </summary> - public uint AttackLayer => Role.AttackLayer; - public Role Master { get; set; } public int PackageIndex { get; set; } = -1; diff --git a/DungeonShooting_Godot/src/game/activity/weapon/knife/Knife.cs b/DungeonShooting_Godot/src/game/activity/weapon/knife/Knife.cs index 11f51c7..aae6cb9 100644 --- a/DungeonShooting_Godot/src/game/activity/weapon/knife/Knife.cs +++ b/DungeonShooting_Godot/src/game/activity/weapon/knife/Knife.cs @@ -26,7 +26,7 @@ public override void OnInit() { base.OnInit(); - + //没有Master时不能触发开火 NoMasterCanTrigger = false; _hitArea = GetNode<Area2D>("HitArea"); @@ -40,6 +40,9 @@ _hitArea.Monitorable = false; _hitArea.BodyEntered += OnBodyEntered; _hitArea.AreaEntered += OnArea2dEntered; + + //更新碰撞层级 + _hitArea.CollisionMask = Role.AttackLayer | PhysicsLayer.Bullet; //禁用自动播放动画 IsAutoPlaySpriteFrames = false; @@ -74,8 +77,6 @@ protected override void OnFire() { Debug.Log("近战武器攻击! 蓄力时长: " + GetTriggerChargeTime() + ", 扳机按下时长: " + GetTriggerDownTime()); - //更新碰撞层级 - _hitArea.CollisionMask = AttackLayer | PhysicsLayer.Bullet; //启用碰撞 _hitArea.Monitoring = true; _attackIndex = 0; @@ -130,8 +131,7 @@ } else if (body is Bullet bullet) //攻击子弹 { - var attackLayer = bullet.AttackLayer; - if (TriggerRole != null && TriggerRole.CollisionWithMask(attackLayer)) //是攻击玩家的子弹 + if (TriggerRole != null && TriggerRole.IsEnemy(bullet.BulletData.TriggerRole)) { //反弹子弹 bullet.OnPlayDisappearEffect(); @@ -143,6 +143,7 @@ } bullet.MoveController.ScaleAllVelocity(scale); bullet.Rotation += Mathf.Pi; + bullet.Camp = Master.Camp; bullet.RefreshBulletColor(false); } } @@ -158,44 +159,44 @@ private void HandlerCollision(IHurt hurt) { - var damage = Utils.Random.RandomConfigRange(Attribute.Bullet.HarmRange); - //计算子弹造成的伤害 - if (TriggerRole != null) - { - damage = TriggerRole.RoleState.CalcDamage(damage); - } - //击退 - var attr = GetUseAttribute(TriggerRole); - var repel = Utils.Random.RandomConfigRange(attr.Bullet.RepelRange); - //计算击退 - if (TriggerRole != null) - { - repel = TriggerRole.RoleState.CalcBulletRepel(repel); - } - - var globalPosition = GlobalPosition; - if (repel != 0) - { - var o = hurt.GetActivityObject(); - if (o != null && o is not Player) //不是玩家才能被击退 - { - Vector2 position; - if (TriggerRole != null) - { - position = o.GlobalPosition - TriggerRole.MountPoint.GlobalPosition; - } - else - { - position = o.GlobalPosition - globalPosition; - } - var v2 = position.Normalized() * repel; - o.AddRepelForce(v2); - } - } - - //造成伤害 if (hurt.CanHurt(TriggerRole)) { + var damage = Utils.Random.RandomConfigRange(Attribute.Bullet.HarmRange); + //计算子弹造成的伤害 + if (TriggerRole != null) + { + damage = TriggerRole.RoleState.CalcDamage(damage); + } + //击退 + var attr = GetUseAttribute(TriggerRole); + var repel = Utils.Random.RandomConfigRange(attr.Bullet.RepelRange); + //计算击退 + if (TriggerRole != null) + { + repel = TriggerRole.RoleState.CalcBulletRepel(repel); + } + + var globalPosition = GlobalPosition; + if (repel != 0) + { + var o = hurt.GetActivityObject(); + if (o != null && o is not Player) //不是玩家才能被击退 + { + Vector2 position; + if (TriggerRole != null) + { + position = o.GlobalPosition - TriggerRole.MountPoint.GlobalPosition; + } + else + { + position = o.GlobalPosition - globalPosition; + } + var v2 = position.Normalized() * repel; + o.AddRepelForce(v2); + } + } + + //造成伤害 hurt.Hurt(TriggerRole, damage, (hurt.GetPosition() - globalPosition).Angle()); } } diff --git a/DungeonShooting_Godot/src/game/manager/FireManager.cs b/DungeonShooting_Godot/src/game/manager/FireManager.cs index a941ca2..db692a7 100644 --- a/DungeonShooting_Godot/src/game/manager/FireManager.cs +++ b/DungeonShooting_Godot/src/game/manager/FireManager.cs @@ -97,11 +97,13 @@ { if (bullet.Type == 1) //实体子弹 { - return ShootSolidBullet(CreateSolidBulletData(weapon, fireRotation, bullet), weapon.AttackLayer); + return ShootSolidBullet(CreateSolidBulletData(weapon, fireRotation, bullet), + weapon.TriggerRole != null ? weapon.TriggerRole.Camp : CampEnum.None); } else if (bullet.Type == 2) //激光子弹 { - return ShootLaser(CreateLaserData(weapon, fireRotation, bullet), weapon.AttackLayer); + return ShootLaser(CreateLaserData(weapon, fireRotation, bullet), + weapon.TriggerRole != null ? weapon.TriggerRole.Camp : CampEnum.None); } else { @@ -118,7 +120,7 @@ { if (bullet.Type == 1) //实体子弹 { - return ShootSolidBullet(CreateSolidBulletData(trigger, fireRotation, bullet), Role.AttackLayer); + return ShootSolidBullet(CreateSolidBulletData(trigger, fireRotation, bullet), trigger.Camp); } return null; @@ -127,15 +129,15 @@ /// <summary> /// 通过 BulletData 直接发射子弹 /// </summary> - public static IBullet ShootBullet(BulletData bulletData, uint attackLayer) + public static IBullet ShootBullet(BulletData bulletData, CampEnum camp) { if (bulletData.BulletBase.Type == 1) //实体子弹 { - return ShootSolidBullet(bulletData, attackLayer); + return ShootSolidBullet(bulletData, camp); } else if (bulletData.BulletBase.Type == 2) //激光子弹 { - return ShootLaser(bulletData, attackLayer); + return ShootLaser(bulletData, camp); } else { @@ -148,23 +150,23 @@ /// <summary> /// 发射子弹的默认实现方式 /// </summary> - private static Bullet ShootSolidBullet(BulletData bulletData, uint attackLayer) + private static Bullet ShootSolidBullet(BulletData bulletData, CampEnum camp) { //创建子弹 var bulletInstance = ObjectManager.GetBullet(bulletData.BulletBase.Prefab); - bulletInstance.InitData(bulletData, attackLayer); + bulletInstance.InitData(bulletData, camp); return bulletInstance; } /// <summary> /// 发射射线的默认实现方式 /// </summary> - private static Laser ShootLaser(BulletData bulletData, uint attackLayer) + private static Laser ShootLaser(BulletData bulletData, CampEnum camp) { //创建激光 var laser = ObjectManager.GetLaser(bulletData.BulletBase.Prefab); laser.AddToActivityRoot(RoomLayerEnum.YSortLayer); - laser.InitData(bulletData, attackLayer, Laser.LaserDefaultWidth); + laser.InitData(bulletData, camp, Laser.LaserDefaultWidth); return laser; }