diff --git a/DungeonShooting_Godot/prefab/role/Enemy0001.tscn b/DungeonShooting_Godot/prefab/role/Enemy0001.tscn index deb7e34..7eac0c4 100644 --- a/DungeonShooting_Godot/prefab/role/Enemy0001.tscn +++ b/DungeonShooting_Godot/prefab/role/Enemy0001.tscn @@ -32,6 +32,7 @@ [sub_resource type="Animation" id="Animation_nb4pe"] resource_name = "astonished" length = 0.6 +step = 0.05 tracks/0/type = "value" tracks/0/imported = false tracks/0/enabled = true @@ -56,6 +57,42 @@ "update": 1, "values": [ExtResource("5_0p4q8")] } +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("AnimatedSprite:scale") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0, 0.05, 0.15, 0.25, 0.35, 0.45), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(0.8, 0.8), Vector2(1.2, 1.2), Vector2(0.9, 0.9), Vector2(1.1, 1.1), Vector2(1, 1)] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("TipSprite:modulate") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0, 0.1, 0.5, 0.6), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Color(1, 1, 1, 0), Color(1, 1, 1, 1), Color(1, 1, 1, 1), Color(1, 1, 1, 0)] +} +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("TipSprite:position") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0, 0.2, 0.45, 0.6), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(0, -22), Vector2(0, -28), Vector2(0, -28), Vector2(0, -35)] +} [sub_resource type="Animation" id="Animation_0l5k0"] length = 0.001 @@ -83,6 +120,42 @@ "update": 1, "values": [ExtResource("5_0p4q8")] } +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("AnimatedSprite:scale") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("TipSprite:modulate") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Color(1, 1, 1, 0)] +} +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("TipSprite:position") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(0, -22)] +} [sub_resource type="Animation" id="Animation_5mflw"] resource_name = "notify" @@ -146,7 +219,8 @@ sprite_frames = ExtResource("4_qv8w5") [node name="TipSprite" parent="." index="9"] -position = Vector2(0, -28) +modulate = Color(1, 1, 1, 0) +position = Vector2(0, -22) [node name="AnimationPlayer" parent="." index="10"] libraries = { diff --git a/DungeonShooting_Godot/prefab/role/template/AdvancedEnemyTemplate.tscn b/DungeonShooting_Godot/prefab/role/template/AdvancedEnemyTemplate.tscn index e622500..58209e0 100644 --- a/DungeonShooting_Godot/prefab/role/template/AdvancedEnemyTemplate.tscn +++ b/DungeonShooting_Godot/prefab/role/template/AdvancedEnemyTemplate.tscn @@ -35,6 +35,8 @@ [node name="AnimatedSprite" parent="." index="2"] material = SubResource("ShaderMaterial_k8mt5") +position = Vector2(0, 0) +offset = Vector2(0, -12) [node name="ViewRay" type="RayCast2D" parent="." index="6"] position = Vector2(0, -8) diff --git a/DungeonShooting_Godot/prefab/role/template/AdvancedRoleTemplate.tscn b/DungeonShooting_Godot/prefab/role/template/AdvancedRoleTemplate.tscn index 9e6bb5f..3874d8b 100644 --- a/DungeonShooting_Godot/prefab/role/template/AdvancedRoleTemplate.tscn +++ b/DungeonShooting_Godot/prefab/role/template/AdvancedRoleTemplate.tscn @@ -46,7 +46,7 @@ [node name="AnimatedSprite" type="AnimatedSprite2D" parent="."] material = SubResource("ShaderMaterial_yif6x") -position = Vector2(0, -12) +offset = Vector2(0, -12) [node name="Collision" type="CollisionShape2D" parent="."] position = Vector2(0, -4) diff --git a/DungeonShooting_Godot/prefab/role/template/RoleTemplate.tscn b/DungeonShooting_Godot/prefab/role/template/RoleTemplate.tscn index 454bcbd..b001cfc 100644 --- a/DungeonShooting_Godot/prefab/role/template/RoleTemplate.tscn +++ b/DungeonShooting_Godot/prefab/role/template/RoleTemplate.tscn @@ -42,7 +42,7 @@ [node name="AnimatedSprite" type="AnimatedSprite2D" parent="."] material = SubResource("ShaderMaterial_yif6x") -position = Vector2(0, -12) +offset = Vector2(0, -12) [node name="Collision" type="CollisionShape2D" parent="."] position = Vector2(0, -4) diff --git a/DungeonShooting_Godot/resource/sprite/role/common/Role_astonished.png b/DungeonShooting_Godot/resource/sprite/role/common/Role_astonished.png new file mode 100644 index 0000000..6ba090b --- /dev/null +++ b/DungeonShooting_Godot/resource/sprite/role/common/Role_astonished.png Binary files differ diff --git a/DungeonShooting_Godot/resource/sprite/role/common/Role_astonished.png.import b/DungeonShooting_Godot/resource/sprite/role/common/Role_astonished.png.import new file mode 100644 index 0000000..6eb2d0d --- /dev/null +++ b/DungeonShooting_Godot/resource/sprite/role/common/Role_astonished.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b75k7hefqy3tm" +path="res://.godot/imported/Role_astonished.png-8166b8786411283003a535d1677d0104.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://resource/sprite/role/common/Role_astonished.png" +dest_files=["res://.godot/imported/Role_astonished.png-8166b8786411283003a535d1677d0104.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/DungeonShooting_Godot/resource/sprite/role/common/Role_notify.png b/DungeonShooting_Godot/resource/sprite/role/common/Role_notify.png new file mode 100644 index 0000000..b93ffca --- /dev/null +++ b/DungeonShooting_Godot/resource/sprite/role/common/Role_notify.png Binary files differ diff --git a/DungeonShooting_Godot/resource/sprite/role/common/Role_notify.png.import b/DungeonShooting_Godot/resource/sprite/role/common/Role_notify.png.import new file mode 100644 index 0000000..0bd8a72 --- /dev/null +++ b/DungeonShooting_Godot/resource/sprite/role/common/Role_notify.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://6jka6itu76x7" +path="res://.godot/imported/Role_notify.png-be3f9ba9bf6d85ab3633bbe6cbe960e3.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://resource/sprite/role/common/Role_notify.png" +dest_files=["res://.godot/imported/Role_notify.png-be3f9ba9bf6d85ab3633bbe6cbe960e3.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs b/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs index 162153c..b4bfe60 100644 --- a/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs +++ b/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs @@ -18,6 +18,11 @@ public static bool IsDebug { get; set; } /// + /// 实例唯一 Id + /// + public long Id { get; set; } + + /// /// 当前物体对应的配置数据, 如果不是通过 ActivityObject.Create() 函数创建出来的对象那么 ItemConfig 为 null /// public ExcelConfig.ActivityBase ActivityBase { get; private set; } @@ -361,6 +366,7 @@ World = world; ActivityBase = config; Name = GetType().Name + (_instanceIndex++); + Id = _instanceIndex; _blendShaderMaterial = AnimatedSprite.Material as ShaderMaterial; _shadowBlendShaderMaterial = ShadowSprite.Material as ShaderMaterial; if (_blendShaderMaterial != null) @@ -1333,6 +1339,8 @@ /// public void CalcShadowTransform() { + //偏移 + ShadowSprite.Offset = AnimatedSprite.Offset; //缩放 ShadowSprite.Scale = AnimatedSprite.Scale; //阴影角度 diff --git a/DungeonShooting_Godot/src/framework/map/room/RoomInfo.cs b/DungeonShooting_Godot/src/framework/map/room/RoomInfo.cs index a249dda..39bb1f9 100644 --- a/DungeonShooting_Godot/src/framework/map/room/RoomInfo.cs +++ b/DungeonShooting_Godot/src/framework/map/room/RoomInfo.cs @@ -104,6 +104,11 @@ /// 是否处于闭关状态, 也就是房间门没有主动打开 /// public bool IsSeclusion { get; private set; } = false; + + /// + /// 用于标记攻击目标位置 + /// + public Dictionary MarkTargetPosition { get; private set; } = new Dictionary(); public bool IsDestroyed { get; private set; } private bool _openDoorFlag = true; @@ -340,6 +345,8 @@ { AffiliationArea.Destroy(); } + + MarkTargetPosition.Clear(); } /// diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/AdvancedEnemy.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/AdvancedEnemy.cs index f93a65f..97dc009 100644 --- a/DungeonShooting_Godot/src/game/activity/role/enemy/AdvancedEnemy.cs +++ b/DungeonShooting_Godot/src/game/activity/role/enemy/AdvancedEnemy.cs @@ -459,4 +459,15 @@ AnimatedSprite.Play(AnimatorNames.Idle); BasisVelocity = Vector2.Zero; } + + /// + /// 更新房间中标记的目标位置 + /// + public void UpdateMarkTargetPosition() + { + if (LookTarget != null) + { + AffiliationArea.RoomInfo.MarkTargetPosition[LookTarget.Id] = LookTarget.Position; + } + } } diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiAttackState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiAttackState.cs index 7d8b30d..f49c137 100644 --- a/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiAttackState.cs +++ b/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiAttackState.cs @@ -74,6 +74,9 @@ public override void Process(float delta) { + //更新标记位置 + Master.UpdateMarkTargetPosition(); + var weapon = Master.WeaponPack.ActiveItem; if (weapon == null) { @@ -116,7 +119,7 @@ if (AttackState == AiAttackEnum.LockingTime) //锁定玩家状态 { Master.LockTargetTime += delta; - + var aiLockRemainderTime = Master.GetLockRemainderTime(); Master.MountLookTarget = aiLockRemainderTime >= weapon.Attribute.AiAttackAttr.LockAngleTime; //更新瞄准辅助线 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 6d7f141..4a602a8 100644 --- a/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiFollowUpState.cs +++ b/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiFollowUpState.cs @@ -97,6 +97,8 @@ //在视野中 if (Master.TargetInView) { + //更新标记位置 + Master.UpdateMarkTargetPosition(); if (inAttackRange) //在攻击范围内 { //距离够近, 可以切换到环绕模式 diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiLeaveForState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiLeaveForState.cs index 16fc162..058b053 100644 --- a/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiLeaveForState.cs +++ b/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiLeaveForState.cs @@ -46,16 +46,6 @@ } } - /// - /// 设置移动目标位置 - /// - public void SetTargetPosition(Vector2 target) - { - _targetPosition = target; - _navigationUpdateTimer = _navigationInterval; - Master.NavigationAgent2D.TargetPosition = target; - } - public override void Process(float delta) { //这个状态下不会有攻击事件, 所以没必要每一帧检查是否弹药耗尽 @@ -65,6 +55,10 @@ { //每隔一段时间秒更改目标位置 _navigationUpdateTimer = _navigationInterval; + if (Master.AffiliationArea.RoomInfo.MarkTargetPosition.TryGetValue(_target.Id, out var pos)) + { + _targetPosition = pos; + } Master.NavigationAgent2D.TargetPosition = _targetPosition; } else 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 6faee7a..875d365 100644 --- a/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiSurroundState.cs +++ b/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiSurroundState.cs @@ -73,6 +73,9 @@ //在视野中 if (Master.TargetInView) { + //更新标记位置 + Master.UpdateMarkTargetPosition(); + if (_pauseTimer >= 0) { Master.AnimatedSprite.Play(AnimatorNames.Idle);