diff --git a/DungeonShooting_Godot/excel/excelFile/ActivityBase.xlsx b/DungeonShooting_Godot/excel/excelFile/ActivityBase.xlsx
index bd6a11a..818426b 100644
--- a/DungeonShooting_Godot/excel/excelFile/ActivityBase.xlsx
+++ b/DungeonShooting_Godot/excel/excelFile/ActivityBase.xlsx
Binary files differ
diff --git a/DungeonShooting_Godot/excel/excelFile/ActivityMaterial.xlsx b/DungeonShooting_Godot/excel/excelFile/ActivityMaterial.xlsx
index e5d3df5..8f9e321 100644
--- a/DungeonShooting_Godot/excel/excelFile/ActivityMaterial.xlsx
+++ b/DungeonShooting_Godot/excel/excelFile/ActivityMaterial.xlsx
Binary files differ
diff --git a/DungeonShooting_Godot/excel/excelFile/AiAttackAttr.xlsx b/DungeonShooting_Godot/excel/excelFile/AiAttackAttr.xlsx
index 424da67..7491120 100644
--- a/DungeonShooting_Godot/excel/excelFile/AiAttackAttr.xlsx
+++ b/DungeonShooting_Godot/excel/excelFile/AiAttackAttr.xlsx
Binary files differ
diff --git a/DungeonShooting_Godot/excel/excelFile/BulletBase.xlsx b/DungeonShooting_Godot/excel/excelFile/BulletBase.xlsx
index afd438c..eb1663d 100644
--- a/DungeonShooting_Godot/excel/excelFile/BulletBase.xlsx
+++ b/DungeonShooting_Godot/excel/excelFile/BulletBase.xlsx
Binary files differ
diff --git a/DungeonShooting_Godot/excel/excelFile/Sound.xlsx b/DungeonShooting_Godot/excel/excelFile/Sound.xlsx
index 6bd1742..18536a3 100644
--- a/DungeonShooting_Godot/excel/excelFile/Sound.xlsx
+++ b/DungeonShooting_Godot/excel/excelFile/Sound.xlsx
Binary files differ
diff --git a/DungeonShooting_Godot/excel/excelFile/WeaponBase.xlsx b/DungeonShooting_Godot/excel/excelFile/WeaponBase.xlsx
index 88e9e65..def9693 100644
--- a/DungeonShooting_Godot/excel/excelFile/WeaponBase.xlsx
+++ b/DungeonShooting_Godot/excel/excelFile/WeaponBase.xlsx
Binary files differ
diff --git a/DungeonShooting_Godot/prefab/role/Enemy0002.tscn b/DungeonShooting_Godot/prefab/role/Enemy0002.tscn
index 3fe20e2..bebc437 100644
--- a/DungeonShooting_Godot/prefab/role/Enemy0002.tscn
+++ b/DungeonShooting_Godot/prefab/role/Enemy0002.tscn
@@ -27,7 +27,7 @@
shader_parameter/outline_rainbow = false
shader_parameter/outline_use_blend = true
-[sub_resource type="Animation" id="Animation_wn6ao"]
+[sub_resource type="Animation" id="Animation_g3he5"]
resource_name = "attack"
length = 0.6
tracks/0/type = "value"
@@ -37,10 +37,10 @@
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
-"times": PackedFloat32Array(0, 0.6),
-"transitions": PackedFloat32Array(1, 1),
+"times": PackedFloat32Array(0),
+"transitions": PackedFloat32Array(1),
"update": 1,
-"values": [&"attack", &"idle"]
+"values": [&"attack"]
}
tracks/1/type = "value"
tracks/1/imported = false
@@ -65,11 +65,11 @@
"transitions": PackedFloat32Array(1),
"values": [{
"args": [],
-"method": &"ShootBullet"
+"method": &"Attack"
}]
}
-[sub_resource type="Animation" id="Animation_0iqth"]
+[sub_resource type="Animation" id="Animation_4j2gl"]
length = 0.001
tracks/0/type = "value"
tracks/0/imported = false
@@ -93,22 +93,21 @@
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
-"values": [5]
+"values": [0]
}
-[sub_resource type="AnimationLibrary" id="AnimationLibrary_wxs4x"]
+[sub_resource type="AnimationLibrary" id="AnimationLibrary_oris7"]
_data = {
-"RESET": SubResource("Animation_0iqth"),
-"attack": SubResource("Animation_wn6ao")
+"RESET": SubResource("Animation_4j2gl"),
+"attack": SubResource("Animation_g3he5")
}
-[node name="Enemy0002" node_paths=PackedStringArray("ViewRay", "NavigationAgent2D", "NavigationPoint", "FirePoint", "AnimationPlayer", "HurtArea", "HurtCollision", "InteractiveArea", "InteractiveCollision", "ShadowSprite", "AnimatedSprite", "Collision") instance=ExtResource("1_rikvp")]
+[node name="Enemy0002" node_paths=PackedStringArray("ViewRay", "NavigationAgent2D", "NavigationPoint", "FirePoint", "HurtArea", "HurtCollision", "InteractiveArea", "InteractiveCollision", "ShadowSprite", "AnimatedSprite", "Collision", "AnimationPlayer") instance=ExtResource("1_rikvp")]
script = ExtResource("2_wjtfl")
ViewRay = NodePath("ViewRay")
NavigationAgent2D = NodePath("NavigationPoint/NavigationAgent2D")
NavigationPoint = NodePath("NavigationPoint")
FirePoint = NodePath("AnimatedSprite/FirePoint")
-AnimationPlayer = NodePath("AnimationPlayer")
HurtArea = NodePath("HurtArea")
HurtCollision = NodePath("HurtArea/HurtCollision")
InteractiveArea = NodePath("InteractiveArea")
@@ -116,6 +115,7 @@
ShadowSprite = NodePath("ShadowSprite")
AnimatedSprite = NodePath("AnimatedSprite")
Collision = NodePath("Collision")
+AnimationPlayer = NodePath("AnimationPlayer")
[node name="ShadowSprite" parent="." index="0"]
material = SubResource("ShaderMaterial_7theg")
@@ -125,12 +125,11 @@
position = Vector2(0, -10)
sprite_frames = ExtResource("4_ehtyi")
animation = &"attack"
-frame = 5
[node name="FirePoint" type="Marker2D" parent="AnimatedSprite" index="0"]
position = Vector2(9, 4)
[node name="AnimationPlayer" type="AnimationPlayer" parent="." index="7"]
libraries = {
-"": SubResource("AnimationLibrary_wxs4x")
+"": SubResource("AnimationLibrary_oris7")
}
diff --git a/DungeonShooting_Godot/resource/config/AiAttackAttr.json b/DungeonShooting_Godot/resource/config/AiAttackAttr.json
index 3d27a46..251daae 100644
--- a/DungeonShooting_Godot/resource/config/AiAttackAttr.json
+++ b/DungeonShooting_Godot/resource/config/AiAttackAttr.json
@@ -2,6 +2,7 @@
{
"Id": "0001",
"Remark": "",
+ "LockingStand": true,
"FiringStand": true,
"ShowSubline": false,
"LockingTime": 1,
@@ -13,6 +14,7 @@
{
"Id": "0002",
"Remark": "",
+ "LockingStand": true,
"FiringStand": true,
"ShowSubline": false,
"LockingTime": 2,
@@ -24,6 +26,7 @@
{
"Id": "0003",
"Remark": "",
+ "LockingStand": true,
"FiringStand": true,
"ShowSubline": false,
"LockingTime": 1,
@@ -35,6 +38,7 @@
{
"Id": "0004",
"Remark": "\u79FB\u52A8\u5C04\u51FB",
+ "LockingStand": false,
"FiringStand": false,
"ShowSubline": false,
"LockingTime": 0.7,
@@ -46,6 +50,7 @@
{
"Id": "0005",
"Remark": "\u4F7F\u7528\u8FDC\u8DDD\u79BB\u6B66\u5668",
+ "LockingStand": true,
"FiringStand": true,
"ShowSubline": true,
"LockingTime": 1.5,
@@ -57,6 +62,7 @@
{
"Id": "0006",
"Remark": "",
+ "LockingStand": true,
"FiringStand": true,
"ShowSubline": false,
"LockingTime": 0.5,
@@ -68,6 +74,7 @@
{
"Id": "0007",
"Remark": "\u6FC0\u5149\u6B66\u5668",
+ "LockingStand": true,
"FiringStand": true,
"ShowSubline": true,
"LockingTime": 1.5,
@@ -79,6 +86,7 @@
{
"Id": "0008",
"Remark": "\u69B4\u5F39\u70AE",
+ "LockingStand": true,
"FiringStand": true,
"ShowSubline": false,
"LockingTime": 1.5,
diff --git a/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start1/Preinstall.json b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start1/Preinstall.json
index c401b01..09e0c14 100644
--- a/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start1/Preinstall.json
+++ b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start1/Preinstall.json
@@ -1 +1 @@
-[{"Name":"test1","Weight":100,"Remark":"","WaveList":[[{"Position":{"X":19,"Y":2},"Size":{"X":0,"Y":0},"SpecialMarkType":1,"DelayTime":0,"MarkList":[]},{"Position":{"X":24,"Y":-14},"Size":{"X":0,"Y":0},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0001","Weight":100,"Attr":{"CurrAmmon":"30","ResidueAmmo":"210"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":6,"Y":34},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0002","Weight":100,"Attr":{"CurrAmmon":"7","ResidueAmmo":"70"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-42,"Y":9},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0004","Weight":100,"Attr":{"CurrAmmon":"180","ResidueAmmo":"90"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-63,"Y":-18},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0005","Weight":100,"Attr":{"CurrAmmon":"10","ResidueAmmo":"40"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-31,"Y":-16},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0003","Weight":100,"Attr":{"CurrAmmon":"12","ResidueAmmo":"90"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-47,"Y":32},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0006","Weight":100,"Attr":{"CurrAmmon":"20","ResidueAmmo":"300"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":2,"Y":-25},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0007","Weight":100,"Attr":{"CurrAmmon":"60","ResidueAmmo":"300"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-80,"Y":14},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0008","Weight":100,"Attr":{"CurrAmmon":"10","ResidueAmmo":"120"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-75,"Y":47},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0009","Weight":100,"Attr":{"CurrAmmon":"1","ResidueAmmo":"25"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":46,"Y":1},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0011","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":36,"Y":49},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0012","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-90,"Y":-23},"Size":{"X":3,"Y":6},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0013","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-91,"Y":-6},"Size":{"X":0,"Y":0},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0014","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]}],[{"Position":{"X":57,"Y":56},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0003","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":67,"Y":28},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0.5,"MarkList":[{"Id":"prop5000","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":60,"Y":-19},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":1,"MarkList":[{"Id":"prop5001","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":34,"Y":23},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":1.5,"MarkList":[{"Id":"prop0002","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-11,"Y":8},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0010","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-20,"Y":33},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0010","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]}]]}]
\ No newline at end of file
+[{"Name":"test1","Weight":100,"Remark":"","WaveList":[[{"Position":{"X":19,"Y":2},"Size":{"X":0,"Y":0},"SpecialMarkType":1,"DelayTime":0,"MarkList":[]},{"Position":{"X":24,"Y":-14},"Size":{"X":0,"Y":0},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0001","Weight":100,"Attr":{"CurrAmmon":"30","ResidueAmmo":"210"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":6,"Y":34},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0002","Weight":100,"Attr":{"CurrAmmon":"7","ResidueAmmo":"70"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-42,"Y":9},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0004","Weight":100,"Attr":{"CurrAmmon":"180","ResidueAmmo":"90"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-63,"Y":-18},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0005","Weight":100,"Attr":{"CurrAmmon":"10","ResidueAmmo":"40"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-31,"Y":-16},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0003","Weight":100,"Attr":{"CurrAmmon":"12","ResidueAmmo":"90"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-47,"Y":32},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0006","Weight":100,"Attr":{"CurrAmmon":"20","ResidueAmmo":"300"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":2,"Y":-25},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0007","Weight":100,"Attr":{"CurrAmmon":"60","ResidueAmmo":"300"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-80,"Y":14},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0008","Weight":100,"Attr":{"CurrAmmon":"10","ResidueAmmo":"120"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-75,"Y":47},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0009","Weight":100,"Attr":{"CurrAmmon":"1","ResidueAmmo":"25"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":46,"Y":1},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0011","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":36,"Y":49},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0012","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-90,"Y":-23},"Size":{"X":3,"Y":6},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0013","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-91,"Y":-6},"Size":{"X":0,"Y":0},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0014","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]}],[{"Position":{"X":57,"Y":56},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0003","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":67,"Y":28},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0.5,"MarkList":[{"Id":"prop5000","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":60,"Y":-19},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":1,"MarkList":[{"Id":"prop5001","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":34,"Y":23},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":1.5,"MarkList":[{"Id":"prop0002","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-11,"Y":8},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0010","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-20,"Y":33},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0010","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":8,"Y":12},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"enemy0002","Weight":100,"Attr":{"Face":"0","Weapon":null},"Altitude":0,"VerticalSpeed":0}]}]]}]
\ No newline at end of file
diff --git a/DungeonShooting_Godot/resource/spriteFrames/role/Enemy0002.tres b/DungeonShooting_Godot/resource/spriteFrames/role/Enemy0002.tres
index 2851e22..76aae0b 100644
--- a/DungeonShooting_Godot/resource/spriteFrames/role/Enemy0002.tres
+++ b/DungeonShooting_Godot/resource/spriteFrames/role/Enemy0002.tres
@@ -126,7 +126,7 @@
}],
"loop": false,
"name": &"attack",
-"speed": 8.0
+"speed": 15.0
}, {
"frames": [{
"duration": 1.0,
@@ -160,7 +160,7 @@
}],
"loop": true,
"name": &"idle",
-"speed": 8.0
+"speed": 10.0
}, {
"frames": [{
"duration": 1.0,
diff --git a/DungeonShooting_Godot/src/config/ExcelConfig_AiAttackAttr.cs b/DungeonShooting_Godot/src/config/ExcelConfig_AiAttackAttr.cs
index 0dceead..c3c734c 100644
--- a/DungeonShooting_Godot/src/config/ExcelConfig_AiAttackAttr.cs
+++ b/DungeonShooting_Godot/src/config/ExcelConfig_AiAttackAttr.cs
@@ -20,6 +20,12 @@
public string Remark;
///
+ /// 锁定目标时是否站立不动
+ ///
+ [JsonInclude]
+ public bool LockingStand;
+
+ ///
/// 开火时是否站立不动
///
[JsonInclude]
@@ -75,6 +81,7 @@
var inst = new AiAttackAttr();
inst.Id = Id;
inst.Remark = Remark;
+ inst.LockingStand = LockingStand;
inst.FiringStand = FiringStand;
inst.ShowSubline = ShowSubline;
inst.LockingTime = LockingTime;
diff --git a/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs b/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs
index 109eb8e..c88e33f 100644
--- a/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs
+++ b/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs
@@ -59,6 +59,12 @@
///
[Export, ExportFillNode]
public CollisionShape2D Collision { get; set; }
+
+ ///
+ /// 动画播放器
+ ///
+ [Export, ExportFillNode]
+ public AnimationPlayer AnimationPlayer { get; set; }
///
/// 是否调用过 Destroy() 函数
diff --git a/DungeonShooting_Godot/src/framework/activity/components/StateController.cs b/DungeonShooting_Godot/src/framework/activity/components/StateController.cs
index d33027c..f1b035c 100644
--- a/DungeonShooting_Godot/src/framework/activity/components/StateController.cs
+++ b/DungeonShooting_Godot/src/framework/activity/components/StateController.cs
@@ -135,6 +135,7 @@
}
else if (CurrStateBase.CanChangeState(next))
{
+ // Debug.Log($"changeState: {CurrState} => {next}");
_isChangeState = !late;
var prev = CurrStateBase.State;
CurrStateBase.Exit(next);
diff --git a/DungeonShooting_Godot/src/game/GameApplication.cs b/DungeonShooting_Godot/src/game/GameApplication.cs
index 23d0fa6..4496067 100644
--- a/DungeonShooting_Godot/src/game/GameApplication.cs
+++ b/DungeonShooting_Godot/src/game/GameApplication.cs
@@ -104,7 +104,7 @@
//随机化种子
//GD.Randomize();
//固定帧率
- //Engine.MaxFps = TargetFps;
+ Engine.MaxFps = TargetFps;
//调试绘制开关
ActivityObject.IsDebug = true;
//Engine.TimeScale = 0.2f;
diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/AdvancedEnemy.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/AdvancedEnemy.cs
index cf69f1e..22ae399 100644
--- a/DungeonShooting_Godot/src/game/activity/role/enemy/AdvancedEnemy.cs
+++ b/DungeonShooting_Godot/src/game/activity/role/enemy/AdvancedEnemy.cs
@@ -67,7 +67,7 @@
///
/// Ai攻击状态, 调用 Attack() 函数后会刷新
///
- public AiAttackState AttackState { get; private set; }
+ public AiAttackEnum AttackState { get; private set; }
///
/// 当前敌人所看向的对象, 也就是枪口指向的对象
@@ -193,7 +193,7 @@
_lockTargetTime = 0;
}
- if (AttackState == AiAttackState.LockingTime) //锁定玩家状态
+ if (AttackState == AiAttackEnum.LockingTime) //锁定玩家状态
{
var aiLockRemainderTime = GetLockRemainderTime();
MountLookTarget = aiLockRemainderTime >= weapon.Attribute.AiAttackAttr.LockAngleTime;
@@ -224,7 +224,7 @@
SubLine.Enable = false;
}
- if (AttackState == AiAttackState.Attack || AttackState == AiAttackState.AttackInterval)
+ if (AttackState == AiAttackEnum.Attack || AttackState == AiAttackEnum.AttackInterval)
{
if (weapon.Attribute.AiAttackAttr.AttackLockAngle) //开火时锁定枪口角度
{
@@ -391,7 +391,7 @@
}
else //没有武器
{
- AttackState = AiAttackState.NoWeapon;
+ AttackState = AiAttackEnum.NoWeapon;
}
}
diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/AiAttackEnum.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/AiAttackEnum.cs
new file mode 100644
index 0000000..f8e8b89
--- /dev/null
+++ b/DungeonShooting_Godot/src/game/activity/role/enemy/AiAttackEnum.cs
@@ -0,0 +1,43 @@
+
+///
+/// 调用 Enemy.EnemyAttack() 函数返回的结果
+///
+public enum AiAttackEnum
+{
+ ///
+ /// 未触发 EnemyAttack()
+ ///
+ None,
+ ///
+ /// 触发切换武器
+ ///
+ ExchangeWeapon,
+ ///
+ /// 没有弹药了
+ ///
+ NoAmmo,
+ ///
+ /// 换弹中
+ ///
+ Reloading,
+ ///
+ /// 触发换弹
+ ///
+ TriggerReload,
+ ///
+ /// 没有武器
+ ///
+ NoWeapon,
+ ///
+ /// 正在锁定目标中
+ ///
+ LockingTime,
+ ///
+ /// 攻击间隙时间
+ ///
+ AttackInterval,
+ ///
+ /// 成功触发攻击
+ ///
+ Attack,
+}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/AiAttackState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/AiAttackState.cs
deleted file mode 100644
index 62bc132..0000000
--- a/DungeonShooting_Godot/src/game/activity/role/enemy/AiAttackState.cs
+++ /dev/null
@@ -1,43 +0,0 @@
-
-///
-/// 调用 Enemy.EnemyAttack() 函数返回的结果
-///
-public enum AiAttackState
-{
- ///
- /// 未触发 EnemyAttack()
- ///
- None,
- ///
- /// 触发切换武器
- ///
- ExchangeWeapon,
- ///
- /// 没有弹药了
- ///
- NoAmmo,
- ///
- /// 换弹中
- ///
- Reloading,
- ///
- /// 触发换弹
- ///
- TriggerReload,
- ///
- /// 没有武器
- ///
- NoWeapon,
- ///
- /// 正在锁定目标中
- ///
- LockingTime,
- ///
- /// 攻击间隙时间
- ///
- AttackInterval,
- ///
- /// 成功触发攻击
- ///
- Attack,
-}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/Enemy.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/Enemy.cs
index 4d2e634..b6f69a0 100644
--- a/DungeonShooting_Godot/src/game/activity/role/enemy/Enemy.cs
+++ b/DungeonShooting_Godot/src/game/activity/role/enemy/Enemy.cs
@@ -41,11 +41,6 @@
public float AttackRange { get; set; } = 200;
///
- /// 开火时是否站立不动
- ///
- public bool FiringStand { get; set; } = true;
-
- ///
/// 视野检测射线, 朝玩家打射线, 检测是否碰到墙
///
[Export, ExportFillNode]
@@ -70,25 +65,20 @@
public Marker2D FirePoint { get; private set; }
///
- /// Ai攻击状态, 调用 Attack() 函数后会刷新
- ///
- public AiAttackState AttackState { get; private set; }
-
- ///
/// 攻击时间间隔
///
- public float AttackInterval { get; set; } = 3;
-
- ///
- /// 锁定目标需要消耗的时间
- ///
- public float LockingTime { get; set; } = 2;
+ public float AttackInterval { get; set; } = 5;
///
/// 当前敌人所看向的对象, 也就是枪口指向的对象
///
public ActivityObject LookTarget { get; set; }
+ ///
+ /// Ai 攻击属性
+ ///
+ public ExcelConfig.AiAttackAttr AttackAttribute { get; private set; }
+
//锁定目标时间
private float _lockTargetTime = 0;
//攻击冷却计时器
@@ -97,6 +87,7 @@
public override void OnInit()
{
base.OnInit();
+ AttackAttribute = ExcelConfig.AiAttackAttr_Map["0001"];
IsAi = true;
StateController = AddComponent>();
@@ -113,6 +104,8 @@
StateController.Register(new AiTailAfterState());
StateController.Register(new AiFollowUpState());
StateController.Register(new AiSurroundState());
+ StateController.Register(new AiLeaveForState());
+ StateController.Register(new AiAttackState());
StateController.ChangeState(AINormalStateEnum.AiNormal);
}
@@ -131,20 +124,8 @@
public override void Attack()
{
- if (_attackTimer > 0) //开火间隙
- {
- AttackState = AiAttackState.AttackInterval;
- }
- else if (GetLockRemainderTime() > 0) //锁定目标时间
- {
- AttackState = AiAttackState.LockingTime;
- }
- else //正常攻击
- {
- AttackState = AiAttackState.Attack;
- _attackTimer = AttackInterval;
- OnAttack();
- }
+ _attackTimer = AttackInterval;
+ OnAttack();
}
///
@@ -188,16 +169,9 @@
}
//目标在视野内的时间
var currState = StateController.CurrState;
- if (currState == AINormalStateEnum.AiSurround || currState == AINormalStateEnum.AiFollowUp)
+ if (currState == AINormalStateEnum.AiAttack && _attackTimer <= 0) //必须在可以开火时记录时间
{
- if (_attackTimer <= 0) //必须在可以开火时记录时间
- {
- _lockTargetTime += delta;
- }
- else
- {
- _lockTargetTime = 0;
- }
+ _lockTargetTime += delta;
}
else
{
@@ -324,7 +298,7 @@
///
public float GetLockRemainderTime()
{
- return LockingTime - _lockTargetTime;
+ return AttackAttribute.LockingTime - _lockTargetTime;
}
///
@@ -353,4 +327,32 @@
LookTarget = null;
base.LookTargetPosition(pos);
}
+
+ ///
+ /// 获取攻击冷却计时时间, 小于等于 0 表示冷却完成
+ ///
+ public float GetAttackTimer()
+ {
+ return _attackTimer;
+ }
+
+ ///
+ /// 执行移动操作
+ ///
+ public void DoMove()
+ {
+ AnimatedSprite.Play(AnimatorNames.Run);
+ //计算移动
+ var nextPos = NavigationAgent2D.GetNextPathPosition();
+ BasisVelocity = (nextPos - Position - NavigationPoint.Position).Normalized() * RoleState.MoveSpeed;
+ }
+
+ ///
+ /// 执行站立操作
+ ///
+ public void DoIdle()
+ {
+ AnimatedSprite.Play(AnimatorNames.Idle);
+ BasisVelocity = Vector2.Zero;
+ }
}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiFollowUpState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiFollowUpState.cs
index 86bbe98..ae6ee0d 100644
--- a/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiFollowUpState.cs
+++ b/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiFollowUpState.cs
@@ -73,7 +73,7 @@
if (!Master.NavigationAgent2D.IsNavigationFinished())
{
if (weapon == null || !weapon.Attribute.AiAttackAttr.FiringStand ||
- (Master.AttackState != AiAttackState.LockingTime && Master.AttackState != AiAttackState.Attack))
+ (Master.AttackState != AiAttackEnum.LockingTime && Master.AttackState != AiAttackEnum.Attack))
{
//计算移动
var nextPos = Master.NavigationAgent2D.GetNextPathPosition();
@@ -105,7 +105,7 @@
}
//在视野中, 或者锁敌状态下, 或者攻击状态下, 继续保持原本逻辑
- if (Master.TargetInView || Master.AttackState == AiAttackState.LockingTime || Master.AttackState == AiAttackState.Attack)
+ if (Master.TargetInView || Master.AttackState == AiAttackEnum.LockingTime || Master.AttackState == AiAttackEnum.Attack)
{
if (inAttackRange) //在攻击范围内
{
diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiSurroundState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiSurroundState.cs
index 07dc504..fc5578a 100644
--- a/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiSurroundState.cs
+++ b/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiSurroundState.cs
@@ -70,7 +70,7 @@
//在视野中, 或者锁敌状态下, 或者攻击状态下, 继续保持原本逻辑
if (Master.TargetInView ||
(weapon != null && weapon.Attribute.AiAttackAttr.FiringStand &&
- (Master.AttackState == AiAttackState.LockingTime || Master.AttackState == AiAttackState.Attack)
+ (Master.AttackState == AiAttackEnum.LockingTime || Master.AttackState == AiAttackEnum.Attack)
))
{
if (_pauseTimer >= 0)
@@ -111,7 +111,6 @@
}
else
{
- var pos = masterPosition;
var lastSlideCollision = Master.GetLastSlideCollision();
if (lastSlideCollision != null && lastSlideCollision.GetCollider() is AdvancedRole) //碰到其他角色
{
@@ -124,12 +123,12 @@
{
//判断开火状态, 进行移动
if (weapon == null || !weapon.Attribute.AiAttackAttr.FiringStand ||
- (Master.AttackState != AiAttackState.LockingTime && Master.AttackState != AiAttackState.Attack))
+ (Master.AttackState != AiAttackEnum.LockingTime && Master.AttackState != AiAttackEnum.Attack))
{ //正常移动
//计算移动
var nextPos = Master.NavigationAgent2D.GetNextPathPosition();
Master.AnimatedSprite.Play(AnimatorNames.Run);
- Master.BasisVelocity = (nextPos - pos - Master.NavigationPoint.Position).Normalized() *
+ Master.BasisVelocity = (nextPos - masterPosition - Master.NavigationPoint.Position).Normalized() *
Master.RoleState.MoveSpeed;
}
else //站立不动
@@ -139,13 +138,14 @@
}
}
- if (_prevPos.DistanceSquaredTo(pos) <= 1 * delta)
+ if (_prevPos.DistanceSquaredTo(masterPosition) <= 1 * delta)
{
_lockTimer += delta;
}
else
{
- _prevPos = pos;
+ _lockTimer = 0;
+ _prevPos = masterPosition;
}
}
diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiTailAfterState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiTailAfterState.cs
index 96fc91c..b24319a 100644
--- a/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiTailAfterState.cs
+++ b/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiTailAfterState.cs
@@ -67,7 +67,7 @@
{
var weapon = Master.WeaponPack.ActiveItem;
if (weapon == null || !weapon.Attribute.AiAttackAttr.FiringStand ||
- (Master.AttackState != AiAttackState.LockingTime && Master.AttackState != AiAttackState.Attack))
+ (Master.AttackState != AiAttackEnum.LockingTime && Master.AttackState != AiAttackEnum.Attack))
{
//计算移动
var nextPos = Master.NavigationAgent2D.GetNextPathPosition();
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 447e4e6..9b8fe24 100644
--- a/DungeonShooting_Godot/src/game/activity/role/enemy/normalState/AINormalStateEnum.cs
+++ b/DungeonShooting_Godot/src/game/activity/role/enemy/normalState/AINormalStateEnum.cs
@@ -6,10 +6,6 @@
/// Ai 状态, 正常, 未发现目标
///
AiNormal,
- // ///
- // /// 发现目标, 但不知道在哪
- // ///
- // AiProbe,
///
/// 找到玩家,准备通知其他敌人
///
@@ -30,4 +26,8 @@
/// 距离足够近, 在目标附近随机移动
///
AiSurround,
+ ///
+ /// 攻击状态
+ ///
+ AiAttack,
}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/normalState/AiAttackState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/normalState/AiAttackState.cs
new file mode 100644
index 0000000..b6f9f92
--- /dev/null
+++ b/DungeonShooting_Godot/src/game/activity/role/enemy/normalState/AiAttackState.cs
@@ -0,0 +1,68 @@
+using Godot;
+
+namespace NnormalState;
+
+public class AiAttackState : StateBase
+{
+ //上一个状态
+ public AINormalStateEnum PrevState;
+ //攻击步骤, 0.锁定目标, 1.执行攻击, 2.攻击完成
+ private byte _attackStep = 0;
+
+ public AiAttackState() : base(AINormalStateEnum.AiAttack)
+ {
+ }
+
+ public override void Enter(AINormalStateEnum prev, params object[] args)
+ {
+ if (Master.GetAttackTimer() > 0)
+ {
+ Debug.LogError("攻击冷却还未完成就进入了 AINormalStateEnum.AiAttack 状态!");
+ ChangeState(prev);
+ }
+ _attackStep = 0;
+ PrevState = prev;
+ Master.AnimationPlayer.AnimationFinished += OnAnimationFinished;
+ }
+
+ public override void Exit(AINormalStateEnum next)
+ {
+ Master.AnimationPlayer.AnimationFinished -= OnAnimationFinished;
+ }
+
+ public override void Process(float delta)
+ {
+ if (_attackStep == 0) //锁定目标步骤
+ {
+ if (Master.GetLockRemainderTime() > 0) //锁定目标时间
+ {
+ if (!Master.AttackAttribute.FiringStand && !Master.NavigationAgent2D.IsNavigationFinished())
+ {
+ //移动
+ Master.DoMove();
+ }
+ else
+ {
+ //站立
+ Master.DoIdle();
+ }
+ }
+ else
+ {
+ _attackStep = 1;
+ }
+ }
+ else if (_attackStep == 1) //攻击步骤
+ {
+ Master.BasisVelocity = Vector2.Zero;
+ Master.AnimationPlayer.Play(AnimatorNames.Attack);
+ _attackStep = 2;
+ }
+
+ }
+
+ public void OnAnimationFinished(StringName name)
+ {
+ ChangeState(PrevState);
+ }
+}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/normalState/AiFollowUpState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/normalState/AiFollowUpState.cs
index b0185de..5fe2add 100644
--- a/DungeonShooting_Godot/src/game/activity/role/enemy/normalState/AiFollowUpState.cs
+++ b/DungeonShooting_Godot/src/game/activity/role/enemy/normalState/AiFollowUpState.cs
@@ -37,9 +37,8 @@
{
_navigationUpdateTimer -= delta;
}
-
- var masterPosition = Master.GlobalPosition;
- var distanceSquared = masterPosition.DistanceSquaredTo(playerPos);
+
+ var distanceSquared = Master.GlobalPosition.DistanceSquaredTo(playerPos);
//是否在攻击范围内
var inAttackRange = distanceSquared <= Mathf.Pow(Master.GetAttackRange(), 2);
@@ -48,23 +47,13 @@
if (!Master.NavigationAgent2D.IsNavigationFinished())
{
- if (Master.AttackState != AiAttackState.LockingTime && Master.AttackState != AiAttackState.Attack)
- {
- //计算移动
- var nextPos = Master.NavigationAgent2D.GetNextPathPosition();
- Master.AnimatedSprite.Play(AnimatorNames.Run);
- Master.BasisVelocity = (nextPos - masterPosition - Master.NavigationPoint.Position).Normalized() *
- Master.RoleState.MoveSpeed;
- }
- else
- {
- Master.AnimatedSprite.Play(AnimatorNames.Idle);
- Master.BasisVelocity = Vector2.Zero;
- }
+ //移动
+ Master.DoMove();
}
else
{
- Master.BasisVelocity = Vector2.Zero;
+ //站立
+ Master.DoIdle();
}
//检测玩家是否在视野内
@@ -79,20 +68,20 @@
Master.TargetInView = false;
}
- //在视野中, 或者锁敌状态下, 或者攻击状态下, 继续保持原本逻辑
- if (Master.TargetInView || Master.AttackState == AiAttackState.LockingTime || Master.AttackState == AiAttackState.Attack)
+ //在视野中
+ if (Master.TargetInView)
{
if (inAttackRange) //在攻击范围内
{
- //发起攻击
- //Master.AnimatedSprite.Play(AnimatorNames.Attack);
- Master.Attack();
-
//距离够近, 可以切换到环绕模式
if (distanceSquared <= Mathf.Pow(Master.GetAttackRange() * 0.7f, 2) * 0.7f)
{
ChangeState(AINormalStateEnum.AiSurround);
}
+ else if (Master.GetAttackTimer() <= 0) //攻击
+ {
+ ChangeState(AINormalStateEnum.AiAttack);
+ }
}
}
else //不在视野中
diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/normalState/AiLeaveForState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/normalState/AiLeaveForState.cs
new file mode 100644
index 0000000..9cd1c49
--- /dev/null
+++ b/DungeonShooting_Godot/src/game/activity/role/enemy/normalState/AiLeaveForState.cs
@@ -0,0 +1,89 @@
+
+using Godot;
+
+namespace NnormalState;
+
+///
+/// 收到其他敌人通知, 前往发现目标的位置
+///
+public class AiLeaveForState : StateBase
+{
+ //导航目标点刷新计时器
+ private float _navigationUpdateTimer = 0;
+ private float _navigationInterval = 0.3f;
+
+ public AiLeaveForState() : base(AINormalStateEnum.AiLeaveFor)
+ {
+ }
+
+ public override void Enter(AINormalStateEnum prev, params object[] args)
+ {
+ if (Master.World.Enemy_IsFindTarget)
+ {
+ Master.NavigationAgent2D.TargetPosition = Master.World.Enemy_FindTargetPosition;
+ }
+ else
+ {
+ ChangeState(prev);
+ }
+ }
+
+ public override void Process(float delta)
+ {
+ //这个状态下不会有攻击事件, 所以没必要每一帧检查是否弹药耗尽
+
+ //更新玩家位置
+ if (_navigationUpdateTimer <= 0)
+ {
+ //每隔一段时间秒更改目标位置
+ _navigationUpdateTimer = _navigationInterval;
+ Master.NavigationAgent2D.TargetPosition = Master.World.Enemy_FindTargetPosition;
+ }
+ else
+ {
+ _navigationUpdateTimer -= delta;
+ }
+
+ if (!Master.NavigationAgent2D.IsNavigationFinished())
+ {
+ Master.LookTargetPosition(Master.World.Enemy_FindTargetPosition);
+ //移动
+ Master.DoMove();
+ }
+ else
+ {
+ //站立
+ Master.DoIdle();
+ }
+
+ var playerPos = Player.Current.GetCenterPosition();
+ //检测玩家是否在视野内, 如果在, 则切换到 AiTargetInView 状态
+ if (Master.IsInTailAfterViewRange(playerPos))
+ {
+ if (!Master.TestViewRayCast(playerPos)) //看到玩家
+ {
+ //关闭射线检测
+ Master.TestViewRayCastOver();
+ //切换成发现目标状态
+ ChangeState(AINormalStateEnum.AiFollowUp);
+ return;
+ }
+ else
+ {
+ //关闭射线检测
+ Master.TestViewRayCastOver();
+ }
+ }
+
+ //移动到目标掉了, 还没发现目标
+ if (Master.NavigationAgent2D.IsNavigationFinished())
+ {
+ ChangeState(AINormalStateEnum.AiNormal);
+ }
+ }
+
+ public override void DebugDraw()
+ {
+ Master.DrawLine(Vector2.Zero, Master.ToLocal(Master.NavigationAgent2D.TargetPosition), Colors.Yellow);
+ }
+}
diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/normalState/AiNormalState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/normalState/AiNormalState.cs
index e991e00..c2f2a32 100644
--- a/DungeonShooting_Godot/src/game/activity/role/enemy/normalState/AiNormalState.cs
+++ b/DungeonShooting_Godot/src/game/activity/role/enemy/normalState/AiNormalState.cs
@@ -94,37 +94,31 @@
_pauseTimer = Utils.Random.RandomRangeFloat(0.3f, 2f);
_isMoveOver = true;
_moveFlag = false;
- Master.BasisVelocity = Vector2.Zero;
+ Master.DoIdle();
}
else if (!_moveFlag)
{
_moveFlag = true;
- var pos = Master.GlobalPosition;
- //计算移动
- var nextPos = Master.NavigationAgent2D.GetNextPathPosition();
- Master.AnimatedSprite.Play(AnimatorNames.Run);
- Master.BasisVelocity = (nextPos - pos - Master.NavigationPoint.Position).Normalized() *
- Master.RoleState.MoveSpeed;
+ var pos = Master.Position;
+ //移动
+ Master.DoMove();
_prevPos = pos;
}
else
{
- var pos = Master.GlobalPosition;
+ var pos = Master.Position;
var lastSlideCollision = Master.GetLastSlideCollision();
if (lastSlideCollision != null && lastSlideCollision.GetCollider() is AdvancedRole) //碰到其他角色
{
_pauseTimer = Utils.Random.RandomRangeFloat(0.1f, 0.5f);
_isMoveOver = true;
_moveFlag = false;
- Master.BasisVelocity = Vector2.Zero;
+ Master.DoIdle();
}
else
{
//计算移动
- var nextPos = Master.NavigationAgent2D.GetNextPathPosition();
- Master.AnimatedSprite.Play(AnimatorNames.Run);
- Master.BasisVelocity = (nextPos - pos - Master.NavigationPoint.Position).Normalized() *
- Master.RoleState.MoveSpeed;
+ Master.DoMove();
}
if (_prevPos.DistanceSquaredTo(pos) <= 0.01f)
diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/normalState/AiSurroundState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/normalState/AiSurroundState.cs
index b66e1fb..f2705bd 100644
--- a/DungeonShooting_Godot/src/game/activity/role/enemy/normalState/AiSurroundState.cs
+++ b/DungeonShooting_Godot/src/game/activity/role/enemy/normalState/AiSurroundState.cs
@@ -54,11 +54,8 @@
Master.TargetInView = false;
}
- //在视野中, 或者锁敌状态下, 或者攻击状态下, 继续保持原本逻辑
- if (Master.TargetInView ||
- (Master.FiringStand &&
- (Master.AttackState == AiAttackState.LockingTime || Master.AttackState == AiAttackState.Attack)
- ))
+ //在视野中
+ if (Master.TargetInView)
{
if (_pauseTimer >= 0)
{
@@ -72,7 +69,7 @@
}
else
{
- var masterPosition = Master.GlobalPosition;
+ var masterPosition = Master.Position;
if (_lockTimer >= 1) //卡在一个点超过一秒
{
RunOver(playerPos);
@@ -84,55 +81,38 @@
_pauseTimer = Utils.Random.RandomRangeFloat(0f, 0.5f);
_isMoveOver = true;
_moveFlag = false;
- Master.BasisVelocity = Vector2.Zero;
+ Master.DoIdle();
}
else if (!_moveFlag)
{
_moveFlag = true;
//计算移动
- var nextPos = Master.NavigationAgent2D.GetNextPathPosition();
- Master.AnimatedSprite.Play(AnimatorNames.Run);
- Master.BasisVelocity =
- (nextPos - masterPosition - Master.NavigationPoint.Position).Normalized() *
- Master.RoleState.MoveSpeed;
+ Master.DoMove();
}
else
{
- var pos = masterPosition;
var lastSlideCollision = Master.GetLastSlideCollision();
if (lastSlideCollision != null && lastSlideCollision.GetCollider() is AdvancedRole) //碰到其他角色
{
_pauseTimer = Utils.Random.RandomRangeFloat(0f, 0.3f);
_isMoveOver = true;
_moveFlag = false;
- Master.BasisVelocity = Vector2.Zero;
+ Master.DoIdle();
}
else
{
- //判断开火状态, 进行移动
- if (!Master.FiringStand ||
- (Master.AttackState != AiAttackState.LockingTime && Master.AttackState != AiAttackState.Attack))
- { //正常移动
- //计算移动
- var nextPos = Master.NavigationAgent2D.GetNextPathPosition();
- Master.AnimatedSprite.Play(AnimatorNames.Run);
- Master.BasisVelocity = (nextPos - pos - Master.NavigationPoint.Position).Normalized() *
- Master.RoleState.MoveSpeed;
- }
- else //站立不动
- {
- Master.AnimatedSprite.Play(AnimatorNames.Idle);
- Master.BasisVelocity = Vector2.Zero;
- }
+ //计算移动
+ Master.DoMove();
}
-
- if (_prevPos.DistanceSquaredTo(pos) <= 1 * delta)
+
+ if (_prevPos.DistanceSquaredTo(masterPosition) <= 1 * delta)
{
_lockTimer += delta;
}
else
{
- _prevPos = pos;
+ _lockTimer = 0;
+ _prevPos = masterPosition;
}
}
@@ -140,10 +120,9 @@
{
ChangeState(AINormalStateEnum.AiFollowUp);
}
- else
+ else if (Master.GetAttackTimer() <= 0) //发起攻击
{
- //发起攻击
- Master.Attack();
+ ChangeState(AINormalStateEnum.AiAttack);
}
}
}
diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/normalState/AiTailAfterState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/normalState/AiTailAfterState.cs
index fe894e2..f1a2646 100644
--- a/DungeonShooting_Godot/src/game/activity/role/enemy/normalState/AiTailAfterState.cs
+++ b/DungeonShooting_Godot/src/game/activity/role/enemy/normalState/AiTailAfterState.cs
@@ -54,23 +54,12 @@
if (!Master.NavigationAgent2D.IsNavigationFinished())
{
- if (Master.AttackState != AiAttackState.LockingTime && Master.AttackState != AiAttackState.Attack)
- {
- //计算移动
- var nextPos = Master.NavigationAgent2D.GetNextPathPosition();
- Master.AnimatedSprite.Play(AnimatorNames.Run);
- Master.BasisVelocity = (nextPos - Master.GlobalPosition - Master.NavigationPoint.Position).Normalized() *
- Master.RoleState.MoveSpeed;
- }
- else
- {
- Master.AnimatedSprite.Play(AnimatorNames.Idle);
- Master.BasisVelocity = Vector2.Zero;
- }
+ //移动
+ Master.DoMove();
}
else
{
- Master.BasisVelocity = Vector2.Zero;
+ Master.DoIdle();
}
//检测玩家是否在视野内, 如果在, 则切换到 AiTargetInView 状态
if (Master.IsInTailAfterViewRange(playerPos))
diff --git a/DungeonShooting_Godot/src/game/activity/weapon/Weapon.cs b/DungeonShooting_Godot/src/game/activity/weapon/Weapon.cs
index b3ff8a1..69fc6e7 100644
--- a/DungeonShooting_Godot/src/game/activity/weapon/Weapon.cs
+++ b/DungeonShooting_Godot/src/game/activity/weapon/Weapon.cs
@@ -894,7 +894,7 @@
}
///
- /// 获取攻击冷却计时时间, 等于 0 表示冷却完成
+ /// 获取攻击冷却计时时间, 小于等于 0 表示冷却完成
///
public float GetAttackTimer()
{
@@ -1906,45 +1906,45 @@
///
/// Ai 调用, 刷新 Ai 攻击状态并返回, 并不会调用相应的函数
///
- public AiAttackState AiRefreshAttackState()
+ public AiAttackEnum AiRefreshAttackState()
{
- AiAttackState flag;
+ AiAttackEnum flag;
if (IsTotalAmmoEmpty()) //当前武器弹药打空
{
//切换到有子弹的武器
var index = Master.WeaponPack.FindIndex((we, i) => !we.IsTotalAmmoEmpty());
if (index != -1)
{
- flag = AiAttackState.ExchangeWeapon;
+ flag = AiAttackEnum.ExchangeWeapon;
}
else //所有子弹打光
{
- flag = AiAttackState.NoAmmo;
+ flag = AiAttackEnum.NoAmmo;
}
}
else if (Reloading) //换弹中
{
- flag = AiAttackState.TriggerReload;
+ flag = AiAttackEnum.TriggerReload;
}
else if (IsAmmoEmpty()) //弹夹已经打空
{
- flag = AiAttackState.Reloading;
+ flag = AiAttackEnum.Reloading;
}
else if (_beLoadedState == 0 || _beLoadedState == -1) //需要上膛
{
- flag = AiAttackState.AttackInterval;
+ flag = AiAttackEnum.AttackInterval;
}
else if (_beLoadedState == 1) //上膛中
{
- flag = AiAttackState.AttackInterval;
+ flag = AiAttackEnum.AttackInterval;
}
else if (_continuousCount >= 1) //连发中
{
- flag = AiAttackState.Attack;
+ flag = AiAttackEnum.Attack;
}
else if (IsAttackIntervalTime()) //开火间隙
{
- flag = AiAttackState.AttackInterval;
+ flag = AiAttackEnum.AttackInterval;
}
else
{
@@ -1953,23 +1953,23 @@
{
if (GetDelayedAttackTime() > 0)
{
- flag = AiAttackState.Attack;
+ flag = AiAttackEnum.Attack;
}
else
{
if (Attribute.ContinuousShoot) //连发
{
- flag = AiAttackState.Attack;
+ flag = AiAttackEnum.Attack;
}
else //单发
{
- flag = AiAttackState.Attack;
+ flag = AiAttackEnum.Attack;
}
}
}
else //锁定时间没到
{
- flag = AiAttackState.LockingTime;
+ flag = AiAttackEnum.LockingTime;
}
}
@@ -1979,35 +1979,35 @@
///
/// Ai调用, 触发扣动扳机, 并返回攻击状态
///
- public AiAttackState AiTriggerAttackState()
+ public AiAttackEnum AiTriggerAttackState()
{
- AiAttackState flag;
+ AiAttackEnum flag;
if (IsTotalAmmoEmpty()) //当前武器弹药打空
{
//切换到有子弹的武器
var index = Master.WeaponPack.FindIndex((we, i) => !we.IsTotalAmmoEmpty());
if (index != -1)
{
- flag = AiAttackState.ExchangeWeapon;
+ flag = AiAttackEnum.ExchangeWeapon;
Master.WeaponPack.ExchangeByIndex(index);
}
else //所有子弹打光
{
- flag = AiAttackState.NoAmmo;
+ flag = AiAttackEnum.NoAmmo;
}
}
else if (Reloading) //换弹中
{
- flag = AiAttackState.TriggerReload;
+ flag = AiAttackEnum.TriggerReload;
}
else if (IsAmmoEmpty()) //弹夹已经打空
{
- flag = AiAttackState.Reloading;
+ flag = AiAttackEnum.Reloading;
Reload();
}
else if (_beLoadedState == 0 || _beLoadedState == -1) //需要上膛
{
- flag = AiAttackState.AttackInterval;
+ flag = AiAttackEnum.AttackInterval;
if (_attackTimer <= 0)
{
Master.Attack();
@@ -2015,15 +2015,15 @@
}
else if (_beLoadedState == 1) //上膛中
{
- flag = AiAttackState.AttackInterval;
+ flag = AiAttackEnum.AttackInterval;
}
else if (_continuousCount >= 1) //连发中
{
- flag = AiAttackState.Attack;
+ flag = AiAttackEnum.Attack;
}
else if (IsAttackIntervalTime()) //开火间隙
{
- flag = AiAttackState.AttackInterval;
+ flag = AiAttackEnum.AttackInterval;
}
else
{
@@ -2032,7 +2032,7 @@
{
if (GetDelayedAttackTime() > 0)
{
- flag = AiAttackState.Attack;
+ flag = AiAttackEnum.Attack;
enemy.Attack();
if (_attackFlag)
{
@@ -2043,7 +2043,7 @@
{
if (Attribute.ContinuousShoot) //连发
{
- flag = AiAttackState.Attack;
+ flag = AiAttackEnum.Attack;
enemy.Attack();
if (_attackFlag)
{
@@ -2052,7 +2052,7 @@
}
else //单发
{
- flag = AiAttackState.Attack;
+ flag = AiAttackEnum.Attack;
enemy.Attack();
if (_attackFlag)
{
@@ -2063,7 +2063,7 @@
}
else //锁定时间没到
{
- flag = AiAttackState.LockingTime;
+ flag = AiAttackEnum.LockingTime;
}
}