diff --git a/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs b/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs
index eef5518..b4bfe60 100644
--- a/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs
+++ b/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs
@@ -1735,6 +1735,6 @@
///
public Vector2 GetCenterPosition()
{
- return AnimatedSprite.GlobalPosition + AnimatedSprite.Offset;
+ return AnimatedSprite.Position + Position;
}
}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/activity/role/AdvancedRole.cs b/DungeonShooting_Godot/src/game/activity/role/AdvancedRole.cs
index ceaad7e..c1350c1 100644
--- a/DungeonShooting_Godot/src/game/activity/role/AdvancedRole.cs
+++ b/DungeonShooting_Godot/src/game/activity/role/AdvancedRole.cs
@@ -326,7 +326,7 @@
//WeaponPack.ActiveItem.TriggerMeleeAttack(this);
//播放近战动画
- this.PlayAnimation_MeleeAttack(() =>
+ PlayAnimation_MeleeAttack(() =>
{
MountLookTarget = true;
IsMeleeAttack = false;
@@ -399,21 +399,6 @@
return -MountPoint.Position.Y;
}
- public override float GetAttackRotation()
- {
- return MountPoint.RealRotation;
- }
-
- public override Vector2 GetMountPosition()
- {
- return MountPoint.GlobalPosition;
- }
-
- public override Node2D GetMountNode()
- {
- return MountPoint;
- }
-
protected override void OnDestroy()
{
base.OnDestroy();
diff --git a/DungeonShooting_Godot/src/game/activity/role/AdvancedRole_Animation.cs b/DungeonShooting_Godot/src/game/activity/role/AdvancedRole_Animation.cs
new file mode 100644
index 0000000..e829a1f
--- /dev/null
+++ b/DungeonShooting_Godot/src/game/activity/role/AdvancedRole_Animation.cs
@@ -0,0 +1,78 @@
+
+using System;
+using Godot;
+using Vector2 = Godot.Vector2;
+
+public partial class AdvancedRole
+{
+ ///
+ /// 播放近战攻击动画
+ ///
+ public virtual void PlayAnimation_MeleeAttack(Action finish)
+ {
+ var r = MountPoint.RotationDegrees;
+ //var gp = MountPoint.GlobalPosition;
+ var p1 = MountPoint.Position;
+ var p2 = p1 + new Vector2(6, 0).Rotated(Mathf.DegToRad(r - MeleeAttackAngle / 2f));
+ var p3 = p1 + new Vector2(6, 0).Rotated(Mathf.DegToRad(r + MeleeAttackAngle / 2f));
+
+ var tween = CreateTween();
+ tween.SetParallel();
+
+ tween.TweenProperty(MountPoint, "rotation_degrees", r - MeleeAttackAngle / 2f, 0.1);
+ tween.TweenProperty(MountPoint, "position", p2, 0.1);
+ tween.TweenProperty(MountPoint, "position", p2, 0.1);
+ tween.Chain();
+
+ tween.TweenCallback(Callable.From(() =>
+ {
+ MountPoint.RotationDegrees = r + MeleeAttackAngle / 2f;
+ MountPoint.Position = p3;
+ //重新计算武器阴影位置
+ var activeItem = WeaponPack.ActiveItem;
+ activeItem.CalcShadowTransform();
+ //创建屏幕抖动
+ if (Face == FaceDirection.Right)
+ {
+ //GameCamera.Main.DirectionalShake(Vector2.FromAngle(Mathf.DegToRad(r - 90)) * 5);
+ GameCamera.Main.DirectionalShake(Vector2.FromAngle(Mathf.DegToRad(r - 180)) * 6);
+ }
+ else
+ {
+ //GameCamera.Main.DirectionalShake(Vector2.FromAngle(Mathf.DegToRad(270 - r)) * 5);
+ GameCamera.Main.DirectionalShake(Vector2.FromAngle(Mathf.DegToRad(-r)) * 6);
+ }
+ //播放特效
+ var effect = ObjectManager.GetPoolItem(ResourcePath.prefab_effect_weapon_MeleeAttack1_tscn);
+ var sprite = (Node2D)effect;
+ var localFirePosition = activeItem.GetLocalFirePosition() - activeItem.GripPoint.Position;
+ localFirePosition *= 0.9f;
+ sprite.Position = p1 + localFirePosition.Rotated(Mathf.DegToRad(r));
+ sprite.RotationDegrees = r;
+ AddChild(sprite);
+ effect.PlayEffect();
+
+ //启用近战碰撞区域
+ MeleeAttackCollision.Disabled = false;
+ }));
+ tween.Chain();
+
+ tween.TweenInterval(0.1f);
+ tween.Chain();
+
+ tween.TweenCallback(Callable.From(() =>
+ {
+ //关闭近战碰撞区域
+ MeleeAttackCollision.Disabled = true;
+ }));
+ tween.TweenProperty(MountPoint, "rotation_degrees", r, 0.2);
+ tween.TweenProperty(MountPoint, "position", p1, 0.2);
+ tween.Chain();
+
+ tween.TweenCallback(Callable.From(() =>
+ {
+ finish();
+ }));
+ tween.Play();
+ }
+}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/activity/role/Role.cs b/DungeonShooting_Godot/src/game/activity/role/Role.cs
index a63cc35..fcea8b0 100644
--- a/DungeonShooting_Godot/src/game/activity/role/Role.cs
+++ b/DungeonShooting_Godot/src/game/activity/role/Role.cs
@@ -737,15 +737,7 @@
// blood.Rotation = angle;
// GameApplication.Instance.Node3D.GetRoot().AddChild(blood);
}
-
- if (target == null || target.IsDestroyed)
- {
- OnHit(null, damage, angle, !flag);
- }
- else
- {
- OnHit(target, damage, angle, !flag);
- }
+ OnHit(target, damage, angle, !flag);
//受伤特效
PlayHitAnimation();
@@ -894,30 +886,6 @@
{
return -AnimatedSprite.Position.Y;
}
-
- ///
- /// 获取攻击标角度, 弧度制
- ///
- public virtual float GetAttackRotation()
- {
- return GetCenterPosition().AngleTo(LookPosition);
- }
-
- ///
- /// 获取物品挂载点
- ///
- public virtual Vector2 GetMountPosition()
- {
- return AnimatedSprite.Position;
- }
-
- ///
- /// 获取物品挂载节点对象
- ///
- public virtual Node2D GetMountNode()
- {
- return AnimatedSprite;
- }
protected override void OnDestroy()
{
diff --git a/DungeonShooting_Godot/src/game/activity/role/RoleAnimation.cs b/DungeonShooting_Godot/src/game/activity/role/RoleAnimation.cs
deleted file mode 100644
index 227fb3f..0000000
--- a/DungeonShooting_Godot/src/game/activity/role/RoleAnimation.cs
+++ /dev/null
@@ -1,149 +0,0 @@
-
-using System;
-using Godot;
-using Vector2 = Godot.Vector2;
-
-public static class RoleAnimation
-{
- ///
- /// 播放近战攻击动画
- ///
- public static void PlayAnimation_MeleeAttack(this AdvancedRole role, Action finish)
- {
- var r = role.MountPoint.RotationDegrees;
- //var gp = MountPoint.GlobalPosition;
- var p1 = role.MountPoint.Position;
- var p2 = p1 + new Vector2(6, 0).Rotated(Mathf.DegToRad(r - role.MeleeAttackAngle / 2f));
- var p3 = p1 + new Vector2(6, 0).Rotated(Mathf.DegToRad(r + role.MeleeAttackAngle / 2f));
-
- var tween = role.CreateTween();
- tween.SetParallel();
-
- tween.TweenProperty(role.MountPoint, "rotation_degrees", r - role.MeleeAttackAngle / 2f, 0.1);
- tween.TweenProperty(role.MountPoint, "position", p2, 0.1);
- tween.TweenProperty(role.MountPoint, "position", p2, 0.1);
- tween.Chain();
-
- tween.TweenCallback(Callable.From(() =>
- {
- role.MountPoint.RotationDegrees = r + role.MeleeAttackAngle / 2f;
- role.MountPoint.Position = p3;
- //重新计算武器阴影位置
- var activeItem = role.WeaponPack.ActiveItem;
- activeItem.CalcShadowTransform();
- //创建屏幕抖动
- if (role.Face == FaceDirection.Right)
- {
- //GameCamera.Main.DirectionalShake(Vector2.FromAngle(Mathf.DegToRad(r - 90)) * 5);
- GameCamera.Main.DirectionalShake(Vector2.FromAngle(Mathf.DegToRad(r - 180)) * 6);
- }
- else
- {
- //GameCamera.Main.DirectionalShake(Vector2.FromAngle(Mathf.DegToRad(270 - r)) * 5);
- GameCamera.Main.DirectionalShake(Vector2.FromAngle(Mathf.DegToRad(-r)) * 6);
- }
- //播放特效
- var effect = ObjectManager.GetPoolItem(ResourcePath.prefab_effect_weapon_MeleeAttack1_tscn);
- var sprite = (Node2D)effect;
- var localFirePosition = activeItem.GetLocalFirePosition() - activeItem.GripPoint.Position;
- localFirePosition *= 0.9f;
- sprite.Position = p1 + localFirePosition.Rotated(Mathf.DegToRad(r));
- sprite.RotationDegrees = r;
- role.AddChild(sprite);
- effect.PlayEffect();
-
- //启用近战碰撞区域
- role.MeleeAttackCollision.Disabled = false;
- }));
- tween.Chain();
-
- tween.TweenInterval(0.1f);
- tween.Chain();
-
- tween.TweenCallback(Callable.From(() =>
- {
- //关闭近战碰撞区域
- role.MeleeAttackCollision.Disabled = true;
- }));
- tween.TweenProperty(role.MountPoint, "rotation_degrees", r, 0.2);
- tween.TweenProperty(role.MountPoint, "position", p1, 0.2);
- tween.Chain();
-
- tween.TweenCallback(Callable.From(() =>
- {
- finish();
- }));
- tween.Play();
- }
-
- ///
- /// 播放近战攻击动画
- ///
- public static void PlayAnimation_MeleeAttack(this AdvancedEnemy role, Action finish)
- {
- var r = role.MountPoint.RotationDegrees;
- //var gp = MountPoint.GlobalPosition;
- var p1 = role.MountPoint.Position;
- var p2 = p1 + new Vector2(6, 0).Rotated(Mathf.DegToRad(r - role.MeleeAttackAngle / 2f));
- var p3 = p1 + new Vector2(6, 0).Rotated(Mathf.DegToRad(r + role.MeleeAttackAngle / 2f));
-
- var tween = role.CreateTween();
- tween.SetParallel();
-
- tween.TweenProperty(role.MountPoint, "rotation_degrees", r - role.MeleeAttackAngle / 2f, 0.1);
- tween.TweenProperty(role.MountPoint, "position", p2, 0.1);
- tween.TweenProperty(role.MountPoint, "position", p2, 0.1);
- tween.Chain();
-
- tween.TweenCallback(Callable.From(() =>
- {
- role.MountPoint.RotationDegrees = r + role.MeleeAttackAngle / 2f;
- role.MountPoint.Position = p3;
- //重新计算武器阴影位置
- var activeItem = role.WeaponPack.ActiveItem;
- activeItem.CalcShadowTransform();
- //创建屏幕抖动
- if (role.Face == FaceDirection.Right)
- {
- //GameCamera.Main.DirectionalShake(Vector2.FromAngle(Mathf.DegToRad(r - 90)) * 5);
- GameCamera.Main.DirectionalShake(Vector2.FromAngle(Mathf.DegToRad(r - 180)) * 6);
- }
- else
- {
- //GameCamera.Main.DirectionalShake(Vector2.FromAngle(Mathf.DegToRad(270 - r)) * 5);
- GameCamera.Main.DirectionalShake(Vector2.FromAngle(Mathf.DegToRad(-r)) * 6);
- }
- //播放特效
- var effect = ObjectManager.GetPoolItem(ResourcePath.prefab_effect_weapon_MeleeAttack1_tscn);
- var sprite = (Node2D)effect;
- var localFirePosition = activeItem.GetLocalFirePosition() - activeItem.GripPoint.Position;
- localFirePosition *= 0.9f;
- sprite.Position = p1 + localFirePosition.Rotated(Mathf.DegToRad(r));
- sprite.RotationDegrees = r;
- role.AddChild(sprite);
- effect.PlayEffect();
-
- //启用近战碰撞区域
- role.MeleeAttackCollision.Disabled = false;
- }));
- tween.Chain();
-
- tween.TweenInterval(0.1f);
- tween.Chain();
-
- tween.TweenCallback(Callable.From(() =>
- {
- //关闭近战碰撞区域
- role.MeleeAttackCollision.Disabled = true;
- }));
- tween.TweenProperty(role.MountPoint, "rotation_degrees", r, 0.2);
- tween.TweenProperty(role.MountPoint, "position", p1, 0.2);
- tween.Chain();
-
- tween.TweenCallback(Callable.From(() =>
- {
- finish();
- }));
- tween.Play();
- }
-}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/AdvancedEnemy.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/AdvancedEnemy.cs
index 75f7900..b2d184d 100644
--- a/DungeonShooting_Godot/src/game/activity/role/enemy/AdvancedEnemy.cs
+++ b/DungeonShooting_Godot/src/game/activity/role/enemy/AdvancedEnemy.cs
@@ -14,93 +14,66 @@
using System;
using AdvancedState;
using Godot;
-using NnormalState;
-using AiAstonishedState = AdvancedState.AiAstonishedState;
-using AiAttackState = AdvancedState.AiAttackState;
-using AiFollowUpState = AdvancedState.AiFollowUpState;
-using AiLeaveForState = AdvancedState.AiLeaveForState;
-using AiNormalState = AdvancedState.AiNormalState;
-using AiNotifyState = AdvancedState.AiNotifyState;
-using AiSurroundState = AdvancedState.AiSurroundState;
-using AiTailAfterState = AdvancedState.AiTailAfterState;
///
/// 高级敌人,可以携带武器
///
[Tool]
-public partial class AdvancedEnemy : Enemy
+public partial class AdvancedEnemy : AdvancedRole
{
///
- /// 角色携带的武器背包
+ /// 目标是否在视野内
///
- public Package WeaponPack { get; private set; }
+ public bool TargetInView { get; set; } = true;
///
- /// 武器挂载点
+ /// 敌人身上的状态机控制器
///
- [Export, ExportFillNode]
- public MountRotation MountPoint { get; set; }
-
- ///
- /// 近战碰撞检测区域
- ///
- [Export, ExportFillNode]
- public Area2D MeleeAttackArea { get; set; }
-
- ///
- /// 近战碰撞检测区域的碰撞器
- ///
- [Export, ExportFillNode]
- public CollisionPolygon2D MeleeAttackCollision { get; set; }
+ public StateController StateController { get; private set; }
///
- /// 近战攻击时挥动武器的角度
+ /// 视野半径, 单位像素, 发现玩家后改视野范围可以穿墙
///
- [Export]
- public float MeleeAttackAngle { get; set; } = 120;
+ public float ViewRange { get; set; } = 250;
///
- /// 武器挂载点是否始终指向目标
+ /// 发现玩家后的视野半径
///
- public bool MountLookTarget { get; set; } = true;
-
+ public float TailAfterViewRange { get; set; } = 400;
+
///
- /// 背后武器的挂载点
+ /// 背后的视野半径, 单位像素
+ ///
+ public float BackViewRange { get; set; } = 50;
+
+ ///
+ /// 视野检测射线, 朝玩家打射线, 检测是否碰到墙
///
[Export, ExportFillNode]
- public Marker2D BackMountPoint { get; set; }
-
- ///
- /// 是否处于近战攻击中
- ///
- public bool IsMeleeAttack { get; private set; }
-
- //近战计时器
- private float _meleeAttackTimer = 0;
-
-
- ///
- /// 当拾起某个武器时调用
- ///
- protected virtual void OnPickUpWeapon(Weapon weapon)
- {
- }
-
- ///
- /// 当扔掉某个武器时调用
- ///
- protected virtual void OnThrowWeapon(Weapon weapon)
- {
- }
+ public RayCast2D ViewRay { get; private set; }
///
- /// 当切换到某个武器时调用
+ /// 导航代理
///
- protected virtual void OnExchangeWeapon(Weapon weapon)
- {
- }
+ [Export, ExportFillNode]
+ public NavigationAgent2D NavigationAgent2D { get; private set; }
+ ///
+ /// 导航代理中点
+ ///
+ [Export, ExportFillNode]
+ public Marker2D NavigationPoint { get; private set; }
+ ///
+ /// 当前敌人所看向的对象, 也就是枪口指向的对象
+ ///
+ public ActivityObject LookTarget { get; set; }
+
+ ///
+ /// 锁定目标已经走过的时间
+ ///
+ public float LockTargetTime { get; set; } = 0;
+
public override void OnInit()
{
base.OnInit();
@@ -207,32 +180,15 @@
//拾起武器操作
EnemyPickUpWeapon();
}
-
- ///
- /// 当武器放到后背时调用, 用于设置武器位置和角度
- ///
- /// 武器实例
- /// 放入武器背包的位置
- public virtual void OnPutBackMount(Weapon weapon, int index)
+
+ protected override void OnHit(ActivityObject target, int damage, float angle, bool realHarm)
{
- if (index < 8)
+ //受到伤害
+ var state = StateController.CurrState;
+ if (state == AIAdvancedStateEnum.AiNormal || state == AIAdvancedStateEnum.AiLeaveFor) //|| state == AiStateEnum.AiProbe
{
- if (index % 2 == 0)
- {
- weapon.Position = new Vector2(-4, 3);
- weapon.RotationDegrees = 90 - (index / 2f) * 20;
- weapon.Scale = new Vector2(-1, 1);
- }
- else
- {
- weapon.Position = new Vector2(4, 3);
- weapon.RotationDegrees = 270 + (index - 1) / 2f * 20;
- weapon.Scale = new Vector2(1, 1);
- }
- }
- else
- {
- weapon.Visible = false;
+ LookTarget = target;
+ StateController.ChangeState(AIAdvancedStateEnum.AiTailAfter);
}
}
@@ -341,7 +297,60 @@
return 0;
}
-
+
+ ///
+ /// 返回目标点是否在视野范围内
+ ///
+ public bool IsInViewRange(Vector2 target)
+ {
+ var isForward = IsPositionInForward(target);
+ if (isForward)
+ {
+ if (GlobalPosition.DistanceSquaredTo(target) <= ViewRange * ViewRange) //没有超出视野半径
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ ///
+ /// 返回目标点是否在跟随状态下的视野半径内
+ ///
+ public bool IsInTailAfterViewRange(Vector2 target)
+ {
+ var isForward = IsPositionInForward(target);
+ if (isForward)
+ {
+ if (GlobalPosition.DistanceSquaredTo(target) <= TailAfterViewRange * TailAfterViewRange) //没有超出视野半径
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ ///
+ /// 调用视野检测, 如果被墙壁和其它物体遮挡, 则返回true
+ ///
+ public bool TestViewRayCast(Vector2 target)
+ {
+ ViewRay.Enabled = true;
+ ViewRay.TargetPosition = ViewRay.ToLocal(target);
+ ViewRay.ForceRaycastUpdate();
+ return ViewRay.IsColliding();
+ }
+
+ ///
+ /// 调用视野检测完毕后, 需要调用 TestViewRayCastOver() 来关闭视野检测射线
+ ///
+ public void TestViewRayCastOver()
+ {
+ ViewRay.Enabled = false;
+ }
+
///
/// AI 拾起武器操作
///
@@ -349,7 +358,7 @@
{
//这几个状态不需要主动拾起武器操作
var state = StateController.CurrState;
- if (state == AINormalStateEnum.AiNormal)
+ if (state == AIAdvancedStateEnum.AiNormal)
{
return;
}
@@ -401,7 +410,7 @@
///
/// 获取锁定目标的剩余时间
///
- public override float GetLockRemainderTime()
+ public float GetLockRemainderTime()
{
var weapon = WeaponPack.ActiveItem;
if (weapon == null)
@@ -411,263 +420,48 @@
return weapon.Attribute.AiAttackAttr.LockingTime - LockTargetTime;
}
+ ///
+ /// 强制设置锁定目标时间
+ ///
+ public void SetLockTargetTime(float time)
+ {
+ LockTargetTime = time;
+ }
+
public override void LookTargetPosition(Vector2 pos)
{
LookTarget = null;
- LookPosition = pos;
- if (MountLookTarget)
- {
- //脸的朝向
- var gPos = Position;
- if (pos.X > gPos.X && Face == FaceDirection.Left)
- {
- Face = FaceDirection.Right;
- }
- else if (pos.X < gPos.X && Face == FaceDirection.Right)
- {
- Face = FaceDirection.Left;
- }
- //枪口跟随目标
- MountPoint.SetLookAt(pos);
- }
+ base.LookTargetPosition(pos);
}
///
- /// 返回所有武器是否弹药都打光了
+ /// 执行移动操作
///
- public bool IsAllWeaponTotalAmmoEmpty()
+ public void DoMove()
{
- foreach (var weapon in WeaponPack.ItemSlot)
- {
- if (weapon != null && !weapon.IsTotalAmmoEmpty())
- {
- return false;
- }
- }
-
- return true;
- }
-
- public override float GetAttackRotation()
- {
- return MountPoint.RealRotation;
- }
-
- public override Vector2 GetMountPosition()
- {
- return MountPoint.GlobalPosition;
- }
-
- public override Node2D GetMountNode()
- {
- return MountPoint;
+ AnimatedSprite.Play(AnimatorNames.Run);
+ //计算移动
+ var nextPos = NavigationAgent2D.GetNextPathPosition();
+ BasisVelocity = (nextPos - Position - NavigationPoint.Position).Normalized() * RoleState.MoveSpeed;
}
///
- /// 拾起一个武器, 返回是否成功拾起, 如果不想立刻切换到该武器, exchange 请传 false
+ /// 执行站立操作
///
- /// 武器对象
- /// 是否立即切换到该武器, 默认 true
- public bool PickUpWeapon(Weapon weapon, bool exchange = true)
+ public void DoIdle()
{
- if (WeaponPack.PickupItem(weapon, exchange) != -1)
- {
- //从可互动队列中移除
- InteractiveItemList.Remove(weapon);
- OnPickUpWeapon(weapon);
- return true;
- }
-
- return false;
- }
-
- ///
- /// 切换到下一个武器
- ///
- public void ExchangeNextWeapon()
- {
- var weapon = WeaponPack.ActiveItem;
- WeaponPack.ExchangeNext();
- if (WeaponPack.ActiveItem != weapon)
- {
- OnExchangeWeapon(WeaponPack.ActiveItem);
- }
- }
-
- ///
- /// 切换到上一个武器
- ///
- public void ExchangePrevWeapon()
- {
- var weapon = WeaponPack.ActiveItem;
- WeaponPack.ExchangePrev();
- if (WeaponPack.ActiveItem != weapon)
- {
- OnExchangeWeapon(WeaponPack.ActiveItem);
- }
- }
-
- ///
- /// 扔掉当前使用的武器, 切换到上一个武器
- ///
- public void ThrowWeapon()
- {
- ThrowWeapon(WeaponPack.ActiveIndex);
- }
-
- ///
- /// 扔掉指定位置的武器
- ///
- /// 武器在武器背包中的位置
- public void ThrowWeapon(int index)
- {
- var weapon = WeaponPack.GetItem(index);
- if (weapon == null)
- {
- return;
- }
-
- var temp = weapon.AnimatedSprite.Position;
- if (Face == FaceDirection.Left)
- {
- temp.Y = -temp.Y;
- }
- //var pos = GlobalPosition + temp.Rotated(weapon.GlobalRotation);
- WeaponPack.RemoveItem(index);
- //播放抛出效果
- weapon.ThrowWeapon(this, GlobalPosition);
+ AnimatedSprite.Play(AnimatorNames.Idle);
+ BasisVelocity = Vector2.Zero;
}
///
- /// 切换到下一个武器
+ /// 更新房间中标记的目标位置
///
- public void ExchangeNextActiveProp()
+ public void UpdateMarkTargetPosition()
{
- var prop = ActivePropsPack.ActiveItem;
- ActivePropsPack.ExchangeNext();
- if (prop != ActivePropsPack.ActiveItem)
+ if (LookTarget != null)
{
- OnExchangeActiveProp(ActivePropsPack.ActiveItem);
- }
- }
-
- ///
- /// 切换到上一个武器
- ///
- public void ExchangePrevActiveProp()
- {
- var prop = ActivePropsPack.ActiveItem;
- ActivePropsPack.ExchangePrev();
- if (prop != ActivePropsPack.ActiveItem)
- {
- OnExchangeActiveProp(ActivePropsPack.ActiveItem);
- }
- }
-
- //-------------------------------------------------------------------------------------
-
- ///
- /// 触发换弹
- ///
- public virtual void Reload()
- {
- if (WeaponPack.ActiveItem != null)
- {
- WeaponPack.ActiveItem.Reload();
- }
- }
-
- public override void Attack()
- {
- if (!IsMeleeAttack && WeaponPack.ActiveItem != null)
- {
- WeaponPack.ActiveItem.Trigger(this);
- }
- }
-
- ///
- /// 触发近战攻击
- ///
- public virtual void MeleeAttack()
- {
- if (IsMeleeAttack || _meleeAttackTimer > 0)
- {
- return;
- }
-
- if (WeaponPack.ActiveItem != null && WeaponPack.ActiveItem.Attribute.CanMeleeAttack)
- {
- IsMeleeAttack = true;
- _meleeAttackTimer = RoleState.MeleeAttackTime;
- MountLookTarget = false;
-
- //WeaponPack.ActiveItem.TriggerMeleeAttack(this);
- //播放近战动画
- this.PlayAnimation_MeleeAttack(() =>
- {
- MountLookTarget = true;
- IsMeleeAttack = false;
- });
- }
- }
-
- ///
- /// 切换当前使用的武器的回调
- ///
- private void OnChangeActiveItem(Weapon weapon)
- {
- //这里处理近战区域
- if (weapon != null)
- {
- MeleeAttackCollision.Polygon = Utils.CreateSectorPolygon(
- Utils.ConvertAngle(-MeleeAttackAngle / 2f),
- (weapon.GetLocalFirePosition() - weapon.GripPoint.Position).Length() * 1.2f,
- MeleeAttackAngle,
- 6
- );
- MeleeAttackArea.CollisionMask = AttackLayer | PhysicsLayer.Bullet;
- }
- }
-
- ///
- /// 近战区域碰到敌人
- ///
- private void OnMeleeAttackBodyEntered(Node2D body)
- {
- var activeWeapon = WeaponPack.ActiveItem;
- if (activeWeapon == null)
- {
- return;
- }
- var activityObject = body.AsActivityObject();
- if (activityObject != null)
- {
- if (activityObject is AdvancedRole role) //攻击角色
- {
- var damage = Utils.Random.RandomConfigRange(activeWeapon.Attribute.MeleeAttackHarmRange);
- damage = RoleState.CalcDamage(damage);
-
- //击退
- if (role is not Player) //目标不是玩家才会触发击退
- {
- var attr = IsAi ? activeWeapon.AiUseAttribute : activeWeapon.PlayerUseAttribute;
- var repel = Utils.Random.RandomConfigRange(attr.MeleeAttackRepelRange);
- var position = role.GlobalPosition - MountPoint.GlobalPosition;
- var v2 = position.Normalized() * repel;
- role.MoveController.AddForce(v2);
- }
-
- role.CallDeferred(nameof(Hurt), this, damage, (role.GetCenterPosition() - GlobalPosition).Angle());
- }
- else if (activityObject is Bullet bullet) //攻击子弹
- {
- var attackLayer = bullet.AttackLayer;
- if (CollisionWithMask(attackLayer)) //是攻击玩家的子弹
- {
- bullet.PlayDisappearEffect();
- bullet.Destroy();
- }
- }
+ AffiliationArea.RoomInfo.MarkTargetPosition[LookTarget.Id] = LookTarget.Position;
}
}
}
diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/Enemy.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/Enemy.cs
index e711869..1513d7c 100644
--- a/DungeonShooting_Godot/src/game/activity/role/enemy/Enemy.cs
+++ b/DungeonShooting_Godot/src/game/activity/role/enemy/Enemy.cs
@@ -75,15 +75,12 @@
public ActivityObject LookTarget { get; set; }
///
- /// 锁定目标已经走过的时间
- ///
- public float LockTargetTime { get; set; } = 0;
-
- ///
/// Ai 攻击属性
///
public ExcelConfig.AiAttackAttr AttackAttribute { get; private set; }
+ //锁定目标时间
+ private float _lockTargetTime = 0;
//攻击冷却计时器
private float _attackTimer = 0;
@@ -174,11 +171,11 @@
var currState = StateController.CurrState;
if (currState == AINormalStateEnum.AiAttack && _attackTimer <= 0) //必须在可以开火时记录时间
{
- LockTargetTime += delta;
+ _lockTargetTime += delta;
}
else
{
- LockTargetTime = 0;
+ _lockTargetTime = 0;
}
}
@@ -186,11 +183,14 @@
{
//受到伤害
var state = StateController.CurrState;
- if (target != null && state == AINormalStateEnum.AiNormal || state == AINormalStateEnum.AiLeaveFor) //|| state == AiStateEnum.AiProbe
- {
- LookTarget = target;
- StateController.ChangeState(AINormalStateEnum.AiTailAfter);
- }
+ // if (state == AINormalStateEnum.AiNormal)
+ // {
+ // StateController.ChangeState(AINormalStateEnum.AiLeaveFor, target);
+ // }
+ // else if (state == AINormalStateEnum.AiLeaveFor)
+ // {
+ //
+ // }
}
protected override void OnDie()
@@ -268,13 +268,29 @@
{
ViewRay.Enabled = false;
}
+
+ ///
+ /// 获取锁定目标的时间
+ ///
+ public float GetLockTime()
+ {
+ return _lockTargetTime;
+ }
///
/// 获取锁定目标的剩余时间
///
- public virtual float GetLockRemainderTime()
+ public float GetLockRemainderTime()
{
- return AttackAttribute.LockingTime - LockTargetTime;
+ return AttackAttribute.LockingTime - _lockTargetTime;
+ }
+
+ ///
+ /// 强制设置锁定目标时间
+ ///
+ public void SetLockTargetTime(float time)
+ {
+ _lockTargetTime = time;
}
///
@@ -305,17 +321,6 @@
}
///
- /// 更新房间中标记的目标位置
- ///
- public void UpdateMarkTargetPosition()
- {
- if (LookTarget != null)
- {
- AffiliationArea.RoomInfo.MarkTargetPosition[LookTarget.Id] = LookTarget.Position;
- }
- }
-
- ///
/// 执行移动操作
///
public void DoMove()
diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/normalState/AINormalStateEnum.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/normalState/AINormalStateEnum.cs
index f731d72..35e56dd 100644
--- a/DungeonShooting_Godot/src/game/activity/role/enemy/normalState/AINormalStateEnum.cs
+++ b/DungeonShooting_Godot/src/game/activity/role/enemy/normalState/AINormalStateEnum.cs
@@ -11,7 +11,7 @@
///
AiNotify,
///
- /// 惊讶状态
+ /// 发现目标, 惊讶状态
///
AiAstonished,
///
@@ -31,11 +31,7 @@
///
AiSurround,
///
- /// Ai 寻找弹药
- ///
- AiFindAmmo,
- ///
- /// Ai攻击
+ /// 攻击状态
///
AiAttack,
}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/activity/weapon/Weapon.cs b/DungeonShooting_Godot/src/game/activity/weapon/Weapon.cs
index e39f771..9a2fd78 100644
--- a/DungeonShooting_Godot/src/game/activity/weapon/Weapon.cs
+++ b/DungeonShooting_Godot/src/game/activity/weapon/Weapon.cs
@@ -6,7 +6,7 @@
///
/// 武器的基类
///
-public abstract partial class Weapon : ActivityObject, IPackageItem
+public abstract partial class Weapon : ActivityObject, IPackageItem
{
///
/// 武器使用的属性数据, 该属性会根据是否是玩家使用武器, 如果是Ai使用武器, 则会返回 AiUseAttribute 的属性对象
@@ -32,7 +32,7 @@
///
public CampEnum TargetCamp { get; set; }
- public Role Master { get; set; }
+ public AdvancedRole Master { get; set; }
public int PackageIndex { get; set; } = -1;
@@ -127,19 +127,7 @@
///
/// 返回是否真正使用该武器
///
- public bool IsActive
- {
- get
- {
- if (Master == null)
- return false;
- else if (Master is AdvancedRole advancedRole)
- return advancedRole.WeaponPack.ActiveItem == this;
- else if (Master is AdvancedEnemy advancedEnemy)
- return advancedEnemy.WeaponPack.ActiveItem == this;
- return false;
- }
- }
+ public bool IsActive => Master != null && Master.WeaponPack.ActiveItem == this;
///
/// 动画播放器
@@ -160,7 +148,7 @@
///
/// 上一次触发改武器开火的角色, 可能为 null
///
- public Role TriggerRole { get; private set; }
+ public AdvancedRole TriggerRole { get; private set; }
///
/// 上一次触发改武器开火的触发开火攻击的层级, 数据源自于:
@@ -409,7 +397,7 @@
/// 当武器被拾起时调用
///
/// 拾起该武器的角色
- protected virtual void OnPickUp(Role master)
+ protected virtual void OnPickUp(AdvancedRole master)
{
}
@@ -417,7 +405,7 @@
/// 当武器从武器背包中移除时调用
///
/// 移除该武器的角色
- protected virtual void OnRemove(Role master)
+ protected virtual void OnRemove(AdvancedRole master)
{
}
@@ -464,7 +452,7 @@
//这把武器被扔在地上, 或者当前武器没有被使用
//if (Master == null || Master.WeaponPack.ActiveItem != this)
- if (!IsActive || !_triggerRoleFlag) //在背上, 或者被扔出去了
+ if ((Master != null && Master.WeaponPack.ActiveItem != this) || !_triggerRoleFlag) //在背上, 或者被扔出去了
{
//_triggerTimer
_triggerTimer = _triggerTimer > 0 ? _triggerTimer - delta : 0;
@@ -707,7 +695,7 @@
/// 扳机函数, 调用即视为按下扳机
///
/// 按下扳机的角色, 如果传 null, 则视为走火
- public void Trigger(Role triggerRole)
+ public void Trigger(AdvancedRole triggerRole)
{
//不能触发扳机
if (!NoMasterCanTrigger && Master == null) return;
@@ -1053,7 +1041,7 @@
if (Master != null)
{
bulletCount = Master.RoleState.CalcBulletCount(bulletCount);
- fireRotation += Master.GetAttackRotation();
+ fireRotation += Master.MountPoint.RealRotation;
}
else
{
@@ -1117,7 +1105,7 @@
///
/// 根据触扳机的角色对象判断该角色使用的武器数据
///
- public ExcelConfig.WeaponBase GetUseAttribute(Role triggerRole)
+ public ExcelConfig.WeaponBase GetUseAttribute(AdvancedRole triggerRole)
{
if (triggerRole == null || !triggerRole.IsAi)
{
@@ -1746,14 +1734,14 @@
///
public float GetRealGlobalRotation()
{
- return Master.GetAttackRotation() + Rotation;
+ return Mathf.DegToRad(Master.MountPoint.RealRotationDegrees) + Rotation;
}
///
/// 触发扔掉武器时抛出的效果, 并不会管武器是否在武器背包中
///
/// 触发扔掉该武器的的角色
- public void ThrowWeapon(Role master)
+ public void ThrowWeapon(AdvancedRole master)
{
ThrowWeapon(master, master.GlobalPosition);
}
@@ -1763,7 +1751,7 @@
///
/// 触发扔掉该武器的的角色
/// 投抛起始位置
- public void ThrowWeapon(Role master, Vector2 startPosition)
+ public void ThrowWeapon(AdvancedRole master, Vector2 startPosition)
{
//阴影偏移
ShadowOffset = new Vector2(0, 2);
@@ -1773,29 +1761,11 @@
Scale *= new Vector2(1, -1);
}
- float rotation;
- float startHeight;
- if (master is AdvancedRole advancedRole)
- {
- var mountPoint = advancedRole.MountPoint;
- rotation = mountPoint.GlobalRotation;
- startHeight = -mountPoint.Position.Y;
- }
- else if (master is AdvancedEnemy advancedEnemy)
- {
- var mountPoint = advancedEnemy.MountPoint;
- rotation = mountPoint.GlobalRotation;
- startHeight = -mountPoint.Position.Y;
- }
- else
- {
- rotation = master.AnimatedSprite.GlobalRotation;
- startHeight = -GetCenterPosition().Y;
- }
-
+ var rotation = master.MountPoint.GlobalRotation;
GlobalRotation = rotation;
startPosition -= GripPoint.Position.Rotated(rotation);
+ var startHeight = -master.MountPoint.Position.Y;
var velocity = new Vector2(20, 0).Rotated(rotation);
var yf = Utils.Random.RandomRangeInt(50, 70);
Throw(startPosition, startHeight, yf, velocity, 0);
@@ -1829,19 +1799,7 @@
{
//调整阴影
//ShadowOffset = new Vector2(0, Master.GlobalPosition.Y - GlobalPosition.Y);
- if (Master is AdvancedRole advancedRole)
- {
- ShadowOffset = new Vector2(0, -advancedRole.MountPoint.Position.Y);
- }
- else if (Master is AdvancedEnemy advancedEnemy)
- {
- ShadowOffset = new Vector2(0, -advancedEnemy.MountPoint.Position.Y);
- }
- else
- {
- ShadowOffset = new Vector2(0, -Master.GetCenterPosition().Y);
- }
-
+ ShadowOffset = new Vector2(0, -Master.MountPoint.Position.Y);
//枪口默认抬起角度
RotationDegrees = -Attribute.DefaultAngle;
ShowShadowSprite();
@@ -1905,33 +1863,16 @@
public void OnActiveItem()
{
- if (Master is AdvancedRole advancedRole)
+ //更改父节点
+ var parent = GetParentOrNull();
+ if (parent == null)
{
- //更改父节点
- var parent = GetParentOrNull();
- if (parent == null)
- {
- advancedRole.MountPoint.AddChild(this);
- }
- else if (parent != advancedRole.MountPoint)
- {
- parent.RemoveChild(this);
- advancedRole.MountPoint.AddChild(this);
- }
+ Master.MountPoint.AddChild(this);
}
- else if (Master is AdvancedEnemy advancedEnemy)
+ else if (parent != Master.MountPoint)
{
- //更改父节点
- var parent = GetParentOrNull();
- if (parent == null)
- {
- advancedEnemy.MountPoint.AddChild(this);
- }
- else if (parent != advancedEnemy.MountPoint)
- {
- parent.RemoveChild(this);
- advancedEnemy.MountPoint.AddChild(this);
- }
+ parent.RemoveChild(this);
+ Master.MountPoint.AddChild(this);
}
Position = Vector2.Zero;
@@ -1943,41 +1884,19 @@
public void OnConcealItem()
{
- if (Master is AdvancedRole advancedRole)
+ var tempParent = GetParentOrNull();
+ if (tempParent != null)
{
- var tempParent = GetParentOrNull();
- if (tempParent != null)
- {
- tempParent.RemoveChild(this);
- advancedRole.BackMountPoint.AddChild(this);
- advancedRole.OnPutBackMount(this, PackageIndex);
- Conceal();
- }
+ tempParent.RemoveChild(this);
+ Master.BackMountPoint.AddChild(this);
+ Master.OnPutBackMount(this, PackageIndex);
+ Conceal();
}
- else if (Master is AdvancedEnemy advancedEnemy)
- {
- var tempParent = GetParentOrNull();
- if (tempParent != null)
- {
- tempParent.RemoveChild(this);
- advancedEnemy.BackMountPoint.AddChild(this);
- advancedEnemy.OnPutBackMount(this, PackageIndex);
- Conceal();
- }
- }
-
}
public void OnOverflowItem()
{
- if (Master is AdvancedRole advancedRole)
- {
- advancedRole.ThrowWeapon(PackageIndex);
- }
- else if (Master is AdvancedEnemy advancedEnemy)
- {
- advancedEnemy.ThrowWeapon(PackageIndex);
- }
+ Master.ThrowWeapon(PackageIndex);
}
///
@@ -2006,13 +1925,12 @@
AiAttackEnum flag;
if (IsTotalAmmoEmpty()) //当前武器弹药打空
{
- var enemy = (AdvancedEnemy)Master;
//切换到有子弹的武器
- var index = enemy.WeaponPack.FindIndex((we, i) => !we.IsTotalAmmoEmpty());
+ var index = Master.WeaponPack.FindIndex((we, i) => !we.IsTotalAmmoEmpty());
if (index != -1)
{
flag = AiAttackEnum.ExchangeWeapon;
- enemy.WeaponPack.ExchangeByIndex(index);
+ Master.WeaponPack.ExchangeByIndex(index);
}
else //所有子弹打光
{
@@ -2059,7 +1977,7 @@
enemy.Attack();
if (_attackFlag)
{
- enemy.LockTargetTime = 0;
+ enemy.SetLockTargetTime(0);
}
}
else
@@ -2070,7 +1988,7 @@
enemy.Attack();
if (_attackFlag)
{
- enemy.LockTargetTime = 0;
+ enemy.SetLockTargetTime(0);
}
}
else //单发
@@ -2079,7 +1997,7 @@
enemy.Attack();
if (_attackFlag)
{
- enemy.LockTargetTime = 0;
+ enemy.SetLockTargetTime(0);
}
}
}
diff --git a/DungeonShooting_Godot/src/game/activity/weapon/knife/Knife.cs b/DungeonShooting_Godot/src/game/activity/weapon/knife/Knife.cs
index d32b28d..b5db0d6 100644
--- a/DungeonShooting_Godot/src/game/activity/weapon/knife/Knife.cs
+++ b/DungeonShooting_Godot/src/game/activity/weapon/knife/Knife.cs
@@ -50,7 +50,7 @@
if (IsActive)
{
//让碰撞节点与武器挂载节点位置保持一致, 而不跟着武器走
- _hitArea.GlobalPosition = Master.GetMountPosition();
+ _hitArea.GlobalPosition = Master.MountPoint.GlobalPosition;
}
}
@@ -85,8 +85,8 @@
SpecialEffectManager.Play(
Master,
ResourcePath.resource_spriteFrames_effect_KnifeHit1_tres, "default",
- Master.GetMountPosition(),
- Master.GetAttackRotation() + Mathf.DegToRad(Attribute.UpliftAngle + 60),
+ Master.MountPoint.Position,
+ Master.MountPoint.Rotation + Mathf.DegToRad(Attribute.UpliftAngle + 60),
AnimatedSprite.Scale,
new Vector2(17, 4), 1
);
@@ -95,7 +95,7 @@
if (Master == Player.Current)
{
- var r = Mathf.RadToDeg(Master.GetAttackRotation());
+ var r = Master.MountPoint.RotationDegrees;
//创建屏幕抖动
if (Master.Face == FaceDirection.Right)
{
@@ -148,7 +148,7 @@
Vector2 position;
if (TriggerRole != null)
{
- position = role.GlobalPosition - TriggerRole.GetMountPosition();
+ position = role.GlobalPosition - TriggerRole.MountPoint.GlobalPosition;
}
else
{
diff --git a/DungeonShooting_Godot/src/game/room/DungeonManager.cs b/DungeonShooting_Godot/src/game/room/DungeonManager.cs
index ab4560a..3cf058f 100644
--- a/DungeonShooting_Godot/src/game/room/DungeonManager.cs
+++ b/DungeonShooting_Godot/src/game/room/DungeonManager.cs
@@ -566,9 +566,23 @@
//不与玩家处于同一个房间
if (!enemy.IsDestroyed && enemy.AffiliationArea != playerAffiliationArea)
{
- if (enemy.StateController.CurrState != AINormalStateEnum.AiNormal)
+ if (enemy is Enemy e)
{
- enemy.StateController.ChangeState(AINormalStateEnum.AiNormal);
+ if (e.StateController.CurrState != AINormalStateEnum.AiNormal)
+ {
+ e.StateController.ChangeState(AINormalStateEnum.AiNormal);
+ }
+ }
+ else if (enemy is AdvancedEnemy ae)
+ {
+ if (ae.StateController.CurrState != AIAdvancedStateEnum.AiNormal)
+ {
+ ae.StateController.ChangeState(AIAdvancedStateEnum.AiNormal);
+ }
+ }
+ else
+ {
+ throw new Exception("World.Enemy_InstanceList 混入了非 Enemy 和 AdvancedEnemy 类型的对象!");
}
}
}
diff --git a/DungeonShooting_Godot/src/game/room/World.cs b/DungeonShooting_Godot/src/game/room/World.cs
index 1285582..1ed2eab 100644
--- a/DungeonShooting_Godot/src/game/room/World.cs
+++ b/DungeonShooting_Godot/src/game/room/World.cs
@@ -63,7 +63,7 @@
///
/// 记录所有存活的敌人
///
- public List Enemy_InstanceList { get; } = new List();
+ public List Enemy_InstanceList { get; } = new List();
private bool _pause = false;
private List _coroutineList;