diff --git a/DungeonShooting_Art/effect/KnifeHit1.aseprite b/DungeonShooting_Art/effect/KnifeHit1.aseprite
new file mode 100644
index 0000000..b13a3d7
--- /dev/null
+++ b/DungeonShooting_Art/effect/KnifeHit1.aseprite
Binary files differ
diff --git a/DungeonShooting_Godot/prefab/FanCollisionShape.tscn b/DungeonShooting_Godot/prefab/FanCollisionShape.tscn
new file mode 100644
index 0000000..b810a3e
--- /dev/null
+++ b/DungeonShooting_Godot/prefab/FanCollisionShape.tscn
@@ -0,0 +1,4 @@
+[gd_scene format=2]
+
+[node name="FanCollisionShape" type="CollisionPolygon2D"]
+polygon = PoolVector2Array( 0, -10, 5, -9, 9, -5, 10, 0, 9, 5, 5, 9, 0, 10 )
diff --git a/DungeonShooting_Godot/prefab/effect/Hit.tscn b/DungeonShooting_Godot/prefab/effect/Hit.tscn
index 1549fc4..26e0459 100644
--- a/DungeonShooting_Godot/prefab/effect/Hit.tscn
+++ b/DungeonShooting_Godot/prefab/effect/Hit.tscn
@@ -1,23 +1,11 @@
-[gd_scene load_steps=8 format=2]
+[gd_scene load_steps=3 format=2]
-[ext_resource path="res://resource/sprite/effect/hit/hit2.png" type="Texture" id=1]
-[ext_resource path="res://resource/sprite/effect/hit/hit1.png" type="Texture" id=2]
-[ext_resource path="res://resource/sprite/effect/hit/hit4.png" type="Texture" id=3]
-[ext_resource path="res://resource/sprite/effect/hit/hit0.png" type="Texture" id=4]
-[ext_resource path="res://resource/sprite/effect/hit/hit3.png" type="Texture" id=5]
+[ext_resource path="res://resource/effects/Hit.tres" type="SpriteFrames" id=1]
[ext_resource path="res://src/game/effect/Hit.cs" type="Script" id=6]
-[sub_resource type="SpriteFrames" id=1]
-animations = [ {
-"frames": [ ExtResource( 4 ), ExtResource( 2 ), ExtResource( 1 ), ExtResource( 5 ), ExtResource( 3 ) ],
-"loop": true,
-"name": "Hit",
-"speed": 20.0
-} ]
-
[node name="Hit" type="AnimatedSprite"]
z_index = 5
-frames = SubResource( 1 )
+frames = ExtResource( 1 )
animation = "Hit"
offset = Vector2( 1, 11 )
script = ExtResource( 6 )
diff --git a/DungeonShooting_Godot/prefab/role/Enemy.tscn b/DungeonShooting_Godot/prefab/role/Enemy.tscn
index c4fd32f..b24c830 100644
--- a/DungeonShooting_Godot/prefab/role/Enemy.tscn
+++ b/DungeonShooting_Godot/prefab/role/Enemy.tscn
@@ -23,7 +23,7 @@
[node name="AnimatedSprite" parent="." index="2"]
material = SubResource( 2 )
-frame = 0
+frame = 2
[node name="ViewRay" type="RayCast2D" parent="." index="7"]
position = Vector2( 0, -8 )
diff --git a/DungeonShooting_Godot/prefab/weapon/Knife.tscn b/DungeonShooting_Godot/prefab/weapon/Knife.tscn
index 5e94459..d5628c3 100644
--- a/DungeonShooting_Godot/prefab/weapon/Knife.tscn
+++ b/DungeonShooting_Godot/prefab/weapon/Knife.tscn
@@ -1,7 +1,9 @@
-[gd_scene load_steps=5 format=2]
+[gd_scene load_steps=8 format=2]
[ext_resource path="res://prefab/weapon/Weapon.tscn" type="PackedScene" id=1]
+[ext_resource path="res://resource/sprite/gun/knife1.png" type="Texture" id=2]
[ext_resource path="res://resource/materlal/Blend.gdshader" type="Shader" id=3]
+[ext_resource path="res://prefab/FanCollisionShape.tscn" type="PackedScene" id=4]
[sub_resource type="ShaderMaterial" id=2]
resource_local_to_scene = true
@@ -15,6 +17,14 @@
shader_param/shadowColor = Color( 1, 1, 1, 1 )
shader_param/schedule = 0.0
+[sub_resource type="SpriteFrames" id=4]
+animations = [ {
+"frames": [ ExtResource( 2 ) ],
+"loop": true,
+"name": "default",
+"speed": 5.0
+} ]
+
[node name="Knife" instance=ExtResource( 1 )]
[node name="ShadowSprite" parent="." index="0"]
@@ -23,3 +33,14 @@
[node name="AnimatedSprite" parent="." index="1"]
material = SubResource( 3 )
position = Vector2( 0, 0 )
+frames = SubResource( 4 )
+
+[node name="HitArea" type="Area2D" parent="." index="4"]
+collision_layer = 0
+collision_mask = 0
+monitoring = false
+monitorable = false
+
+[node name="FanCollisionShape" parent="HitArea" index="0" instance=ExtResource( 4 )]
+rotation = -1.5708
+scale = Vector2( 3, 3 )
diff --git a/DungeonShooting_Godot/resource/effects/KnifeHit1.tres b/DungeonShooting_Godot/resource/effects/KnifeHit1.tres
new file mode 100644
index 0000000..70f5cf8
--- /dev/null
+++ b/DungeonShooting_Godot/resource/effects/KnifeHit1.tres
@@ -0,0 +1,35 @@
+[gd_resource type="SpriteFrames" load_steps=8 format=2]
+
+[ext_resource path="res://resource/sprite/effect/KnifeHit1.png" type="Texture" id=1]
+
+[sub_resource type="AtlasTexture" id=1]
+atlas = ExtResource( 1 )
+region = Rect2( 0, 0, 64, 68 )
+
+[sub_resource type="AtlasTexture" id=2]
+atlas = ExtResource( 1 )
+region = Rect2( 64, 0, 64, 68 )
+
+[sub_resource type="AtlasTexture" id=3]
+atlas = ExtResource( 1 )
+region = Rect2( 128, 0, 64, 68 )
+
+[sub_resource type="AtlasTexture" id=4]
+atlas = ExtResource( 1 )
+region = Rect2( 192, 0, 64, 68 )
+
+[sub_resource type="AtlasTexture" id=5]
+atlas = ExtResource( 1 )
+region = Rect2( 256, 0, 64, 68 )
+
+[sub_resource type="AtlasTexture" id=6]
+atlas = ExtResource( 1 )
+region = Rect2( 320, 0, 64, 68 )
+
+[resource]
+animations = [ {
+"frames": [ SubResource( 1 ), SubResource( 2 ), SubResource( 3 ), SubResource( 4 ), SubResource( 5 ), SubResource( 6 ) ],
+"loop": true,
+"name": "default",
+"speed": 30.0
+} ]
diff --git a/DungeonShooting_Godot/resource/sprite/effect/KnifeHit1.aseprite b/DungeonShooting_Godot/resource/sprite/effect/KnifeHit1.aseprite
new file mode 100644
index 0000000..8a8a0e3
--- /dev/null
+++ b/DungeonShooting_Godot/resource/sprite/effect/KnifeHit1.aseprite
Binary files differ
diff --git a/DungeonShooting_Godot/resource/sprite/effect/KnifeHit1.png b/DungeonShooting_Godot/resource/sprite/effect/KnifeHit1.png
new file mode 100644
index 0000000..0c07004
--- /dev/null
+++ b/DungeonShooting_Godot/resource/sprite/effect/KnifeHit1.png
Binary files differ
diff --git a/DungeonShooting_Godot/resource/sprite/effect/KnifeHit1.png.import b/DungeonShooting_Godot/resource/sprite/effect/KnifeHit1.png.import
new file mode 100644
index 0000000..626d1a0
--- /dev/null
+++ b/DungeonShooting_Godot/resource/sprite/effect/KnifeHit1.png.import
@@ -0,0 +1,35 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/KnifeHit1.png-8ec1b83e3e29bcb0e825de1a30fc9c75.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://resource/sprite/effect/KnifeHit1.png"
+dest_files=[ "res://.import/KnifeHit1.png-8ec1b83e3e29bcb0e825de1a30fc9c75.stex" ]
+
+[params]
+
+compress/mode=0
+compress/lossy_quality=0.7
+compress/hdr_mode=0
+compress/bptc_ldr=0
+compress/normal_map=0
+flags/repeat=0
+flags/filter=false
+flags/mipmaps=false
+flags/anisotropic=false
+flags/srgb=2
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/HDR_as_SRGB=false
+process/invert_color=false
+process/normal_map_invert_y=false
+stream=false
+size_limit=0
+detect_3d=false
+svg/scale=1.0
diff --git a/DungeonShooting_Godot/src/game/item/weapon/Weapon.cs b/DungeonShooting_Godot/src/game/item/weapon/Weapon.cs
index 438910a..5ef38fb 100644
--- a/DungeonShooting_Godot/src/game/item/weapon/Weapon.cs
+++ b/DungeonShooting_Godot/src/game/item/weapon/Weapon.cs
@@ -117,9 +117,7 @@
///
public bool IsActive => Master != null && Master.Holster.ActiveWeapon == this;
-
-
-
+
//--------------------------------------------------------------------------------------------
//是否按下
@@ -629,6 +627,15 @@
}
///
+ /// 获取武器攻击的目标层级
+ ///
+ ///
+ public uint GetAttackLayer()
+ {
+ return Master != null ? Master.AttackLayer : Role.DefaultAttackLayer;
+ }
+
+ ///
/// 返回弹药是否到达上限
///
public bool IsFullAmmo()
diff --git a/DungeonShooting_Godot/src/game/item/weapon/bullet/Bullet.cs b/DungeonShooting_Godot/src/game/item/weapon/bullet/Bullet.cs
index 048e65d..22e46ae 100644
--- a/DungeonShooting_Godot/src/game/item/weapon/bullet/Bullet.cs
+++ b/DungeonShooting_Godot/src/game/item/weapon/bullet/Bullet.cs
@@ -55,7 +55,7 @@
{
if (other is Role role)
{
- role.Hit(1);
+ role.Hurt(1);
}
//播放受击动画
diff --git a/DungeonShooting_Godot/src/game/item/weapon/gun/Gun.cs b/DungeonShooting_Godot/src/game/item/weapon/gun/Gun.cs
index c0eecc8..7a394ca 100644
--- a/DungeonShooting_Godot/src/game/item/weapon/gun/Gun.cs
+++ b/DungeonShooting_Godot/src/game/item/weapon/gun/Gun.cs
@@ -120,7 +120,7 @@
Utils.RandRange(Attribute.MinDistance, Attribute.MaxDistance),
FirePoint.GlobalPosition,
fireRotation,
- Master != null ? Master.AttackLayer : Role.DefaultAttackLayer
+ GetAttackLayer()
);
bullet.PutDown();
}
diff --git a/DungeonShooting_Godot/src/game/item/weapon/gun/Shotgun.cs b/DungeonShooting_Godot/src/game/item/weapon/gun/Shotgun.cs
index e571048..4763747 100644
--- a/DungeonShooting_Godot/src/game/item/weapon/gun/Shotgun.cs
+++ b/DungeonShooting_Godot/src/game/item/weapon/gun/Shotgun.cs
@@ -88,7 +88,7 @@
Utils.RandRange(Attribute.MinDistance, Attribute.MaxDistance),
FirePoint.GlobalPosition,
fireRotation + Utils.RandRange(-20 / 180f * Mathf.Pi, 20 / 180f * Mathf.Pi),
- Master != null ? Master.AttackLayer : Role.DefaultAttackLayer
+ GetAttackLayer()
);
bullet.PutDown();
}
diff --git a/DungeonShooting_Godot/src/game/item/weapon/knife/Knife.cs b/DungeonShooting_Godot/src/game/item/weapon/knife/Knife.cs
index 23c9ba2..72f0e7e 100644
--- a/DungeonShooting_Godot/src/game/item/weapon/knife/Knife.cs
+++ b/DungeonShooting_Godot/src/game/item/weapon/knife/Knife.cs
@@ -26,26 +26,68 @@
MaxBacklash = -8;
MinBacklash = -8;
BacklashRegressionSpeed = 24;
- UpliftAngle = -90;
+ UpliftAngle = -95;
}
}
+
+ private Area2D _hitArea;
+
+ private int _attackIndex = 0;
public Knife(string id, WeaponAttribute attribute) : base(id, attribute)
{
-
+ _hitArea = GetNode("HitArea");
+ _hitArea.Monitoring = false;
+ _hitArea.Monitorable = false;
+
+ _hitArea.Connect("body_entered", this, nameof(OnBodyEntered));
}
-
+
+ public override void _Process(float delta)
+ {
+ base._Process(delta);
+
+ if (IsActive)
+ {
+ //让碰撞节点与武器挂载节点位置保持一致, 而不跟着武器走
+ _hitArea.GlobalPosition = Master.MountPoint.GlobalPosition;
+ }
+ }
+
+ public override void _PhysicsProcess(float delta)
+ {
+ base._PhysicsProcess(delta);
+
+ //过去两个物理帧后就能关闭碰撞了
+ if (++_attackIndex >= 2)
+ {
+ _hitArea.Monitoring = false;
+ }
+ }
+
protected override void OnStartCharge()
{
+ //开始蓄力时武器角度上抬120度
RotationDegrees = -120;
}
protected override void OnFire()
{
GD.Print("近战武器攻击! 蓄力时长: " + GetTriggerChargeTime() + ", 扳机按下时长: " + GetTriggerDownTime());
+ //更新碰撞层级
+ _hitArea.CollisionMask = GetAttackLayer();
+ //启用碰撞
+ _hitArea.Monitoring = true;
+ _attackIndex = 0;
+
+ if (IsActive) //被使用
+ {
+ //播放挥刀特效
+ SpecialEffectManager.Play(ResourcePath.resource_effects_KnifeHit1_tres, "default",
+ Master.MountPoint.GlobalPosition, GlobalRotation + Mathf.Pi * 0.5f, new Vector2(0.8f * (int)Master.Face, 0.8f), new Vector2(17, 4), 1);
+ }
- //这里写播放挥刀特效和碰撞检测代码
-
+
if (Master == GameApplication.Instance.Room.Player)
{
//创建抖动
@@ -63,4 +105,17 @@
//这里要做判断, 如果没有碰到敌人, 则不消耗弹药 (耐久)
return 0;
}
+
+ private void OnBodyEntered(Node2D body)
+ {
+ GD.Print("碰到物体: " + body.Name);
+ var activityObject = body.AsActivityObject();
+ if (activityObject != null)
+ {
+ if (activityObject is Role role)
+ {
+ role.Hurt(1);
+ }
+ }
+ }
}
diff --git a/DungeonShooting_Godot/src/game/manager/ResourcePath.cs b/DungeonShooting_Godot/src/game/manager/ResourcePath.cs
index 02d93ff..893d355 100644
--- a/DungeonShooting_Godot/src/game/manager/ResourcePath.cs
+++ b/DungeonShooting_Godot/src/game/manager/ResourcePath.cs
@@ -10,6 +10,7 @@
public const string editor_prefabs_CodeHintPanel_tscn = "res://editor/prefabs/CodeHintPanel.tscn";
public const string editor_prefabs_CodePanel_tscn = "res://editor/prefabs/CodePanel.tscn";
public const string editor_prefabs_Editor_tscn = "res://editor/prefabs/Editor.tscn";
+ public const string prefab_FanCollisionShape_tscn = "res://prefab/FanCollisionShape.tscn";
public const string prefab_effect_FirePart_tscn = "res://prefab/effect/FirePart.tscn";
public const string prefab_effect_Hit_tscn = "res://prefab/effect/Hit.tscn";
public const string prefab_role_CPlusPlus_tscn = "res://prefab/role/CPlusPlus.tscn";
@@ -26,6 +27,7 @@
public const string prefab_weapon_bullet_Bullet_tscn = "res://prefab/weapon/bullet/Bullet.tscn";
public const string prefab_weapon_shell_ShellCase_tscn = "res://prefab/weapon/shell/ShellCase.tscn";
public const string resource_effects_Hit_tres = "res://resource/effects/Hit.tres";
+ public const string resource_effects_KnifeHit1_tres = "res://resource/effects/KnifeHit1.tres";
public const string resource_font_cn_font_12_tres = "res://resource/font/cn_font_12.tres";
public const string resource_font_cn_font_18_tres = "res://resource/font/cn_font_18.tres";
public const string resource_font_cn_font_35_tres = "res://resource/font/cn_font_35.tres";
@@ -38,6 +40,7 @@
public const string resource_sprite_bullet_arrow_png = "res://resource/sprite/bullet/arrow.png";
public const string resource_sprite_bullet_bullet_png = "res://resource/sprite/bullet/bullet.png";
public const string resource_sprite_bullet_bullet2_png = "res://resource/sprite/bullet/bullet2.png";
+ public const string resource_sprite_effect_KnifeHit1_png = "res://resource/sprite/effect/KnifeHit1.png";
public const string resource_sprite_effect_Trajectory_png = "res://resource/sprite/effect/Trajectory.png";
public const string resource_sprite_effect_hit_hit0_png = "res://resource/sprite/effect/hit/hit0.png";
public const string resource_sprite_effect_hit_hit1_png = "res://resource/sprite/effect/hit/hit1.png";
diff --git a/DungeonShooting_Godot/src/game/manager/SpecialEffectManager.cs b/DungeonShooting_Godot/src/game/manager/SpecialEffectManager.cs
index f71a6a7..0f58ee7 100644
--- a/DungeonShooting_Godot/src/game/manager/SpecialEffectManager.cs
+++ b/DungeonShooting_Godot/src/game/manager/SpecialEffectManager.cs
@@ -42,7 +42,7 @@
}
///
- /// 在场景指定位置播放一个特效
+ /// 在场景指定位置播放一个特效, 特效必须是 SpriteFrames 类型
///
/// 特效SpriteFrames资源路径
/// 动画名称
@@ -53,7 +53,7 @@
/// 层级
/// 播放速度
/// 循环次数, 到达该次数特效停止播放
- public static void Play(string path, string animName, Vector2 pos, float rotation, Vector2 scale, Vector2 offset, int zIndex, float speed = 1, int loopCount = 1)
+ public static void Play(string path, string animName, Vector2 pos, float rotation, Vector2 scale, Vector2 offset, int zIndex = 0, float speed = 1, int loopCount = 1)
{
var spriteFrames = ResourceManager.Load(path);
diff --git a/DungeonShooting_Godot/src/game/role/FaceDirection.cs b/DungeonShooting_Godot/src/game/role/FaceDirection.cs
index b6f34a7..0ed5025 100644
--- a/DungeonShooting_Godot/src/game/role/FaceDirection.cs
+++ b/DungeonShooting_Godot/src/game/role/FaceDirection.cs
@@ -3,6 +3,6 @@
///
public enum FaceDirection
{
- Left,
- Right,
+ Left = -1,
+ Right = 1,
}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/role/Role.cs b/DungeonShooting_Godot/src/game/role/Role.cs
index 1cb7309..9336219 100644
--- a/DungeonShooting_Godot/src/game/role/Role.cs
+++ b/DungeonShooting_Godot/src/game/role/Role.cs
@@ -419,7 +419,7 @@
/// 受到伤害
///
/// 伤害的量
- public virtual void Hit(int damage)
+ public virtual void Hurt(int damage)
{
Hp -= damage;
AnimationPlayer.Stop();