mirror of
https://github.com/zoriya/Gamacon.git
synced 2026-06-02 19:51:47 +00:00
Adding an animator
This commit is contained in:
@@ -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 \
|
||||
|
||||
@@ -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
@@ -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;
|
||||
@@ -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))
|
||||
@@ -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
@@ -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
|
||||
};
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user