#include "sprite.h" #include "camera.h" #include "debug.h" #include "render.h" #include "spritesheet.h" #include #include struct Sprite { // The animation sheet to sample sprites from. Spritesheet* spritesheet; // The current frame of animation. size_t tile_index; // The local transformation of this sprite. Vector origin; SDL_RendererFlip flip_state; }; Sprite* sprite_from_spritesheet(Spritesheet* sheet, size_t initial_frame) { Sprite* self = malloc(sizeof(Sprite)); ASSERT_RETURN(self != NULL, NULL, "Failed to allocate memory for new sprite."); self->spritesheet = sheet; self->origin = (Vector){0.5f, 0.5f}; self->tile_index = initial_frame; self->flip_state = SDL_FLIP_NONE; return self; } void sprite_destroy(Sprite* self) { free(self); } void sprite_draw(Sprite* self, Transform transform) { SDL_Texture* texture = spritesheet_get_texture(self->spritesheet); SDL_Rect source = spritesheet_get_tile_rect(self->spritesheet, self->tile_index); Vector origin = self->origin; if(self->flip_state && SDL_FLIP_HORIZONTAL) { origin.x = 1.0-origin.x; } if((self->flip_state & SDL_FLIP_VERTICAL) != 0) { origin.y = 1.0-origin.y; } Vector left_top = transform_point(&transform, vinvf(origin)); SDL_FRect destination = (SDL_FRect) { left_top.x, left_top.y, transform.scale.x, transform.scale.y }; destination = camera_world_to_pixel_rect(&g_camera, &destination); origin = vmulf(origin, transform.scale); SDL_RenderCopyExF(g_renderer, texture, &source, &destination, transform.rotation * 57.2958, &origin, self->flip_state); SDL_SetRenderDrawColor(g_renderer, 255, 255, 255, 255); } Vector sprite_get_origin(Sprite* self) { return self->origin; } void sprite_set_origin(Sprite* self, Vector origin) { self->origin = origin; } size_t sprite_get_tile(const Sprite* self) { return self->tile_index; } void sprite_set_tile(Sprite* self, size_t frame) { frame = frame % spritesheet_get_tile_count(self->spritesheet); self->tile_index = frame; } Spritesheet* sprite_get_spritesheet(const Sprite* self) { return self->spritesheet; } void sprite_set_spritesheet(Sprite* self, Spritesheet* spritesheet) { self->spritesheet = spritesheet; } void sprite_flip_horizontal(Sprite* self, int horizontal) { if(horizontal) { self->flip_state |= SDL_FLIP_HORIZONTAL; } else { self->flip_state &= ~SDL_FLIP_HORIZONTAL; } } void sprite_flip_vertical(Sprite* self, int vertical) { if(vertical) { self->flip_state |= SDL_FLIP_VERTICAL; } else { self->flip_state &= ~SDL_FLIP_VERTICAL; } }