Adding an animator

This commit is contained in:
AnonymusRaccoon
2020-01-09 17:18:43 +01:00
parent 55c2b117e2
commit 836645532a
10 changed files with 268 additions and 54 deletions
+2
View File
@@ -26,6 +26,8 @@ SRC = src/engine/engine.c \
src/components/friction_component.c \
src/components/friction_giver.c \
src/components/controllers/keyboard_controller.c \
src/components/renderers/sprite_renderer.c \
src/components/renderers/anim_renderer.c \
src/scene/scene.c \
src/scene/scene_music.c \
src/utility/arraylen.c \
+13 -5
View File
@@ -8,18 +8,26 @@
#pragma once
#include "component.h"
#include "sprite.h"
#include "vector2.h"
enum GC_TEXTURETYPE {
GC_TEXTUREREND
};
typedef enum GC_TEXTURETYPE {
GC_NONE,
GC_TEXTUREREND,
GC_ANIMREND
} GC_TEXTURETYPE;
struct renderer
{
gc_component base;
gc_sprite *sprite;
enum GC_TEXTURETYPE type;
void *data;
};
void sprite_ctr(struct renderer *cmp, va_list args);
void sprite_fdctr(gc_scene *scene, struct renderer *cmp, node *n);
void anim_ctr(struct renderer *cmp, va_list args);
void anim_fdctr(gc_scene *scene, struct renderer *cmp, node *n);
void rend_set_anim(struct renderer *rend, const char *name);
extern const struct renderer renderer_component;
+18 -2
View File
@@ -23,5 +23,21 @@ typedef struct gc_sprite {
gc_texture *texture;
gc_int_rect rect;
gc_vector2 pos;
gc_vector2 size;
} gc_sprite;
gc_vector2 scale;
} gc_sprite;
typedef struct gc_anim {
char *name;
int frame_count;
float frame_rate;
gc_int_rect rect;
} gc_anim;
typedef struct gc_animholder {
gc_sprite *sprite;
gc_anim *anims;
int animcount;
gc_anim *current;
float timesince_up;
} gc_animholder;
+1
View File
@@ -33,5 +33,6 @@ void *my_realloc(void *oldptr, size_t oldsize, size_t newsize);
#define ABSCLAMP(x, y) (((x) > 0) ? CLAMP((x), (y)) : NCLAMP((x), -(y)))
#define GETSIGN(x) (((x) < 0) ? (-1) : (1))
#define SET_SIGN(x, s) (x = (x) * (s) > 0 ? (x) : ((x) * (-1)))
#define ABS(x) ((x) > 0 ? (x) : -(x))
+1
View File
@@ -35,4 +35,5 @@ int xml_getbinaprop(node *n, const char *key);
int xml_gethexaprop(node *n, const char *key);
float xml_getfloatprop(node *n, const char *key);
int xml_getchildcount(node *n);
int xml_getchildcount_filtered(node *n, char *name);
void xml_destroy(node *n);
+26 -28
View File
@@ -16,39 +16,31 @@
static void ctr(void *component, va_list args)
{
struct renderer *cmp = (struct renderer *)component;
sfVector2u size;
GC_TEXTURETYPE type = va_arg(args, GC_TEXTURETYPE);
cmp->sprite = malloc(sizeof(gc_sprite));
if (!cmp->sprite)
return;
cmp->sprite->texture = va_arg(args, gc_texture *);
cmp->sprite->rect = va_arg(args, gc_int_rect);
if (cmp->sprite->texture && cmp->sprite->rect.height < 0) {
size = sfTexture_getSize(cmp->sprite->texture->texture);
cmp->sprite->rect.height = (float)size.y;
cmp->sprite->rect.width = (float)size.x;
}
cmp->data = NULL;
if (type == GC_TEXTUREREND)
sprite_ctr(cmp, args);
if (type == GC_ANIMREND)
anim_ctr(cmp, args);
}
GC_TEXTURETYPE renderer_get_type(node *n)
{
if (xml_getnode(n, "animation"))
return (GC_ANIMREND);
return (GC_TEXTUREREND);
}
static void fdctr(gc_entity *entity, gc_scene *scene, void *component, node *n)
{
struct renderer *cmp = (struct renderer *)component;
node *rect = xml_getnode(n, "Rect");
sfVector2u size;
GC_TEXTURETYPE type = renderer_get_type(n);
if (!cmp->sprite)
return;
cmp->sprite->texture = get_texture(scene, xml_getproperty(n, "src"));
cmp->sprite->rect.height = xml_getfloatprop(rect, "height");
cmp->sprite->rect.width = xml_getfloatprop(rect, "width");
cmp->sprite->rect.top = xml_getfloatprop(rect, "top");
cmp->sprite->rect.left = xml_getfloatprop(rect, "left");
if (cmp->sprite->texture && cmp->sprite->rect.height < 0) {
size = sfTexture_getSize(cmp->sprite->texture->texture);
cmp->sprite->rect.height = (float)size.y;
cmp->sprite->rect.width = (float)size.x;
}
cmp->type = GC_TEXTUREREND;
if (type == GC_TEXTUREREND)
sprite_fdctr(scene, cmp, n);
if (type == GC_ANIMREND)
anim_fdctr(scene, cmp, n);
(void)entity;
}
@@ -56,7 +48,13 @@ static void dtr(void *component)
{
struct renderer *cmp = (struct renderer *)component;
free(cmp->sprite);
if (cmp->type == GC_TEXTUREREND)
free(cmp->data);
if (cmp->type == GC_ANIMREND) {
free(((gc_animholder *)cmp->data)->sprite);
free(((gc_animholder *)cmp->data)->anims);
free(cmp->data);
}
}
static char *serialize(void *component)
@@ -78,6 +76,6 @@ const struct renderer renderer_component = {
next: NULL,
prev: NULL
},
sprite: NULL,
data: NULL,
type: GC_TEXTUREREND
};
+102
View File
@@ -0,0 +1,102 @@
/*
** EPITECH PROJECT, 2020
** Twac
** File description:
** anim_renderer
*/
#include "components/renderer.h"
#include "vector2.h"
#include "sprite.h"
#include "xml.h"
#include "my.h"
#include <malloc.h>
#include <SFML/Graphics.h>
void rend_set_anim(struct renderer *rend, const char *name)
{
gc_animholder *holder = (gc_animholder *)rend->data;
if (holder->current && !my_strcmp(holder->current->name, name))
return;
for (int i = 0; i < holder->animcount; i++) {
if (!my_strcmp(holder->anims[i].name, name)) {
holder->current = &holder->anims[i];
holder->sprite->rect = holder->anims[i].rect;
return;
}
}
}
void anim_ctr(struct renderer *cmp, va_list args)
{
sfVector2u size;
gc_sprite *sprite;
sprite = malloc(sizeof(gc_sprite));
if (!sprite)
return;
cmp->data = sprite;
sprite->texture = va_arg(args, gc_texture *);
sprite->rect = va_arg(args, gc_int_rect);
if (sprite->texture && sprite->rect.height < 0) {
size = sfTexture_getSize(sprite->texture->texture);
sprite->rect.height = (float)size.y;
sprite->rect.width = (float)size.x;
}
}
void animation_fdctr(gc_anim *anim, gc_sprite *sprite, node *n)
{
node *rect = xml_getnode(n, "Rect");
int tmp;
anim->name = xml_getproperty(n, "name");
anim->frame_count = xml_getintprop(n, "frame_count");
anim->frame_rate = xml_getfloatprop(n, "frame_rate");
anim->rect.height = sprite->rect.height;
anim->rect.width = sprite->rect.width;
anim->rect.top = sprite->rect.top;
anim->rect.left = sprite->rect.left;
if ((tmp = xml_getfloatprop(rect, "height")) != 0)
anim->rect.height = tmp;
if ((tmp = xml_getfloatprop(rect, "width")) != 0)
anim->rect.width = tmp;
if ((tmp = xml_getfloatprop(rect, "top")) != 0)
anim->rect.top = tmp;
if ((tmp = xml_getfloatprop(rect, "left")) != 0)
anim->rect.left = tmp;
}
void animation_setnone(gc_anim *anim, gc_sprite *sprite)
{
anim->name = "none";
anim->frame_count = 1;
anim->frame_rate = 0;
anim->rect = sprite->rect;
}
void anim_fdctr(gc_scene *scene, struct renderer *cmp, node *n)
{
gc_animholder *hold = malloc(sizeof(gc_animholder));
int animcount = xml_getchildcount_filtered(n, "animation") + 1;
gc_anim *anims = malloc(sizeof(gc_anim) * animcount);
int i = 1;
if (!hold || !anims)
return;
sprite_fdctr(scene, cmp, n);
hold->sprite = (gc_sprite *)cmp->data;
hold->anims = anims;
hold->current = NULL;
hold->animcount = animcount;
hold->timesince_up = 0;
cmp->data = hold;
animation_setnone(&anims[0], hold->sprite);
for (n = n->child; n; n = n->next) {
if (my_strcmp(n->name, "animation"))
continue;
animation_fdctr(&anims[i], hold->sprite, n);
}
cmp->type = GC_ANIMREND;
}
@@ -0,0 +1,55 @@
/*
** EPITECH PROJECT, 2020
** Twac
** File description:
** sprite_renderer
*/
#include "components/renderer.h"
#include "vector2.h"
#include "xml.h"
#include "sprite.h"
#include <malloc.h>
#include <SFML/Graphics.h>
void sprite_ctr(struct renderer *cmp, va_list args)
{
sfVector2u size;
gc_sprite *sprite;
sprite = malloc(sizeof(gc_sprite));
if (!sprite)
return;
cmp->data = sprite;
sprite->texture = va_arg(args, gc_texture *);
sprite->rect = va_arg(args, gc_int_rect);
if (sprite->texture && sprite->rect.height < 0) {
size = sfTexture_getSize(sprite->texture->texture);
sprite->rect.height = (float)size.y;
sprite->rect.width = (float)size.x;
}
sprite->scale = (gc_vector2){1, 1};
}
void sprite_fdctr(gc_scene *scene, struct renderer *cmp, node *n)
{
node *rect = xml_getnode(n, "Rect");
sfVector2u size;
gc_sprite *sprite = malloc(sizeof(gc_sprite));
cmp->data = sprite;
if (!cmp->data)
return;
sprite->texture = get_texture(scene, xml_getproperty(n, "src"));
sprite->rect.height = xml_getfloatprop(rect, "height");
sprite->rect.width = xml_getfloatprop(rect, "width");
sprite->rect.top = xml_getfloatprop(rect, "top");
sprite->rect.left = xml_getfloatprop(rect, "left");
if (sprite->texture && sprite->rect.height < 0) {
size = sfTexture_getSize(sprite->texture->texture);
sprite->rect.height = (float)size.y;
sprite->rect.width = (float)size.x;
}
sprite->scale = (gc_vector2){1, 1};
cmp->type = GC_TEXTUREREND;
}
+5 -2
View File
@@ -8,6 +8,7 @@
#include "entity.h"
#include "system.h"
#include "texture.h"
#include "sprite.h"
#include "vector2.h"
#include "components/parallax_component.h"
#include "components/renderer.h"
@@ -20,10 +21,12 @@ gc_entity *entity, float dtime)
struct renderer *text = GETCMP(renderer);
struct parallax_component *par = GETCMP(parallax_component);
struct transform_component *tra = GETCMP(transform_component);
gc_sprite *sprite;
if (!text->sprite)
if (text->type != GC_TEXTUREREND || !text->data)
return;
text->sprite->rect.left += (tra->position.x - par->old_pos.x) * par->speed;
sprite = ((gc_sprite *)text->data);
sprite->rect.left += (tra->position.x - par->old_pos.x) * par->speed;
par->old_pos = tra->position;
(void)system;
(void)engine;
+45 -17
View File
@@ -9,6 +9,7 @@
#include "system.h"
#include "texture.h"
#include "vector2.h"
#include "sprite.h"
#include "systems/sfml_renderer_system.h"
#include "components/transform_component.h"
#include "components/renderer.h"
@@ -16,26 +17,48 @@
#include <stdlib.h>
void renderer_draw_texture(struct sfml_renderer_system *renderer, \
gc_sprite *sprite)
struct transform_component *tra, gc_sprite *sprite)
{
sfVector2f pos = (sfVector2f){sprite->pos.x, -sprite->pos.y};
sfVector2f scale;
sfVector2u t;
sfIntRect rect = {
(int)sprite->rect.left, (int)sprite->rect.top,
(int)sprite->rect.width, (int)sprite->rect.height
};
sfVector2f pos = (sfVector2f){tra->position.x, -tra->position.y};
sfVector2f scale = (sfVector2f){
tra->size.x * sprite->scale.x / sprite->rect.width,
tra->size.y * sprite->scale.y / sprite->rect.height
};;
sprite->pos = tra->position;
if (!sprite->texture)
return;
scale = (sfVector2f){sprite->size.x / rect.width, sprite->size.y / rect.height};
sfSprite_setTexture(renderer->sprite, sprite->texture->texture, true);
sfSprite_setTextureRect(renderer->sprite, rect);
sfSprite_setTextureRect(renderer->sprite, (sfIntRect){
(int)sprite->rect.left, (int)sprite->rect.top,
(int)sprite->rect.width, (int)sprite->rect.height
});
sfSprite_setPosition(renderer->sprite, pos);
sfSprite_setScale(renderer->sprite, scale);
sfSprite_setOrigin(renderer->sprite, (sfVector2f){
scale.x < 0 ? sprite->rect.width : 0,
scale.y < 0 ? sprite->rect.height : 0
});
sfRenderWindow_drawSprite(renderer->window, renderer->sprite, NULL);
}
void renderer_draw_anim(struct sfml_renderer_system *renderer, \
struct transform_component *tra, gc_animholder *holder, float dtime)
{
gc_int_rect *rec = &holder->sprite->rect;
gc_anim *curr = holder->current;
if (curr)
holder->timesince_up += dtime;
if (curr && holder->timesince_up > 1 / curr->frame_rate) {
rec->left += rec->width;
holder->timesince_up = 0;
if (rec->left > curr->rect.left + rec->width * (curr->frame_count - 1))
rec->left = curr->rect.left;
}
renderer_draw_texture(renderer, tra, holder->sprite);
}
void sfml_update_entity(gc_engine *engine, void *system, \
gc_entity *entity, float dtime)
{
@@ -43,14 +66,19 @@ gc_entity *entity, float dtime)
struct renderer *text = GETCMP(renderer);
struct sfml_renderer_system *rend = (struct sfml_renderer_system *)system;
if (!text->sprite)
if (!text->data)
return;
text->sprite->pos = pos->position;
text->sprite->size = pos->size;
if (text->type == GC_TEXTUREREND)
renderer_draw_texture(rend, text->sprite);
else
my_printf("Trying to render a texture with an unknow type.\n");
switch (text->type) {
case GC_TEXTUREREND:
renderer_draw_texture(rend, pos, (gc_sprite *)text->data);
break;
case GC_ANIMREND:
renderer_draw_anim(rend, pos, (gc_animholder *)text->data, dtime);
break;
default:
my_printf("Trying to render a texture with an unknown type.\n");
break;
}
(void)dtime;
(void)engine;
}