feat: added animation events to animation_sprite
This commit is contained in:
parent
a63cfdd2b0
commit
f67f95fd6a
5 changed files with 102 additions and 63 deletions
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue