Working lever and door !

This commit is contained in:
Ulysse Cura 2026-08-10 20:59:14 +02:00
parent 4668d4dbe4
commit a805daf573
13 changed files with 143 additions and 27 deletions

@ -1 +1 @@
Subproject commit 5d902de564b085b322ec68a8396711f430dc0bce Subproject commit 67c5c18fa2d65004ef164848f69c2e5f9e7eeac4

View File

@ -8,7 +8,8 @@ SOURCES := \
components/interact_component.c \ components/interact_component.c \
components/animation_system.c \ components/animation_system.c \
components/player_system.c \ components/player_system.c \
components/lever_component.c components/lever_component.c \
components/door_component.c
# Compiler and flags # Compiler and flags
SRC_CC = gcc SRC_CC = gcc

View File

@ -109,7 +109,7 @@ int animation_system_create_frames_clips(animation_system_data_t *system_data)
elem_t *frame = create_elem(&system_data->frames); elem_t *frame = create_elem(&system_data->frames);
if(!frame) return EXIT_FAILURE; if(!frame) return EXIT_FAILURE;
((rect_t *)frame->data)->x = sprite_component_data->src_rect.w * (float)current_frame_nb; ((rect_t *)frame->data)->x = sprite_component_data->src_rect.w * current_frame_nb;
((rect_t *)frame->data)->y = 0; ((rect_t *)frame->data)->y = 0;
((rect_t *)frame->data)->w = sprite_component_data->src_rect.w; ((rect_t *)frame->data)->w = sprite_component_data->src_rect.w;
((rect_t *)frame->data)->h = sprite_component_data->src_rect.h; ((rect_t *)frame->data)->h = sprite_component_data->src_rect.h;

View File

@ -0,0 +1,88 @@
#include "door_component.h"
#include <stdarg.h>
#include "game.h"
#include "animation_system.h"
#include "hitbox_component.h"
#include "event_bus.h"
#include "memory_alloc.h"
#include "errors.h"
// Event arg = size_t state, Subscription arg = entity_t *entity
static inline int door_component_callback(va_list event_args, void *subscription_data)
{
const entity_t *entity = subscription_data;
component_t *door_component = entity_get_component(entity, DOOR_COMPONENT);
if(!door_component) return EXIT_FAILURE;
door_component_data_t *component_data = door_component->data;
component_data->state = (bool)va_arg(event_args, size_t);
return EXIT_SUCCESS;
}
inline int door_component_init(component_t *component)
{
door_component_data_t *component_data = component->data;
component_t *animation_system = entity_get_component(component->entity, ANIMATION_SYSTEM);
if(!animation_system)
{
error_printf("Door component require an animation system.");
return EXIT_FAILURE;
}
component_data->animation_system_data = animation_system->data;
component_t *hitbox_component = entity_get_component(component->entity, HITBOX_COMPONENT);
if(!hitbox_component)
{
error_printf("Door component require an hitbox component.");
return EXIT_FAILURE;
}
component_data->hitbox_component_data = hitbox_component->data;
animation_system_data_t *animation_system_data = component_data->animation_system_data;
animation_system_data->nb_frames = 8;
animation_system_data->frame_delay_ms = DOOR_DEFAULT_ANIMATION_SPEED;
if(animation_system_create_frames_clips(animation_system_data)) return EXIT_FAILURE;
component_data->topic_id = 0;
event_bus_subscribe(&game.event_bus, component_data->topic_id, door_component_callback, component->entity);
component_data->state = false;
component_data->last_state = false;
return EXIT_SUCCESS;
}
inline int door_component_update(component_t *component)
{
door_component_data_t *component_data = component->data;
animation_system_data_t *animation_system_data = component_data->animation_system_data;
hitbox_component_data_t *hitbox_component_data = component_data->hitbox_component_data;
if(component_data->state != component_data->last_state)
{
animation_system_data->play = true;
animation_system_data->reverse = !component_data->state;
hitbox_component_data->activated = !component_data->state;
}
component_data->last_state = component_data->state;
return EXIT_SUCCESS;
}
inline int door_component_destroy(component_t *component)
{
door_component_data_t *component_data = component->data;
free(component_data);
return EXIT_SUCCESS;
}

View File

@ -17,6 +17,7 @@ COMPONENT(SPRITE_COMPONENT, sprite_component, DRAW)
COMPONENT(ANIMATION_SYSTEM, animation_system, NO_DRAW) COMPONENT(ANIMATION_SYSTEM, animation_system, NO_DRAW)
COMPONENT(PLAYER_SYSTEM, player_system, NO_DRAW) COMPONENT(PLAYER_SYSTEM, player_system, NO_DRAW)
COMPONENT(LEVER_COMPONENT, lever_component, NO_DRAW) COMPONENT(LEVER_COMPONENT, lever_component, NO_DRAW)
COMPONENT(DOOR_COMPONENT, door_component, NO_DRAW)
// Add new components definition here // Add new components definition here
#undef COMPONENT #undef COMPONENT

View File

@ -9,6 +9,7 @@
#include "interact_component.h" #include "interact_component.h"
#include "player_system.h" #include "player_system.h"
#include "lever_component.h" #include "lever_component.h"
#include "door_component.h"
// Add new components header file here // Add new components header file here
#endif // COMPONENTS_H #endif // COMPONENTS_H

View File

@ -0,0 +1,26 @@
#ifndef DOOR_COMPONENT_H
#define DOOR_COMPONENT_H
#include "ecs.h"
#include "animation_system.h"
#include "hitbox_component.h"
#define DOOR_DEFAULT_ANIMATION_SPEED 30
typedef struct door_component_data_t {
animation_system_data_t *animation_system_data;
hitbox_component_data_t *hitbox_component_data;
bool state;
bool last_state;
size_t topic_id;
} door_component_data_t;
int door_component_init(component_t *component);
int door_component_update(component_t *component);
int door_component_destroy(component_t *component);
#endif // DOOR_COMPONENT_H

View File

@ -34,8 +34,8 @@ int interact_component_draw(const component_t *component);
int interact_component_destroy(component_t *component); int interact_component_destroy(component_t *component);
int interact_component_interact(interact_component_data_t *component_data, const entity_t *entity); int interact_component_interact(interact_component_data_t *component_data);
int interact_component_modify_topic(interact_component_data_t *component_data, size_t id, size_t max_history_size); int interact_component_modify_topic(interact_component_data_t *component_data, size_t id);
#endif // TRANSFORM_COMPONENT_H #endif // TRANSFORM_COMPONENT_H

View File

@ -3,17 +3,17 @@
#include "ecs.h" #include "ecs.h"
#include "animation_system.h" #include "animation_system.h"
#include "interact_component.h"
#include "vector2d.h" #include "vector2d.h"
#define LEVER_DEFAULT_ANIMATION_SPEED 100 #define LEVER_DEFAULT_ANIMATION_SPEED 100
typedef struct lever_component_data_t { typedef struct lever_component_data_t {
animation_system_data_t *animation_system_data; animation_system_data_t *animation_system_data;
interact_component_data_t *interact_component_data;
bool state; bool state;
bool last_state; bool last_state;
size_t topic_id;
} lever_component_data_t; } lever_component_data_t;
int lever_component_init(component_t *component); int lever_component_init(component_t *component);

View File

@ -31,7 +31,7 @@ inline int interact_component_init(component_t *component)
component_data->state = 0; component_data->state = 0;
if(event_bus_new_topic(&game.event_bus, component_data->topic_id, 1)) return EXIT_FAILURE; if(event_bus_new_topic(&game.event_bus, component_data->topic_id)) return EXIT_FAILURE;
component_data->activated = true; component_data->activated = true;
@ -73,7 +73,7 @@ inline int interact_component_destroy(component_t *component)
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
inline int interact_component_interact(interact_component_data_t *component_data, const entity_t *entity) inline int interact_component_interact(interact_component_data_t *component_data)
{ {
switch(component_data->type) switch(component_data->type)
{ {
@ -85,12 +85,12 @@ inline int interact_component_interact(interact_component_data_t *component_data
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if(event_bus_publish(&game.event_bus, component_data->topic_id, entity, component_data->state)) return EXIT_FAILURE; if(event_bus_publish(&game.event_bus, component_data->topic_id, component_data->state)) return EXIT_FAILURE;
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
inline int interact_component_modify_topic(interact_component_data_t *component_data, size_t id, size_t max_history_size) inline int interact_component_modify_topic(interact_component_data_t *component_data, size_t id)
{ {
if(event_bus_change_topic_id(&game.event_bus, component_data->topic_id, id)) return EXIT_FAILURE; if(event_bus_change_topic_id(&game.event_bus, component_data->topic_id, id)) return EXIT_FAILURE;

View File

@ -8,17 +8,19 @@
#include "memory_alloc.h" #include "memory_alloc.h"
#include "errors.h" #include "errors.h"
#include "hitbox_component.h"
// Args = entity_t *entity, size_t state // Args = entity_t *entity, size_t state
static inline int lever_component_callback(va_list args) static inline int lever_component_callback(va_list args, void *subscription_data)
{ {
const entity_t *entity = va_arg(args, entity_t *); const entity_t *entity = subscription_data;
component_t *lever_component = entity_get_component(entity, LEVER_COMPONENT); component_t *lever_component = entity_get_component(entity, LEVER_COMPONENT);
if(!lever_component) return EXIT_FAILURE; if(!lever_component) return EXIT_FAILURE;
lever_component_data_t *component_data = lever_component->data; lever_component_data_t *component_data = lever_component->data;
component_data->state = va_arg(args, size_t); component_data->state = (bool)va_arg(args, size_t);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
@ -35,25 +37,18 @@ inline int lever_component_init(component_t *component)
} }
component_data->animation_system_data = animation_system->data; component_data->animation_system_data = animation_system->data;
component_t *interact_component = entity_get_component(component->entity, INTERACT_COMPONENT);
if(!interact_component)
{
error_printf("Lever component require a transform component.");
return EXIT_FAILURE;
}
component_data->interact_component_data = interact_component->data;
animation_system_data_t *animation_system_data = component_data->animation_system_data; animation_system_data_t *animation_system_data = component_data->animation_system_data;
animation_system_data->nb_frames = 3; animation_system_data->nb_frames = 3;
animation_system_data->frame_delay_ms = LEVER_DEFAULT_ANIMATION_SPEED; animation_system_data->frame_delay_ms = LEVER_DEFAULT_ANIMATION_SPEED;
if(animation_system_create_frames_clips(animation_system_data)) return EXIT_FAILURE; if(animation_system_create_frames_clips(animation_system_data)) return EXIT_FAILURE;
interact_component_data_t *interact_component_data = component_data->interact_component_data; component_data->topic_id = 0;
event_bus_subscribe(&game.event_bus, interact_component_data->topic_id, lever_component_callback); event_bus_subscribe(&game.event_bus, component_data->topic_id, lever_component_callback, component->entity);
component_data->state = false; component_data->state = false;
component_data->last_state = false;
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View File

@ -181,7 +181,7 @@ static inline int action_detect_activate_interact(elem_t *elem, va_list args)
if(fhas_intersection(hitbox_bounds, target_interact_bounds)) if(fhas_intersection(hitbox_bounds, target_interact_bounds))
{ {
if(interact_component_interact(target_interact_component_data, target_entity)) return EXIT_FAILURE; if(interact_component_interact(target_interact_component_data)) return EXIT_FAILURE;
} }
return EXIT_SUCCESS; return EXIT_SUCCESS;

View File

@ -108,8 +108,8 @@ int game_init(void)
if(!entity_new_component(lever_entity, LEVER_COMPONENT)) return EXIT_FAILURE; if(!entity_new_component(lever_entity, LEVER_COMPONENT)) return EXIT_FAILURE;
/* ======== Door ======== */ /* ======== Door ======== */
entity_t *door_entity = entity_manager_new_entity(&game.entity_manager, 2); entity_t *door_entity = entity_manager_new_entity(&game.entity_manager, 1);
if(!door_entity) return EXIT_FAILURE; if(!lever_entity) return EXIT_FAILURE;
component = entity_new_component(door_entity, TRANSFORM_COMPONENT); component = entity_new_component(door_entity, TRANSFORM_COMPONENT);
if(!component) return EXIT_FAILURE; if(!component) return EXIT_FAILURE;
@ -126,6 +126,8 @@ int game_init(void)
if(sprite_component_set_texture(component->data, "barred_door_sheet")) return EXIT_FAILURE; if(sprite_component_set_texture(component->data, "barred_door_sheet")) return EXIT_FAILURE;
if(!entity_new_component(door_entity, ANIMATION_SYSTEM)) return EXIT_FAILURE;
component = entity_new_component(door_entity, HITBOX_COMPONENT); component = entity_new_component(door_entity, HITBOX_COMPONENT);
if(!component) return EXIT_FAILURE; if(!component) return EXIT_FAILURE;
@ -139,6 +141,8 @@ int game_init(void)
.y = 1.0f / 7.0f .y = 1.0f / 7.0f
}; };
if(!entity_new_component(door_entity, DOOR_COMPONENT)) return EXIT_FAILURE;
game.is_running = true; game.is_running = true;
return EXIT_SUCCESS; return EXIT_SUCCESS;