added sprite and spritesheet
This commit is contained in:
parent
76c97a51c0
commit
9180c6d06f
59
src/sprite.c
Normal file
59
src/sprite.c
Normal file
|
@ -0,0 +1,59 @@
|
|||
#include "sprite.h"
|
||||
#include "camera.h"
|
||||
#include "render.h"
|
||||
#include "spritesheet.h"
|
||||
#include <SDL2/SDL_image.h>
|
||||
#include <SDL2/SDL_render.h>
|
||||
|
||||
struct Sprite {
|
||||
// The animation sheet to sample sprites from.
|
||||
Spritesheet* sheet;
|
||||
|
||||
// The current frame of animation.
|
||||
size_t current_frame;
|
||||
// Time at the start of the current frame of animation.
|
||||
float current_frame_time;
|
||||
|
||||
// The local transformation of this sprite.
|
||||
Transform transform;
|
||||
Vector origin;
|
||||
};
|
||||
|
||||
Sprite* sprite_from_spritesheet(Spritesheet* sheet) {
|
||||
Sprite* self = malloc(sizeof(Sprite));
|
||||
|
||||
self->sheet = sheet;
|
||||
self->transform = IdentityTransform;
|
||||
self->origin = (Vector){0.5f, 1.0f};
|
||||
self->current_frame = 0;
|
||||
// TODO: replace with a getter for the current game time.
|
||||
self->current_frame_time = 0;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
void sprite_destroy(Sprite* self) {
|
||||
free(self);
|
||||
}
|
||||
|
||||
void sprite_draw(Sprite* self, Transform transform) {
|
||||
SDL_Texture* texture = spritesheet_get_texture(self->sheet);
|
||||
SDL_Rect source = spritesheet_get_frame_rect(self->sheet, self->current_frame);
|
||||
transform = transform_apply(transform, self->transform);
|
||||
Vector left_top = vinvf(transform_point(&transform, self->origin));
|
||||
printf("lt: %f %f\n", left_top.x, left_top.y);
|
||||
printf("or: %f %f\n", self->origin.x, self->origin.y);
|
||||
|
||||
SDL_FRect destination = (SDL_FRect) {
|
||||
left_top.x, left_top.y,
|
||||
transform.scale.x, transform.scale.y
|
||||
};
|
||||
|
||||
destination = camera_world_to_screen_space(&g_camera, &destination);
|
||||
|
||||
Vector origin = vmulf(self->origin, vmulff(transform.scale, 0.5f));
|
||||
self->transform.rotation += 0.01f;
|
||||
|
||||
SDL_RenderCopyExF(g_renderer, texture, &source, &destination,
|
||||
transform.rotation * 57.2958, &origin, SDL_FLIP_NONE);
|
||||
}
|
25
src/sprite.h
Normal file
25
src/sprite.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
#ifndef _fencer_sprite_h
|
||||
#define _fencer_sprite_h
|
||||
|
||||
#include "vmath.h"
|
||||
#include "transform.h"
|
||||
#include "spritesheet.h"
|
||||
#include <SDL2/SDL_render.h>
|
||||
#include <SDL2/SDL_rect.h>
|
||||
|
||||
// Forward declaration of the private sprite struct
|
||||
typedef struct Sprite Sprite;
|
||||
|
||||
extern Sprite* sprite_from_spritesheet(Spritesheet* sheet);
|
||||
extern void sprite_destroy(Sprite* sprite);
|
||||
extern void sprite_draw(Sprite* self, Transform transform);
|
||||
|
||||
extern void sprite_set_position(Sprite* self, Vector position);
|
||||
extern void sprite_translate(Sprite* self, Vector delta_position);
|
||||
extern void sprite_set_scale(Sprite* self, Vector scale);
|
||||
extern void sprite_scale(Sprite* self, Vector scale);
|
||||
extern void sprite_set_rotation(Sprite* self, float rotation);
|
||||
extern void sprite_rotate(Sprite* self, float delta_rotation);
|
||||
extern void sprite_set_origin(Sprite* self, Vector origin);
|
||||
|
||||
#endif // !_fencer_sprite_h
|
72
src/spritesheet.c
Normal file
72
src/spritesheet.c
Normal file
|
@ -0,0 +1,72 @@
|
|||
#include "spritesheet.h"
|
||||
#include "assets.h"
|
||||
#include "render.h"
|
||||
#include <SDL2/SDL_render.h>
|
||||
#include <SDL2/SDL_image.h>
|
||||
|
||||
struct Spritesheet {
|
||||
// The texture to sample.
|
||||
SDL_Texture* texture;
|
||||
// The resolution of the texture.
|
||||
IVector resolution;
|
||||
// The number of frames in the sheet.
|
||||
size_t frame_count;
|
||||
// The number of frames contained in the width of the texture.
|
||||
size_t frame_shear;
|
||||
// Rules for how to play the sheet's animation.
|
||||
AnimationType animation_type;
|
||||
// The resolution of a single frame of the sheet.
|
||||
IVector frame_size;
|
||||
// The time to wait before switching frames.
|
||||
float frame_interval;
|
||||
};
|
||||
|
||||
static
|
||||
void _spritesheet_destroy_asset(void* self_void) {
|
||||
Spritesheet* self = self_void;
|
||||
SDL_DestroyTexture(self->texture);
|
||||
free(self_void);
|
||||
}
|
||||
|
||||
Spritesheet* spritesheet_from_texture(const char* texture_name, IVector frame_resolution) {
|
||||
Spritesheet* self = malloc(sizeof(Spritesheet));
|
||||
|
||||
if(self == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
store_asset(self, _spritesheet_destroy_asset);
|
||||
|
||||
// Load the texture image and query it's size
|
||||
self->texture = IMG_LoadTexture(g_renderer, texture_name);
|
||||
SDL_QueryTexture(self->texture, NULL, NULL, &self->resolution.x, &self->resolution.y);
|
||||
|
||||
self->animation_type = ANIMTYPE_ONCE;
|
||||
self->frame_size = frame_resolution;
|
||||
self->frame_shear = self->resolution.x / self->frame_size.x;
|
||||
self->frame_count = self->resolution.x / self->frame_size.x + self->resolution.y / self->frame_size.y;
|
||||
self->frame_interval = 0.016f;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
void spritesheet_destroy(Spritesheet* self) {
|
||||
asset_id id = get_asset_id(self);
|
||||
if(id != 0) {
|
||||
free_asset(id);
|
||||
}
|
||||
}
|
||||
|
||||
SDL_Texture* spritesheet_get_texture(const Spritesheet* self) {
|
||||
return self->texture;
|
||||
}
|
||||
|
||||
SDL_Rect spritesheet_get_frame_rect(const Spritesheet* self, size_t index) {
|
||||
IVector tile_coord = {index % self->frame_shear, index / self->frame_shear};
|
||||
tile_coord = vmuli(tile_coord, self->frame_size);
|
||||
|
||||
return (SDL_Rect) {
|
||||
tile_coord.x, tile_coord.y,
|
||||
self->frame_size.x, self->frame_size.y
|
||||
};
|
||||
}
|
21
src/spritesheet.h
Normal file
21
src/spritesheet.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
#ifndef _fencer_spritesheet_h
|
||||
#define _fencer_spritesheet_h
|
||||
|
||||
#include "vmath.h"
|
||||
#include <SDL2/SDL_render.h>
|
||||
|
||||
typedef enum AnimationType AnimationType;
|
||||
enum AnimationType {
|
||||
ANIMTYPE_ONCE,
|
||||
ANIMTYPE_LOOP,
|
||||
};
|
||||
|
||||
typedef struct Spritesheet Spritesheet;
|
||||
|
||||
extern Spritesheet* spritesheet_from_texture(const char* texture_name, IVector frame_resolution);
|
||||
extern void spritesheet_destroy(Spritesheet* self);
|
||||
|
||||
extern SDL_Texture* spritesheet_get_texture(const Spritesheet* self);
|
||||
extern SDL_Rect spritesheet_get_frame_rect(const Spritesheet* self, size_t index);
|
||||
|
||||
#endif // !_fencer_spritesheet_h
|
Loading…
Reference in a new issue