91 lines
2.6 KiB
C
91 lines
2.6 KiB
C
#include "animation_sprite.h"
|
|
#include "debug.h"
|
|
#include "program.h"
|
|
|
|
struct AnimationSprite {
|
|
Spritesheet* sheet;
|
|
Sprite* sprite_target;
|
|
|
|
AnimationSpriteLoopMode loop_mode;
|
|
|
|
float frame_interval;
|
|
float start_time;
|
|
};
|
|
|
|
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;
|
|
}
|
|
|
|
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_draw(AnimationSprite* self, Transform* transform) {
|
|
const size_t frame_count = spritesheet_get_tile_count(self->sheet);
|
|
const float time = game_time() - self->start_time;
|
|
|
|
size_t frame = (size_t)(time / self->frame_interval);
|
|
|
|
switch(self->loop_mode) {
|
|
case LoopMode_Hide:
|
|
if(frame >= frame_count)
|
|
return;
|
|
else
|
|
break;
|
|
case LoopMode_Loop:
|
|
frame %= frame_count;
|
|
break;
|
|
case LoopMode_PingPong:
|
|
frame %= frame_count * 2;
|
|
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);
|
|
}
|
|
|
|
float animation_sprite_get_length(AnimationSprite* self) {
|
|
return (float)spritesheet_get_tile_count(self->sheet) * self->frame_interval;
|
|
}
|
|
|
|
void animation_sprite_set_framerate(AnimationSprite* self, float framerate) {
|
|
self->frame_interval = 1.0f / framerate;
|
|
}
|
|
|
|
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) {
|
|
return game_time() - self->start_time;
|
|
}
|
|
|
|
float animation_sprite_get_time_normalized(AnimationSprite* self) {
|
|
return animation_sprite_get_time(self) / animation_sprite_get_length(self);
|
|
}
|