From f67f95fd6a0923f32929936be3e382858b199f26 Mon Sep 17 00:00:00 2001 From: Sara Date: Tue, 10 Sep 2024 09:48:37 +0200 Subject: [PATCH] feat: added animation events to animation_sprite --- core/src/animation_sprite.c | 104 ++++++++++++++++++++++-------------- core/src/animation_sprite.h | 33 ++++++++---- game/src/Enemy.c | 6 +-- game/src/Player.c | 19 +++---- game/src/Player.h | 3 +- 5 files changed, 102 insertions(+), 63 deletions(-) diff --git a/core/src/animation_sprite.c b/core/src/animation_sprite.c index 0bc6749..e9fac89 100644 --- a/core/src/animation_sprite.c +++ b/core/src/animation_sprite.c @@ -1,47 +1,63 @@ #include "animation_sprite.h" #include "debug.h" #include "program.h" +#include "list.h" struct AnimationSprite { - Spritesheet* sheet; - Sprite* sprite_target; + Spritesheet *sheet; + Sprite *sprite_target; - AnimationSpriteLoopMode loop_mode; + AnimationSpriteLoopMode loop_mode; - float frame_interval; - float start_time; + float frame_interval; + float start_time; + + size_t event_index; + List events; }; -AnimationSprite* animation_sprite_new(Sprite* target_sprite, Spritesheet* sheet, float framerate, AnimationSpriteLoopMode loop_mode) { - AnimationSprite* self = malloc(sizeof(AnimationSprite)); - ASSERT_RETURN(self != NULL, NULL, "Failed to allocate memory for AnimationSprite"); - *self = (AnimationSprite){ - .sheet = sheet, - .frame_interval = 1.0f / framerate, - .loop_mode = loop_mode, - .start_time = game_time(), - .sprite_target = target_sprite - }; - - return self; +AnimationSprite *animation_sprite_new(Sprite *target_sprite, Spritesheet *sheet, + float framerate, AnimationSpriteLoopMode loop_mode, + AnimationEvent *events, size_t event_count) { + AnimationSprite *self = malloc(sizeof(AnimationSprite)); + ASSERT_RETURN(self != NULL, NULL, "Failed to allocate memory for AnimationSprite"); + *self = (AnimationSprite){ + .sheet = sheet, + .frame_interval = 1.0f / framerate, + .loop_mode = loop_mode, + .start_time = game_time(), + .sprite_target = target_sprite, + .event_index = 0, + .events = list_with_len(sizeof(AnimationEvent), event_count), + }; + if(event_count > 0) { + memcpy(self->events.data, events, sizeof(AnimationEvent) * event_count); + self->events.len = event_count; + } + return self; } -void animation_sprite_destroy(AnimationSprite* self) { - spritesheet_destroy(self->sheet); - free(self); +void animation_sprite_destroy(AnimationSprite *self) { + spritesheet_destroy(self->sheet); + free(self); } -void animation_sprite_play_from(AnimationSprite* self, float normalized_time) { - self->start_time = game_time() - normalized_time * animation_sprite_get_length(self); +void animation_sprite_reset(AnimationSprite *self) { + self->start_time = game_time(); } -void animation_sprite_draw(AnimationSprite* self, Transform* transform) { +void animation_sprite_play_from(AnimationSprite *self, float normalized_time) { + self->start_time = game_time() - normalized_time * animation_sprite_get_length(self); +} + +void animation_sprite_draw(AnimationSprite *self, Transform *transform) { const size_t frame_count = spritesheet_get_tile_count(self->sheet); - const float time = game_time() - self->start_time; - + const float time = game_time() - self->start_time; size_t frame = (size_t)(time / self->frame_interval); - switch(self->loop_mode) { + case LoopMode_Stop: + if(frame >= frame_count) + frame = frame_count - 1; case LoopMode_Hide: if(frame >= frame_count) return; @@ -55,36 +71,44 @@ void animation_sprite_draw(AnimationSprite* self, Transform* transform) { if(frame >= frame_count) frame = frame_count - (frame - frame_count); return; - case LoopMode_Stop: - if(frame >= frame_count) - frame = frame_count - 1; } sprite_set_spritesheet(self->sprite_target, self->sheet); - sprite_set_tile(self->sprite_target, frame); - sprite_draw(self->sprite_target, *transform); + sprite_set_tile(self->sprite_target, frame); + sprite_draw(self->sprite_target, *transform); } -float animation_sprite_get_length(AnimationSprite* self) { - return (float)spritesheet_get_tile_count(self->sheet) * self->frame_interval; +void animation_sprite_update_events(AnimationSprite *self) { + const float current_time = game_time() - self->start_time; + for(;self->event_index <= self->events.len; ++self->event_index) { + AnimationEvent *event = list_at_as(AnimationEvent, &self->events, self->event_index); + if(event->time < current_time) + return; + else + event->fn(event->target, event->arg.data); + } } -void animation_sprite_set_framerate(AnimationSprite* self, float framerate) { - self->frame_interval = 1.0f / framerate; +float animation_sprite_get_length(AnimationSprite *self) { + return (float)spritesheet_get_tile_count(self->sheet) * self->frame_interval; } -float animation_sprite_get_framerate(const AnimationSprite* self) { - return 1.0f / self->frame_interval; +void animation_sprite_set_framerate(AnimationSprite *self, float framerate) { + self->frame_interval = 1.0f / framerate; } -Sprite* animation_sprite_get_sprite(AnimationSprite* self) { +float animation_sprite_get_framerate(const AnimationSprite *self) { + return 1.0f / self->frame_interval; +} + +Sprite *animation_sprite_get_sprite(AnimationSprite *self) { return self->sprite_target; } -float animation_sprite_get_time(AnimationSprite* self) { +float animation_sprite_get_time(AnimationSprite *self) { return game_time() - self->start_time; } -float animation_sprite_get_time_normalized(AnimationSprite* self) { +float animation_sprite_get_time_normalized(AnimationSprite *self) { return animation_sprite_get_time(self) / animation_sprite_get_length(self); } diff --git a/core/src/animation_sprite.h b/core/src/animation_sprite.h index 2a5ab93..0e2fe01 100644 --- a/core/src/animation_sprite.h +++ b/core/src/animation_sprite.h @@ -1,6 +1,7 @@ #ifndef _fencer_animation_sprite_h #define _fencer_animation_sprite_h +#include "drop.h" #include "sprite.h" #include "spritesheet.h" @@ -11,19 +12,31 @@ typedef enum AnimationSpriteLoopMode { LoopMode_PingPong, } AnimationSpriteLoopMode; +typedef void (*AnimationEventFn)(void *object, void *arg); + +typedef struct AnimationEvent { + float time; + void *target; + Drop arg; + AnimationEventFn fn; +} AnimationEvent; + typedef struct AnimationSprite AnimationSprite; -extern AnimationSprite* animation_sprite_new(Sprite* target_sprite, Spritesheet* sheet, float framerate, AnimationSpriteLoopMode loop_mode); -extern void animation_sprite_destroy(AnimationSprite* self); +extern AnimationSprite *animation_sprite_new(Sprite *target_sprite, Spritesheet *sheet, float framerate, AnimationSpriteLoopMode loop_mode, AnimationEvent *events, size_t event_count); +extern void animation_sprite_destroy(AnimationSprite *self); -extern void animation_sprite_play_from(AnimationSprite* self, float normalized_time); -extern void animation_sprite_draw(AnimationSprite* self, Transform* transform); +extern void animation_sprite_reset(AnimationSprite *self); +extern void animation_sprite_play_from(AnimationSprite *self, float normalized_time); +extern void animation_sprite_draw(AnimationSprite *self, Transform *transform); -extern float animation_sprite_get_length(AnimationSprite* self); -extern void animation_sprite_set_framerate(AnimationSprite* self, float framerate); -extern float animation_sprite_get_framerate(const AnimationSprite* self); -extern Sprite* animation_sprite_get_sprite(AnimationSprite* self); -extern float animation_sprite_get_time(AnimationSprite* self); -extern float animation_sprite_get_time_normalized(AnimationSprite* self); +extern void animation_sprite_update_events(AnimationSprite *self); + +extern float animation_sprite_get_length(AnimationSprite *self); +extern void animation_sprite_set_framerate(AnimationSprite *self, float framerate); +extern float animation_sprite_get_framerate(const AnimationSprite *self); +extern Sprite *animation_sprite_get_sprite(AnimationSprite *self); +extern float animation_sprite_get_time(AnimationSprite *self); +extern float animation_sprite_get_time_normalized(AnimationSprite *self); #endif // !_fencer_animation_sprite_h diff --git a/game/src/Enemy.c b/game/src/Enemy.c index 159ffa1..d4ed25a 100644 --- a/game/src/Enemy.c +++ b/game/src/Enemy.c @@ -75,9 +75,9 @@ Enemy* MakeEnemy() { sprite_set_origin(self->sprite, MakeVector(0.45f, 0.925f)); // load and configure animations - 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); + self->idleAnim = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Idle.png", IVectorFrom(512)), 1.5f, LoopMode_Loop, NULL, 0); + self->walkAnim = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Walk.png", IVectorFrom(512)), 1.5f, LoopMode_Loop, NULL, 0); + self->hurtAnim = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Hurt.png", IVectorFrom(512)), 5.f, LoopMode_Stop, NULL, 0); self->behaviour = state_machine_init(self, EnemyIdle()); return self; diff --git a/game/src/Player.c b/game/src/Player.c index 2de19ad..4829c65 100644 --- a/game/src/Player.c +++ b/game/src/Player.c @@ -93,6 +93,7 @@ Player* MakePlayer() { .slide = NULL, .animationStateMachine = NULL, + .boxes = malloc(sizeof(Hurtbox) * 3), .pushInputTimer = 0.f, .inputLog = list_from_type(PlayerInputFrame), @@ -117,15 +118,15 @@ Player* MakePlayer() { sprite_set_origin(self->sprite, MakeVector(0.45f, 0.925f)); // load and configure animations - 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)), 5.f, LoopMode_Loop); - self->jump = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Jumping.png", IVectorFrom(512)), 1.f, LoopMode_Stop); - self->jab_a = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Jab_A.png", IVectorFrom(512)), 10.f, LoopMode_Stop); - self->jab_b = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Jab_B.png", IVectorFrom(512)), 10.f, LoopMode_Stop); - self->kick_a = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Kick_A.png", IVectorFrom(512)), 12.f, LoopMode_Stop); - self->slash = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Slash.png", IVectorFrom(512)), 12.f, LoopMode_Stop); - self->air_heavy = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Air_Heavy.png", IVectorFrom(512)), 10.f, LoopMode_Stop); - self->slide = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Slide.png", IVectorFrom(512)), 1.f, LoopMode_Loop); + self->idle = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Idle.png", IVectorFrom(512)), 1.5f, LoopMode_Loop, NULL, 0); + self->walk = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Walk.png", IVectorFrom(512)), 5.f, LoopMode_Loop, NULL, 0); + self->jump = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Jumping.png", IVectorFrom(512)), 1.f, LoopMode_Stop, NULL, 0); + self->jab_a = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Jab_A.png", IVectorFrom(512)), 10.f, LoopMode_Stop, NULL, 0); + self->jab_b = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Jab_B.png", IVectorFrom(512)), 10.f, LoopMode_Stop, NULL, 0); + self->kick_a = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Kick_A.png", IVectorFrom(512)), 12.f, LoopMode_Stop, NULL, 0); + self->slash = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Slash.png", IVectorFrom(512)), 12.f, LoopMode_Stop, NULL, 0); + self->air_heavy = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Air_Heavy.png", IVectorFrom(512)), 10.f, LoopMode_Stop, NULL, 0); + self->slide = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Slide.png", IVectorFrom(512)), 1.f, LoopMode_Loop, NULL, 0); self->animationStateMachine = state_machine_init(self, PlayerIdle()); diff --git a/game/src/Player.h b/game/src/Player.h index 61fe089..2f4d54b 100644 --- a/game/src/Player.h +++ b/game/src/Player.h @@ -1,6 +1,7 @@ #ifndef FIGHT_PLAYER_H #define FIGHT_PLAYER_H +#include "Hurtbox.h" #include "dictionary.h" #include "state_machine.h" #include "mirror.h" @@ -56,9 +57,9 @@ typedef struct Player { AnimationSprite* slide; StateMachine* animationStateMachine; + Hurtbox *boxes; AnimationSprite* currentAnimation; - float pushInputTimer; List inputLog; PlayerInputFrame nextInputFrame;