sprite-animation/animation_player.c
2024-11-04 20:01:19 +00:00

79 lines
1.7 KiB
C

#include "animation_player.h"
#include <stdbool.h>
#include <SDL2/SDL_rect.h>
#include <SDL2/SDL_timer.h>
#include <SDL2/SDL_render.h>
#include <SDL2/SDL_image.h>
AnimPlayer ap_init(SDL_Renderer *renderer, const char *filepath, uint32_t ms_speed, uint32_t sprite_width, uint32_t sprite_height, bool loop) {
SDL_Texture *image = IMG_LoadTexture(renderer, filepath);
if (!image) {
return (AnimPlayer){0};
}
int w;
if (SDL_QueryTexture(image, NULL, NULL, &w, NULL) < 0) {
return (AnimPlayer){0};
}
AnimPlayer ap = {
.image = image,
.last_time = SDL_GetTicks(),
.ms_speed = ms_speed,
.sprite_width = sprite_width,
.sprite_height = sprite_height,
.count = w / sprite_width,
.current = 0,
.loop = loop,
.finished = false,
};
ap.ms_duration = ap.ms_speed * ap.count;
return ap;
}
void ap_update(AnimPlayer *ap, uint32_t ticks) {
if (!ap) {
return;
}
if (ap->current + 1 == ap->count && !(ap->loop)) {
ap->finished = true;
return;
}
if (ticks - ap->last_time >= ap->ms_speed) {
ap->last_time = ticks;
ap->current = ++ap->current % ap->count;
}
}
void ap_draw(SDL_Renderer *renderer, const AnimPlayer *ap, const SDL_Rect *dst, bool x_flip) {
if (!renderer || !ap || !(ap->image)) {
return;
}
SDL_Rect src = {
.x = ap->current * ap->sprite_width,
.y = 0,
.w = ap->sprite_width,
.h = ap->sprite_height,
};
SDL_RenderCopyEx(renderer, ap->image, &src, dst, 0, NULL, x_flip ? SDL_FLIP_HORIZONTAL : SDL_FLIP_NONE);
}
void ap_reset(AnimPlayer *ap) {
ap->current = 0;
ap->finished = false;
}
void ap_destroy(AnimPlayer *ap) {
if (!ap || !(ap->image)) {
return;
}
SDL_DestroyTexture(ap->image);
ap->image = NULL;
}