Making funcitonnal lever component.

This commit is contained in:
Ulysse Cura 2026-08-10 18:23:37 +02:00
parent d3cd4c791e
commit 4668d4dbe4
10 changed files with 145 additions and 13 deletions

@ -1 +1 @@
Subproject commit 2e180b6832978ebd7c211a863a9c2007f3a7c591
Subproject commit 5d902de564b085b322ec68a8396711f430dc0bce

View File

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

View File

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

View File

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

View File

@ -7,7 +7,6 @@
#include "errors.h"
typedef enum interact_type_t {
INTERACT_BUTTON,
INTERACT_TOGGLE
} interact_type_t;
@ -18,9 +17,9 @@ typedef struct interact_component_data_t {
fvector2d_t scale;
frect_t bounds;
size_t topic_id;
interact_type_t type;
size_t event_payload;
size_t state;
size_t topic_id;
bool activated;
} interact_component_data_t;
@ -35,6 +34,8 @@ int interact_component_draw(const component_t *component);
int interact_component_destroy(component_t *component);
inline int interact_component_set_topic(interact_component_data_t *component_data, size_t id);
int interact_component_interact(interact_component_data_t *component_data, const entity_t *entity);
int interact_component_modify_topic(interact_component_data_t *component_data, size_t id, size_t max_history_size);
#endif // TRANSFORM_COMPONENT_H

View File

@ -0,0 +1,25 @@
#ifndef LEVER_COMPONENT_H
#define LEVER_COMPONENT_H
#include "ecs.h"
#include "animation_system.h"
#include "interact_component.h"
#include "vector2d.h"
#define LEVER_DEFAULT_ANIMATION_SPEED 100
typedef struct lever_component_data_t {
animation_system_data_t *animation_system_data;
interact_component_data_t *interact_component_data;
bool state;
bool last_state;
} lever_component_data_t;
int lever_component_init(component_t *component);
int lever_component_update(component_t *component);
int lever_component_destroy(component_t *component);
#endif // LEVER_COMPONENT_H

View File

@ -29,7 +29,7 @@ inline int interact_component_init(component_t *component)
component_data->topic_id = 0;
component_data->type = INTERACT_TOGGLE;
component_data->event_payload = 0;
component_data->state = 0;
if(event_bus_new_topic(&game.event_bus, component_data->topic_id, 1)) return EXIT_FAILURE;
@ -73,7 +73,24 @@ inline int interact_component_destroy(component_t *component)
return EXIT_SUCCESS;
}
inline int interact_component_set_topic(interact_component_data_t *component_data, size_t id)
inline int interact_component_interact(interact_component_data_t *component_data, const entity_t *entity)
{
switch(component_data->type)
{
case INTERACT_TOGGLE:
component_data->state = !component_data->state;
break;
default:
return EXIT_FAILURE;
}
if(event_bus_publish(&game.event_bus, component_data->topic_id, entity, component_data->state)) return EXIT_FAILURE;
return EXIT_SUCCESS;
}
inline int interact_component_modify_topic(interact_component_data_t *component_data, size_t id, size_t max_history_size)
{
if(event_bus_change_topic_id(&game.event_bus, component_data->topic_id, id)) return EXIT_FAILURE;

View File

@ -0,0 +1,84 @@
#include "lever_component.h"
#include <stdarg.h>
#include "game.h"
#include "animation_system.h"
#include "interact_component.h"
#include "event_bus.h"
#include "memory_alloc.h"
#include "errors.h"
// Args = entity_t *entity, size_t state
static inline int lever_component_callback(va_list args)
{
const entity_t *entity = va_arg(args, entity_t *);
component_t *lever_component = entity_get_component(entity, LEVER_COMPONENT);
if(!lever_component) return EXIT_FAILURE;
lever_component_data_t *component_data = lever_component->data;
component_data->state = va_arg(args, size_t);
return EXIT_SUCCESS;
}
inline int lever_component_init(component_t *component)
{
lever_component_data_t *component_data = component->data;
component_t *animation_system = entity_get_component(component->entity, ANIMATION_SYSTEM);
if(!animation_system)
{
error_printf("Lever component require an animation system.");
return EXIT_FAILURE;
}
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->nb_frames = 3;
animation_system_data->frame_delay_ms = LEVER_DEFAULT_ANIMATION_SPEED;
if(animation_system_create_frames_clips(animation_system_data)) return EXIT_FAILURE;
interact_component_data_t *interact_component_data = component_data->interact_component_data;
event_bus_subscribe(&game.event_bus, interact_component_data->topic_id, lever_component_callback);
component_data->state = false;
return EXIT_SUCCESS;
}
inline int lever_component_update(component_t *component)
{
lever_component_data_t *component_data = component->data;
animation_system_data_t *animation_system_data = component_data->animation_system_data;
if(component_data->state != component_data->last_state)
{
animation_system_data->play = true;
animation_system_data->reverse = !component_data->state;
}
component_data->last_state = component_data->state;
return EXIT_SUCCESS;
}
inline int lever_component_destroy(component_t *component)
{
lever_component_data_t *component_data = component->data;
free(component_data);
return EXIT_SUCCESS;
}

View File

@ -169,7 +169,7 @@ static inline int action_detect_activate_interact(elem_t *elem, va_list args)
const component_t *target_interact_component = entity_get_component(target_entity, INTERACT_COMPONENT);
if(!target_interact_component) return EXIT_SUCCESS;
const interact_component_data_t *target_interact_component_data = target_interact_component->data;
interact_component_data_t *target_interact_component_data = target_interact_component->data;
if(!target_interact_component_data->activated)
{
@ -181,9 +181,7 @@ static inline int action_detect_activate_interact(elem_t *elem, va_list args)
if(fhas_intersection(hitbox_bounds, target_interact_bounds))
{
static size_t i = 0;
debug_printf("Interact n*%lu", i++);
if(event_bus_publish(&game.event_bus, target_interact_component_data->topic_id, (void *)&target_interact_component_data->event_payload)) return EXIT_FAILURE;
if(interact_component_interact(target_interact_component_data, target_entity)) return EXIT_FAILURE;
}
return EXIT_SUCCESS;
@ -191,7 +189,7 @@ static inline int action_detect_activate_interact(elem_t *elem, va_list args)
static inline int player_system_process_interaction(player_system_data_t *system_data)
{
static bool last_state = false;
static bool last_state = false; // XXX UGLY XXX //
if(game.events.keys[KEY_INTERACT] && !last_state)
{

View File

@ -77,6 +77,8 @@ int game_init(void)
if(sprite_component_set_texture(component->data, "lever_sheet")) return EXIT_FAILURE;
if(!entity_new_component(lever_entity, ANIMATION_SYSTEM)) return EXIT_FAILURE;
component = entity_new_component(lever_entity, HITBOX_COMPONENT);
if(!component) return EXIT_FAILURE;
@ -103,6 +105,8 @@ int game_init(void)
.y = 5.0f / 6.0f
};
if(!entity_new_component(lever_entity, LEVER_COMPONENT)) return EXIT_FAILURE;
/* ======== Door ======== */
entity_t *door_entity = entity_manager_new_entity(&game.entity_manager, 2);
if(!door_entity) return EXIT_FAILURE;