Skip to content

Commit

Permalink
#16 Udemy 2.5D RPG Handle player attacks - make enemy attacks track p…
Browse files Browse the repository at this point in the history
…layer
  • Loading branch information
John Ludlow committed Oct 11, 2024
1 parent b5d5cad commit 8c7dfcc
Show file tree
Hide file tree
Showing 7 changed files with 122 additions and 46 deletions.
28 changes: 14 additions & 14 deletions Udemy25dRpg/Resources/Tiles.tres

Large diffs are not rendered by default.

10 changes: 6 additions & 4 deletions Udemy25dRpg/Scenes/Characters/CharacterBase.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using System;
using System.Linq;

using Godot;
Expand Down Expand Up @@ -40,9 +39,12 @@ public override void _Ready()

private void HurtboxAreaNode_AreaEntered(Area3D area)
{
var health = Stats.FirstOrDefault(st => st.StatType == StatType.Health);
var player = area.GetOwner<CharacterBase>();
health.StatValue -= player.Stats.FirstOrDefault(s => s.StatType == StatType.Strength)?.StatValue ?? 0;
var attacker = area.GetOwner<CharacterBase>();

var myHealth = Stats.FirstOrDefault(s => s.StatType == StatType.Health);
var attackStrength = attacker.Stats.FirstOrDefault(s => s.StatType == StatType.Strength);

myHealth.StatValue -= attackStrength?.StatValue ?? 0;
}

public Vector2 Direction { get; protected set; } = Vector2.Zero;
Expand Down
2 changes: 0 additions & 2 deletions Udemy25dRpg/Scenes/Characters/Enemy/Enemy.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
using Godot;

namespace Udemy25dRpg.Scenes.Characters.Enemy;

public partial class Enemy : CharacterBase
Expand Down
33 changes: 28 additions & 5 deletions Udemy25dRpg/Scenes/Characters/Enemy/Enemy.tscn
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
[gd_scene load_steps=111 format=3 uid="uid://26cy6bbsdt37"]
[gd_scene load_steps=115 format=3 uid="uid://26cy6bbsdt37"]

[ext_resource type="Texture2D" uid="uid://ckonrd67f8enh" path="res://Assets/Sprites/Characters/Enemy Knight/Attack/0_Demons_of_Darkness_Slashing_000.png" id="1_gty22"]
[ext_resource type="Texture2D" uid="uid://cjdjjbuattvtu" path="res://Assets/Sprites/Characters/Enemy Knight/Idle/0_Demons_of_Darkness_Idle_000.png" id="1_le6bp"]
[ext_resource type="Script" path="res://Scenes/Characters/Enemy/Enemy.cs" id="1_tph2b"]
[ext_resource type="Texture2D" uid="uid://b6a43k3p3mr14" path="res://Assets/Sprites/Characters/Enemy Knight/Idle/0_Demons_of_Darkness_Idle_001.png" id="2_1v34l"]
[ext_resource type="Texture2D" uid="uid://d264uonsup8d1" path="res://Assets/Sprites/Characters/Enemy Knight/Attack/0_Demons_of_Darkness_Slashing_001.png" id="2_rlvkw"]
[ext_resource type="Script" path="res://Resources/StatsResource.cs" id="2_rogkc"]
[ext_resource type="Texture2D" uid="uid://dl6cypbwp1oss" path="res://Assets/Sprites/Characters/Enemy Knight/Idle/0_Demons_of_Darkness_Idle_002.png" id="3_2ngr4"]
[ext_resource type="Texture2D" uid="uid://k7l2gwsrgurx" path="res://Assets/Sprites/Characters/Enemy Knight/Attack/0_Demons_of_Darkness_Slashing_002.png" id="3_glu1m"]
[ext_resource type="Texture2D" uid="uid://522cb61osffi" path="res://Assets/Sprites/Characters/Enemy Knight/Attack/0_Demons_of_Darkness_Slashing_003.png" id="4_03nvs"]
Expand Down Expand Up @@ -107,6 +108,16 @@
[ext_resource type="Script" path="res://Scenes/Characters/Enemy/EnemyChaseState.cs" id="105_pnbh4"]
[ext_resource type="Script" path="res://Scenes/Characters/Enemy/EnemyAttackState.cs" id="106_epu7y"]

[sub_resource type="Resource" id="Resource_pse8h"]
script = ExtResource("2_rogkc")
StatType = 0
StatValue = 20.0

[sub_resource type="Resource" id="Resource_yid00"]
script = ExtResource("2_rogkc")
StatType = 1
StatValue = 4.0

[sub_resource type="SpriteFrames" id="SpriteFrames_nl2d3"]
animations = [{
"frames": [{
Expand Down Expand Up @@ -440,27 +451,31 @@ height = 1.29953
radius = 6.0

[sub_resource type="SphereShape3D" id="SphereShape3D_e33me"]
radius = 1.4
radius = 1.0

[sub_resource type="BoxShape3D" id="BoxShape3D_07o6p"]
size = Vector3(0.5, 0.5, 0.5)

[node name="Enemy" type="CharacterBody3D" node_paths=PackedStringArray("StateMachineNode", "AnimatedSprite3DNode", "NavigationAgentNode", "ChaseAreaNode", "AttackAreaNode", "HurtboxAreaNode")]
[node name="Enemy" type="CharacterBody3D" node_paths=PackedStringArray("StateMachineNode", "AnimatedSprite3DNode", "NavigationAgentNode", "ChaseAreaNode", "AttackAreaNode", "HurtboxAreaNode", "HitboxAreaNode", "HitboxShapeNode")]
collision_layer = 4
collision_mask = 7
floor_max_angle = 1.55334
floor_snap_length = 100.0
script = ExtResource("1_tph2b")
Stats = [SubResource("Resource_pse8h"), SubResource("Resource_yid00")]
StateMachineNode = NodePath("StateMachine")
AnimatedSprite3DNode = NodePath("AnimatedSprite3D")
NavigationAgentNode = NodePath("NavigationAgent3D")
ChaseAreaNode = NodePath("ChaseArea")
AttackAreaNode = NodePath("AttackArea")
HurtboxAreaNode = NodePath("Hurtbox")
HitboxAreaNode = NodePath("Hitbox")
HitboxShapeNode = NodePath("Hitbox/CollisionShape3D")

[node name="AnimatedSprite3D" type="AnimatedSprite3D" parent="."]
pixel_size = 0.0025
sprite_frames = SubResource("SpriteFrames_nl2d3")
animation = &"Attack"
frame = 11
frame_progress = 1.0

[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.0016498, -0.0394009, 0.0142541)
Expand Down Expand Up @@ -512,6 +527,14 @@ collision_mask = 2
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.00685871, 0, 0)
shape = SubResource("SphereShape3D_e33me")

[node name="Hitbox" type="Area3D" parent="."]
collision_layer = 4
collision_mask = 0

[node name="CollisionShape3D" type="CollisionShape3D" parent="Hitbox"]
shape = SubResource("BoxShape3D_07o6p")
disabled = true

[node name="Hurtbox" type="Area3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.0442426, 0)
collision_layer = 0
Expand Down
69 changes: 56 additions & 13 deletions Udemy25dRpg/Scenes/Characters/Enemy/EnemyAttackState.cs
Original file line number Diff line number Diff line change
@@ -1,27 +1,70 @@
using System;
using System.Linq;

using Godot;

namespace Udemy25dRpg.Scenes.Characters.Enemy;

public partial class EnemyAttackState : EnemyState
{
protected override void ExitState()
{
base.ExitState();

CharacterNode.AnimatedSprite3DNode.AnimationFinished -= HandleAnimationFinished;
}
private Vector3 _targetPosition;

protected override void EnterState()
{
base.EnterState();
protected override void ExitState()
{
base.ExitState();

CharacterNode.AnimatedSprite3DNode.AnimationFinished += HandleAnimationFinished;
CharacterNode.AnimatedSprite3DNode.Play(nameof(Enemy.EnemyAnimations.Attack));
CharacterNode.AnimatedSprite3DNode.AnimationFinished -= HandleAnimationFinished;
CharacterNode.AnimatedSprite3DNode.FrameChanged -= HandleAnimationFrameChanged;

}

private void HandleAnimationFrameChanged()
{
switch (CharacterNode.AnimatedSprite3DNode.Animation)
{
case "Attack" when CharacterNode.AnimatedSprite3DNode.Frame == 3:
PerformHit();
break;
}
}

private void HandleAnimationFinished()
protected override void EnterState()
{
base.EnterState();

_targetPosition = CharacterNode
.AttackAreaNode
.GetOverlappingBodies()
.First()
.GlobalPosition;

CharacterNode.AnimatedSprite3DNode.AnimationFinished += HandleAnimationFinished;
CharacterNode.AnimatedSprite3DNode.FrameChanged += HandleAnimationFrameChanged;

CharacterNode.HitboxShapeNode.Disabled = true;

CharacterNode.AnimatedSprite3DNode.Play(nameof(Enemy.EnemyAnimations.Attack));
}

private void HandleAnimationFinished()
{
if (CharacterNode
.AttackAreaNode
.GetOverlappingBodies()
.OfType<Player.Player>()
.Any())
{
CharacterNode.StateMachineNode.SwitchState<EnemyChaseState>();
EnterState();
}
else
{
CharacterNode.StateMachineNode.SwitchState<EnemyChaseState>();
}
}

private void PerformHit()
{
CharacterNode.HitboxAreaNode.GlobalPosition = _targetPosition;
CharacterNode.HitboxShapeNode.Disabled = false;
}
}
22 changes: 16 additions & 6 deletions Udemy25dRpg/Scenes/Characters/Player/Player.tscn
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
[gd_scene load_steps=71 format=3 uid="uid://2als0j8j6wxe"]
[gd_scene load_steps=73 format=3 uid="uid://2als0j8j6wxe"]

[ext_resource type="Script" path="res://Scenes/Characters/Player/Player.cs" id="1_huxwr"]
[ext_resource type="Texture2D" uid="uid://y4hs6pyks4tw" path="res://Assets/Sprites/Characters/Player/Idle Blinking/Idle Blinking_000.png" id="2_2r0yv"]
[ext_resource type="Script" path="res://Resources/StatsResource.cs" id="2_g1k4d"]
[ext_resource type="Texture2D" uid="uid://b7lhym3wvu5j6" path="res://Assets/Sprites/Characters/Player/Idle Blinking/Idle Blinking_001.png" id="3_5244l"]
[ext_resource type="Texture2D" uid="uid://cfcjcof4e5sim" path="res://Assets/Sprites/Characters/Player/Idle Blinking/Idle Blinking_002.png" id="4_w2fvd"]
[ext_resource type="Texture2D" uid="uid://ca4skkqngti21" path="res://Assets/Sprites/Characters/Player/Idle Blinking/Idle Blinking_003.png" id="5_02man"]
Expand Down Expand Up @@ -67,6 +68,16 @@
[ext_resource type="Texture2D" uid="uid://cyfm2fm4spldt" path="res://Assets/Sprites/Characters/Player/Slashing/Slashing_011.png" id="61_31xsh"]
[ext_resource type="Script" path="res://Scenes/Characters/Player/PlayerAttackState.cs" id="67_vydjt"]

[sub_resource type="Resource" id="Resource_n7n7n"]
script = ExtResource("2_g1k4d")
StatType = 0
StatValue = 100.0

[sub_resource type="Resource" id="Resource_ymsa8"]
script = ExtResource("2_g1k4d")
StatType = 1
StatValue = 5.0

[sub_resource type="SpriteFrames" id="SpriteFrames_4gqhn"]
animations = [{
"frames": [{
Expand Down Expand Up @@ -282,16 +293,13 @@ height = 1.4337
[sub_resource type="BoxShape3D" id="BoxShape3D_md32l"]
size = Vector3(0.5, 0.5, 0.5)

[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_y4e0i"]
radius = 0.556113
height = 1.47419

[node name="Player" type="CharacterBody3D" node_paths=PackedStringArray("StateMachineNode", "AnimatedSprite3DNode", "HurtboxAreaNode", "HitboxAreaNode", "HitboxShapeNode")]
collision_layer = 2
collision_mask = 7
floor_max_angle = 1.55334
floor_snap_length = 100.0
script = ExtResource("1_huxwr")
Stats = [SubResource("Resource_n7n7n"), SubResource("Resource_ymsa8")]
StateMachineNode = NodePath("StateMachine")
AnimatedSprite3DNode = NodePath("AnimatedSprite3D")
HurtboxAreaNode = NodePath("Hurtbox")
Expand Down Expand Up @@ -343,7 +351,9 @@ shape = SubResource("BoxShape3D_md32l")
disabled = true

[node name="Hurtbox" type="Area3D" parent="."]
collision_layer = 0
collision_mask = 4

[node name="CollisionShape3D" type="CollisionShape3D" parent="Hurtbox"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.0483896, 0.0280536, 0)
shape = SubResource("CapsuleShape3D_y4e0i")
shape = SubResource("CapsuleShape3D_5puhm")
4 changes: 2 additions & 2 deletions Udemy25dRpg/Scenes/Levels/Main.tscn
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ StatValue = 100.0

[sub_resource type="Resource" id="Resource_6ujgn"]
script = ExtResource("5_xdatm")
StatType = 0
StatValue = 0.0
StatType = 1
StatValue = 4.0

[sub_resource type="BoxShape3D" id="BoxShape3D_kpyqv"]
size = Vector3(1, 3, 4)
Expand Down

0 comments on commit 8c7dfcc

Please sign in to comment.