From 26bea065b94c46754fa4bd7a6367be67bd001b17 Mon Sep 17 00:00:00 2001
From: Sara <sara@saragerretsen.nl>
Date: Wed, 29 Nov 2023 14:20:19 +0100
Subject: [PATCH] feat: enemy animation and hurt reaction

---
 game/src/Enemy.c       | 19 ++++++++++---------
 game/src/Enemy.h       |  6 +++---
 game/src/EnemyStates.c | 28 +++++++++++++++++++++++++++-
 game/src/EnemyStates.h |  9 +++++++++
 4 files changed, 49 insertions(+), 13 deletions(-)

diff --git a/game/src/Enemy.c b/game/src/Enemy.c
index 34f4246..1579ef6 100644
--- a/game/src/Enemy.c
+++ b/game/src/Enemy.c
@@ -15,20 +15,21 @@ Enemy* MakeEnemy() {
         .collider = NULL,
         .sprite = sprite_new_empty(),
         .hurt = 0,
-        .idle = NULL,
-        .walk = NULL,
-        .hurt_anim = NULL,
+        .idleAnim = NULL,
+        .walkAnim = NULL,
+        .hurtAnim = NULL,
         .currentAnimation = NULL,
-        .health = 5,
+        .health = 15,
     };
 
     self->rigidbody = rigidbody_make(Enemy_as_PhysicsEntity(self));
-    self->collider = collider_new(Enemy_as_PhysicsEntity(self), shape_new_square(MakeVector(0.2f, 0.05f)), 0, PHYSICS_LAYER_DEFAULT);
+    self->collider = collider_new(Enemy_as_PhysicsEntity(self), shape_new_square(MakeVector(0.2f, 0.05f)), 0, PHYSICS_LAYER_DEFAULT | PHYSICS_LAYER_DEFAULT);
 
     sprite_set_origin(self->sprite, MakeVector(0.45f, 0.925f));
 
-    self->idle = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Idle.png", IVectorFrom(512)), 1.5f, LoopMode_Loop);
-    self->walk = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Walk.png", IVectorFrom(512)), 1.5f, LoopMode_Loop);
+    self->idleAnim = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Idle.png", IVectorFrom(512)), 1.5f, LoopMode_Loop);
+    self->walkAnim = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Walk.png", IVectorFrom(512)), 1.5f, LoopMode_Loop);
+    self->hurtAnim = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Hurt.png", IVectorFrom(512)), 5.f, LoopMode_Stop);
 
     return self;
 }
@@ -46,8 +47,6 @@ void EnemyStart(Enemy* self) {}
 
 void EnemyUpdate(Enemy* self, float deltaTime) {
     state_machine_update(self->behaviour, deltaTime);
-    if(self->health <= 0)
-        game_world_destroy_entity(Enemy_as_BehaviourEntity(self));
 }
 
 void EnemyDraw(Enemy* self) {
@@ -60,6 +59,8 @@ void EnemyDestroy(Enemy* self) {
     collider_destroy(self->collider);
     rigidbody_destroy(self->rigidbody);
     sprite_destroy(self->sprite);
+
+    physics_world_remove_entity(Enemy_as_PhysicsEntity(self));
     free(self);
 }
 
diff --git a/game/src/Enemy.h b/game/src/Enemy.h
index a9d0b7d..9c21af3 100644
--- a/game/src/Enemy.h
+++ b/game/src/Enemy.h
@@ -23,9 +23,9 @@ typedef struct Enemy {
     
     int hurt;
     
-    AnimationSprite* idle;
-    AnimationSprite* walk;
-    AnimationSprite* hurt_anim;
+    AnimationSprite* idleAnim;
+    AnimationSprite* walkAnim;
+    AnimationSprite* hurtAnim;
     
     AnimationSprite* currentAnimation;
 
diff --git a/game/src/EnemyStates.c b/game/src/EnemyStates.c
index a0972ce..f3157ee 100644
--- a/game/src/EnemyStates.c
+++ b/game/src/EnemyStates.c
@@ -1,13 +1,39 @@
 #include "EnemyStates.h"
 #include "Enemy.h"
+#include "animation_sprite.h"
 
 void EnemyState_Exit(Enemy* self) {}
 
 void EnemyIdle_Enter(Enemy* self) {
-    self->currentAnimation = self->idle;
+    self->currentAnimation = self->idleAnim;
     animation_sprite_play_from(self->currentAnimation, 0.f);
 }
 
 const State* EnemyIdle_Update(Enemy* self, float deltaTime) {
+    if(self->hurt)
+        return EnemyHurt();
     return EnemyIdle();
 }
+
+void EnemyWalk_Enter(Enemy* self) {
+    self->currentAnimation = self->walkAnim;
+    animation_sprite_play_from(self->currentAnimation, 0.f);
+}
+
+const State* EnemyWalk_Update(Enemy* self, float deltaTime) {
+    return EnemyWalk();
+}
+
+void EnemyHurt_Enter(Enemy* self) {
+    self->hurt = 0;
+
+    self->currentAnimation = self->hurtAnim;
+    animation_sprite_play_from(self->currentAnimation, 0.f);
+}
+
+const State* EnemyHurt_Update(Enemy* self, float deltaTime) {
+    const float ntime = animation_sprite_get_time_normalized(self->currentAnimation);
+    if(ntime > 1.0f)
+        return EnemyIdle();
+    return EnemyHurt();
+}
\ No newline at end of file
diff --git a/game/src/EnemyStates.h b/game/src/EnemyStates.h
index b66c70f..f493fc9 100644
--- a/game/src/EnemyStates.h
+++ b/game/src/EnemyStates.h
@@ -25,4 +25,13 @@ DefineState(EnemyWalk, Enemy,
     EnemyState_Exit
 )
 
+extern void EnemyHurt_Enter(Enemy* self);
+extern const State* EnemyHurt_Update(Enemy* self, float deltaTime);
+
+DefineState(EnemyHurt, Enemy,
+    EnemyHurt_Enter,
+    EnemyHurt_Update,
+    EnemyState_Exit
+)
+
 #endif // !FIGHT_ENEMY_STATES_H