Compare commits
8 Commits
8ae999ccc8
...
911663b51f
Author | SHA1 | Date |
---|---|---|
|
911663b51f | |
|
70d52cca5b | |
|
c52651ca1b | |
|
b18e072d51 | |
|
73ea7edd07 | |
|
ad789329d1 | |
|
841603a432 | |
|
8165cd41c2 |
|
@ -26,6 +26,7 @@ typedef enum ComponentEnum {
|
||||||
CLIFETIMER_T,
|
CLIFETIMER_T,
|
||||||
CWATERRUNNER_T,
|
CWATERRUNNER_T,
|
||||||
CAIRTIMER_T,
|
CAIRTIMER_T,
|
||||||
|
CEMITTER_T,
|
||||||
} ComponentEnum_t;
|
} ComponentEnum_t;
|
||||||
|
|
||||||
typedef enum MovementMode {
|
typedef enum MovementMode {
|
||||||
|
@ -215,6 +216,13 @@ typedef struct _CMoveable_t {
|
||||||
bool gridmove;
|
bool gridmove;
|
||||||
} CMoveable_t;
|
} CMoveable_t;
|
||||||
|
|
||||||
|
typedef uint16_t EmitterHandle;
|
||||||
|
typedef struct _CEmitter_t
|
||||||
|
{
|
||||||
|
EmitterHandle handle;
|
||||||
|
Vector2 offset;
|
||||||
|
} CEmitter_t;
|
||||||
|
|
||||||
static inline void set_bbox(CBBox_t* p_bbox, unsigned int x, unsigned int y)
|
static inline void set_bbox(CBBox_t* p_bbox, unsigned int x, unsigned int y)
|
||||||
{
|
{
|
||||||
p_bbox->size.x = x;
|
p_bbox->size.x = x;
|
||||||
|
|
|
@ -17,6 +17,6 @@
|
||||||
#define MAX_TILE_TYPES 16
|
#define MAX_TILE_TYPES 16
|
||||||
|
|
||||||
#define N_TAGS 10
|
#define N_TAGS 10
|
||||||
#define N_COMPONENTS 14
|
#define N_COMPONENTS 15
|
||||||
#define MAX_COMP_POOL_SIZE 1024
|
#define MAX_COMP_POOL_SIZE 1024
|
||||||
#endif // _ENGINE_CONF_H
|
#endif // _ENGINE_CONF_H
|
||||||
|
|
|
@ -77,6 +77,7 @@ static CMoveable_t cmoveable_buffer[MAX_COMP_POOL_SIZE];
|
||||||
static CLifeTimer_t clifetimer_buffer[MAX_COMP_POOL_SIZE];
|
static CLifeTimer_t clifetimer_buffer[MAX_COMP_POOL_SIZE];
|
||||||
static CWaterRunner_t cwaterrunner_buffer[32];
|
static CWaterRunner_t cwaterrunner_buffer[32];
|
||||||
static CAirTimer_t cairtimer_buffer[8]; // Only player is expected to have this
|
static CAirTimer_t cairtimer_buffer[8]; // Only player is expected to have this
|
||||||
|
static CEmitter_t cemitter_buffer[MAX_COMP_POOL_SIZE]; // Only player is expected to have this
|
||||||
|
|
||||||
// Static allocate mempools
|
// Static allocate mempools
|
||||||
static MemPool_t comp_mempools[N_COMPONENTS] = {
|
static MemPool_t comp_mempools[N_COMPONENTS] = {
|
||||||
|
@ -94,6 +95,7 @@ static MemPool_t comp_mempools[N_COMPONENTS] = {
|
||||||
{clifetimer_buffer, MAX_COMP_POOL_SIZE, sizeof(CLifeTimer_t), NULL, {0}},
|
{clifetimer_buffer, MAX_COMP_POOL_SIZE, sizeof(CLifeTimer_t), NULL, {0}},
|
||||||
{cwaterrunner_buffer, 32, sizeof(CWaterRunner_t), NULL, {0}},
|
{cwaterrunner_buffer, 32, sizeof(CWaterRunner_t), NULL, {0}},
|
||||||
{cairtimer_buffer, 8, sizeof(CAirTimer_t), NULL, {0}},
|
{cairtimer_buffer, 8, sizeof(CAirTimer_t), NULL, {0}},
|
||||||
|
{cemitter_buffer, MAX_COMP_POOL_SIZE, sizeof(CEmitter_t), NULL, {0}},
|
||||||
};
|
};
|
||||||
static MemPool_t ent_mempool = {
|
static MemPool_t ent_mempool = {
|
||||||
.buffer = entity_buffer,
|
.buffer = entity_buffer,
|
||||||
|
|
|
@ -103,7 +103,7 @@ void play_emitter_handle(ParticleSystem_t* system, uint16_t handle)
|
||||||
|
|
||||||
// An emitter cannot be unloaded or paused mid-way when particles to still
|
// An emitter cannot be unloaded or paused mid-way when particles to still
|
||||||
// emitting, so defer into update function to do so
|
// emitting, so defer into update function to do so
|
||||||
void pause_emitter_handle(ParticleSystem_t* system, uint16_t handle)
|
void stop_emitter_handle(ParticleSystem_t* system, EmitterHandle handle)
|
||||||
{
|
{
|
||||||
if (handle == 0) return;
|
if (handle == 0) return;
|
||||||
//if (!system->emitter_list[handle].playing) return;
|
//if (!system->emitter_list[handle].playing) return;
|
||||||
|
@ -118,7 +118,7 @@ void update_emitter_handle_position(ParticleSystem_t* system, EmitterHandle hand
|
||||||
system->emitters[handle].position = pos;
|
system->emitters[handle].position = pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
void unload_emitter_handle(ParticleSystem_t* system, uint16_t handle)
|
void unload_emitter_handle(ParticleSystem_t* system, EmitterHandle handle)
|
||||||
{
|
{
|
||||||
if (handle == 0) return;
|
if (handle == 0) return;
|
||||||
|
|
||||||
|
@ -126,12 +126,20 @@ void unload_emitter_handle(ParticleSystem_t* system, uint16_t handle)
|
||||||
system->emitters[handle].finished = true;
|
system->emitters[handle].finished = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void play_particle_emitter(ParticleSystem_t* system, const ParticleEmitter_t* in_emitter)
|
bool is_emitter_handle_alive(ParticleSystem_t* system, EmitterHandle handle)
|
||||||
{
|
{
|
||||||
uint16_t idx = load_in_particle_emitter(system, in_emitter);
|
if (handle == 0) return false;
|
||||||
if (idx == 0) return;
|
|
||||||
|
return system->emitters[handle].active;
|
||||||
|
}
|
||||||
|
|
||||||
|
EmitterHandle play_particle_emitter(ParticleSystem_t* system, const ParticleEmitter_t* in_emitter)
|
||||||
|
{
|
||||||
|
EmitterHandle idx = load_in_particle_emitter(system, in_emitter);
|
||||||
|
if (idx == 0) return 0 ;
|
||||||
|
|
||||||
play_emitter_handle(system, idx);
|
play_emitter_handle(system, idx);
|
||||||
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_particle_system(ParticleSystem_t* system)
|
void update_particle_system(ParticleSystem_t* system)
|
||||||
|
@ -143,6 +151,12 @@ void update_particle_system(ParticleSystem_t* system)
|
||||||
{
|
{
|
||||||
ParticleEmitter_t* emitter = system->emitters + emitter_idx;
|
ParticleEmitter_t* emitter = system->emitters + emitter_idx;
|
||||||
uint32_t inactive_count = 0;
|
uint32_t inactive_count = 0;
|
||||||
|
|
||||||
|
if (emitter->emitter_update_func != NULL && emitter->active)
|
||||||
|
{
|
||||||
|
emitter->active = emitter->emitter_update_func(emitter);
|
||||||
|
}
|
||||||
|
|
||||||
for (uint32_t i = 0; i < emitter->n_particles; ++i)
|
for (uint32_t i = 0; i < emitter->n_particles; ++i)
|
||||||
{
|
{
|
||||||
// TODO: If a particle is not spawned, run its timer. Spawn on zero
|
// TODO: If a particle is not spawned, run its timer. Spawn on zero
|
||||||
|
@ -187,10 +201,11 @@ void update_particle_system(ParticleSystem_t* system)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inactive_count == emitter->n_particles)
|
if (inactive_count == emitter->n_particles)
|
||||||
{
|
{
|
||||||
// Stop playing only if all particles is inactive
|
// Stop playing only if all particles is inactive
|
||||||
if (!emitter->finished && emitter->config->one_shot)
|
if (!emitter->finished)
|
||||||
{
|
{
|
||||||
emitter->finished = true;
|
emitter->finished = true;
|
||||||
}
|
}
|
||||||
|
@ -213,6 +228,7 @@ void update_particle_system(ParticleSystem_t* system)
|
||||||
emitter_idx = system->emitter_list[emitter_idx].next;
|
emitter_idx = system->emitter_list[emitter_idx].next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_particle_system(ParticleSystem_t* system)
|
void draw_particle_system(ParticleSystem_t* system)
|
||||||
{
|
{
|
||||||
uint32_t emitter_idx = system->emitter_list[0].next;
|
uint32_t emitter_idx = system->emitter_list[0].next;
|
||||||
|
|
|
@ -7,8 +7,6 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
typedef uint16_t EmitterHandle;
|
|
||||||
|
|
||||||
typedef enum PartEmitterType
|
typedef enum PartEmitterType
|
||||||
{
|
{
|
||||||
EMITTER_UNKNOWN = 0,
|
EMITTER_UNKNOWN = 0,
|
||||||
|
@ -29,7 +27,10 @@ typedef struct Particle
|
||||||
bool spawned;
|
bool spawned;
|
||||||
}Particle_t;
|
}Particle_t;
|
||||||
|
|
||||||
|
typedef struct ParticleEmitter ParticleEmitter_t;
|
||||||
|
|
||||||
typedef void (*particle_update_func_t)(Particle_t* part, void* user_data);
|
typedef void (*particle_update_func_t)(Particle_t* part, void* user_data);
|
||||||
|
typedef bool (*emitter_check_func_t)(const ParticleEmitter_t* emitter);
|
||||||
|
|
||||||
typedef struct EmitterConfig
|
typedef struct EmitterConfig
|
||||||
{
|
{
|
||||||
|
@ -41,7 +42,7 @@ typedef struct EmitterConfig
|
||||||
bool one_shot;
|
bool one_shot;
|
||||||
}EmitterConfig_t;
|
}EmitterConfig_t;
|
||||||
|
|
||||||
typedef struct ParticleEmitter
|
struct ParticleEmitter
|
||||||
{
|
{
|
||||||
const EmitterConfig_t* config;
|
const EmitterConfig_t* config;
|
||||||
Sprite_t* spr;
|
Sprite_t* spr;
|
||||||
|
@ -53,7 +54,8 @@ typedef struct ParticleEmitter
|
||||||
bool active;
|
bool active;
|
||||||
void* user_data;
|
void* user_data;
|
||||||
particle_update_func_t update_func;
|
particle_update_func_t update_func;
|
||||||
}ParticleEmitter_t;
|
emitter_check_func_t emitter_update_func;
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct IndexList
|
typedef struct IndexList
|
||||||
{
|
{
|
||||||
|
@ -75,13 +77,14 @@ void init_particle_system(ParticleSystem_t* system);
|
||||||
uint16_t get_number_of_free_emitter(ParticleSystem_t* system);
|
uint16_t get_number_of_free_emitter(ParticleSystem_t* system);
|
||||||
|
|
||||||
// For one-shots
|
// For one-shots
|
||||||
void play_particle_emitter(ParticleSystem_t* system, const ParticleEmitter_t* in_emitter);
|
EmitterHandle play_particle_emitter(ParticleSystem_t* system, const ParticleEmitter_t* in_emitter);
|
||||||
|
|
||||||
EmitterHandle load_in_particle_emitter(ParticleSystem_t* system, const ParticleEmitter_t* in_emitter);
|
EmitterHandle load_in_particle_emitter(ParticleSystem_t* system, const ParticleEmitter_t* in_emitter);
|
||||||
void play_emitter_handle(ParticleSystem_t* system, EmitterHandle handle);
|
void play_emitter_handle(ParticleSystem_t* system, EmitterHandle handle);
|
||||||
void pause_emitter_handle(ParticleSystem_t* system, EmitterHandle handle);
|
void stop_emitter_handle(ParticleSystem_t* system, EmitterHandle handle);
|
||||||
void update_emitter_handle_position(ParticleSystem_t* system, EmitterHandle handle, Vector2 pos);
|
void update_emitter_handle_position(ParticleSystem_t* system, EmitterHandle handle, Vector2 pos);
|
||||||
void unload_emitter_handle(ParticleSystem_t* system, EmitterHandle handle);
|
void unload_emitter_handle(ParticleSystem_t* system, EmitterHandle handle);
|
||||||
|
bool is_emitter_handle_alive(ParticleSystem_t* system, EmitterHandle handle);
|
||||||
|
|
||||||
void update_particle_system(ParticleSystem_t* system);
|
void update_particle_system(ParticleSystem_t* system);
|
||||||
void draw_particle_system(ParticleSystem_t* system);
|
void draw_particle_system(ParticleSystem_t* system);
|
||||||
|
|
|
@ -45,6 +45,12 @@ void simple_particle_system_update(Particle_t* part, void* user_data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool check_mouse_click(const ParticleEmitter_t* emitter)
|
||||||
|
{
|
||||||
|
return IsMouseButtonDown(MOUSE_RIGHT_BUTTON);
|
||||||
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
InitWindow(1280, 640, "raylib");
|
InitWindow(1280, 640, "raylib");
|
||||||
|
@ -76,12 +82,14 @@ int main(void)
|
||||||
.config = &conf,
|
.config = &conf,
|
||||||
.n_particles = MAX_PARTICLES,
|
.n_particles = MAX_PARTICLES,
|
||||||
.update_func = &simple_particle_system_update,
|
.update_func = &simple_particle_system_update,
|
||||||
|
.emitter_update_func = NULL,
|
||||||
.spr = (tex.width == 0) ? NULL : &spr,
|
.spr = (tex.width == 0) ? NULL : &spr,
|
||||||
};
|
};
|
||||||
|
|
||||||
EmitterConfig_t conf2 ={
|
EmitterConfig_t conf2 ={
|
||||||
.one_shot = false,
|
.one_shot = false,
|
||||||
.launch_range = {45, 135},
|
.launch_range = {45, 135},
|
||||||
|
//.launch_range = {0, 360},
|
||||||
.speed_range = {300, 800},
|
.speed_range = {300, 800},
|
||||||
.particle_lifetime = {15, 30},
|
.particle_lifetime = {15, 30},
|
||||||
.initial_spawn_delay = 5,
|
.initial_spawn_delay = 5,
|
||||||
|
@ -92,15 +100,14 @@ int main(void)
|
||||||
.config = &conf2,
|
.config = &conf2,
|
||||||
.n_particles = MAX_PARTICLES,
|
.n_particles = MAX_PARTICLES,
|
||||||
.update_func = &simple_particle_system_update,
|
.update_func = &simple_particle_system_update,
|
||||||
|
.emitter_update_func = &check_mouse_click,
|
||||||
.spr = (tex.width == 0) ? NULL : &spr,
|
.spr = (tex.width == 0) ? NULL : &spr,
|
||||||
};
|
};
|
||||||
|
|
||||||
EmitterHandle han = load_in_particle_emitter(&part_sys, &emitter2);
|
|
||||||
assert(han != 0);
|
|
||||||
|
|
||||||
bool key_press = false;
|
bool key_press = false;
|
||||||
uint8_t key2_press = 0;
|
uint8_t key2_press = 0;
|
||||||
char text_buffer[32];
|
char text_buffer[32];
|
||||||
|
EmitterHandle han = 0;
|
||||||
while(!WindowShouldClose())
|
while(!WindowShouldClose())
|
||||||
{
|
{
|
||||||
Vector2 mouse_pos = GetMousePosition();
|
Vector2 mouse_pos = GetMousePosition();
|
||||||
|
@ -121,8 +128,8 @@ int main(void)
|
||||||
|
|
||||||
if (key2_press == 0b01)
|
if (key2_press == 0b01)
|
||||||
{
|
{
|
||||||
update_emitter_handle_position(&part_sys, han, mouse_pos);
|
emitter2.position = mouse_pos;
|
||||||
play_emitter_handle(&part_sys, han);
|
han = play_particle_emitter(&part_sys, &emitter2);
|
||||||
}
|
}
|
||||||
else if(key2_press == 0b11)
|
else if(key2_press == 0b11)
|
||||||
{
|
{
|
||||||
|
@ -130,7 +137,8 @@ int main(void)
|
||||||
}
|
}
|
||||||
else if (key2_press == 0b10)
|
else if (key2_press == 0b10)
|
||||||
{
|
{
|
||||||
pause_emitter_handle(&part_sys, han);
|
stop_emitter_handle(&part_sys, han);
|
||||||
|
han = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
update_particle_system(&part_sys);
|
update_particle_system(&part_sys);
|
||||||
|
|
|
@ -41,20 +41,28 @@ static bool parse_emitter_info(char* emitter_info_str, EmitterConfig_t* conf)
|
||||||
char emitter_type;
|
char emitter_type;
|
||||||
uint8_t one_shot;
|
uint8_t one_shot;
|
||||||
int data_count = sscanf(
|
int data_count = sscanf(
|
||||||
emitter_info_str, "%c,%f-%f,%f-%f,%u-%u,%c",
|
emitter_info_str, "%c,%f-%f,%f-%f,%u-%u,%u,%c",
|
||||||
&emitter_type,
|
&emitter_type,
|
||||||
conf->launch_range, conf->launch_range + 1,
|
conf->launch_range, conf->launch_range + 1,
|
||||||
conf->speed_range, conf->speed_range + 1,
|
conf->speed_range, conf->speed_range + 1,
|
||||||
conf->particle_lifetime, conf->particle_lifetime + 1,
|
conf->particle_lifetime, conf->particle_lifetime + 1,
|
||||||
&one_shot
|
&conf->initial_spawn_delay, &one_shot
|
||||||
);
|
);
|
||||||
|
|
||||||
if (data_count == 8)
|
if (data_count == 9)
|
||||||
{
|
{
|
||||||
conf->type = (emitter_type == 'b') ? EMITTER_BURST : EMITTER_UNKNOWN;
|
conf->type = EMITTER_UNKNOWN;
|
||||||
|
if (emitter_type == 'b')
|
||||||
|
{
|
||||||
|
conf->type = EMITTER_BURST;
|
||||||
|
}
|
||||||
|
else if (emitter_type == 's')
|
||||||
|
{
|
||||||
|
conf->type = EMITTER_STREAM;
|
||||||
|
}
|
||||||
conf->one_shot = (one_shot == '1');
|
conf->one_shot = (one_shot == '1');
|
||||||
}
|
}
|
||||||
return data_count == 8;
|
return data_count == 9;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline AssetInfoType_t get_asset_type(const char* str)
|
static inline AssetInfoType_t get_asset_type(const char* str)
|
||||||
|
|
|
@ -171,6 +171,10 @@ static void level_scene_render_func(Scene_t* scene)
|
||||||
sprintf(buffer, "FPS: %u", GetFPS());
|
sprintf(buffer, "FPS: %u", GetFPS());
|
||||||
DrawText(buffer, gui_x, gui_y, 12, BLACK);
|
DrawText(buffer, gui_x, gui_y, 12, BLACK);
|
||||||
|
|
||||||
|
gui_y += 30;
|
||||||
|
sprintf(buffer, "part sys free: %u", get_number_of_free_emitter(&scene->part_sys));
|
||||||
|
DrawText(buffer, gui_x, gui_y, 12, BLACK);
|
||||||
|
|
||||||
gui_y += 30;
|
gui_y += 30;
|
||||||
print_mempool_stats(buffer);
|
print_mempool_stats(buffer);
|
||||||
DrawText(buffer, gui_x, gui_y, 12, BLACK);
|
DrawText(buffer, gui_x, gui_y, 12, BLACK);
|
||||||
|
@ -1022,6 +1026,7 @@ void init_sandbox_scene(LevelScene_t* scene)
|
||||||
sc_array_add(&scene->scene.systems, &spike_collision_system);
|
sc_array_add(&scene->scene.systems, &spike_collision_system);
|
||||||
sc_array_add(&scene->scene.systems, &edge_velocity_check_system);
|
sc_array_add(&scene->scene.systems, &edge_velocity_check_system);
|
||||||
sc_array_add(&scene->scene.systems, &state_transition_update_system);
|
sc_array_add(&scene->scene.systems, &state_transition_update_system);
|
||||||
|
sc_array_add(&scene->scene.systems, &update_entity_emitter_system);
|
||||||
sc_array_add(&scene->scene.systems, &player_ground_air_transition_system);
|
sc_array_add(&scene->scene.systems, &player_ground_air_transition_system);
|
||||||
sc_array_add(&scene->scene.systems, &lifetimer_update_system);
|
sc_array_add(&scene->scene.systems, &lifetimer_update_system);
|
||||||
sc_array_add(&scene->scene.systems, &airtimer_update_system);
|
sc_array_add(&scene->scene.systems, &airtimer_update_system);
|
||||||
|
|
|
@ -378,6 +378,7 @@ void init_game_scene(LevelScene_t* scene)
|
||||||
sc_array_add(&scene->scene.systems, &spike_collision_system);
|
sc_array_add(&scene->scene.systems, &spike_collision_system);
|
||||||
sc_array_add(&scene->scene.systems, &edge_velocity_check_system);
|
sc_array_add(&scene->scene.systems, &edge_velocity_check_system);
|
||||||
sc_array_add(&scene->scene.systems, &state_transition_update_system);
|
sc_array_add(&scene->scene.systems, &state_transition_update_system);
|
||||||
|
sc_array_add(&scene->scene.systems, &update_entity_emitter_system);
|
||||||
sc_array_add(&scene->scene.systems, &player_ground_air_transition_system);
|
sc_array_add(&scene->scene.systems, &player_ground_air_transition_system);
|
||||||
sc_array_add(&scene->scene.systems, &lifetimer_update_system);
|
sc_array_add(&scene->scene.systems, &lifetimer_update_system);
|
||||||
sc_array_add(&scene->scene.systems, &airtimer_update_system);
|
sc_array_add(&scene->scene.systems, &airtimer_update_system);
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
void simple_particle_system_update(Particle_t* part, void* user_data);
|
void simple_particle_system_update(Particle_t* part, void* user_data);
|
||||||
|
void floating_particle_system_update(Particle_t* part, void* user_data);
|
||||||
|
bool check_in_water(const ParticleEmitter_t* emitter);
|
||||||
|
|
||||||
static const Vector2 GRAVITY = {0, GRAV_ACCEL};
|
static const Vector2 GRAVITY = {0, GRAV_ACCEL};
|
||||||
static const Vector2 UPTHRUST = {0, -GRAV_ACCEL * 1.1};
|
static const Vector2 UPTHRUST = {0, -GRAV_ACCEL * 1.1};
|
||||||
|
@ -1469,8 +1471,47 @@ void state_transition_update_system(Scene_t* scene)
|
||||||
.n_particles = 5,
|
.n_particles = 5,
|
||||||
.user_data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data),
|
.user_data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data),
|
||||||
.update_func = &simple_particle_system_update,
|
.update_func = &simple_particle_system_update,
|
||||||
|
.emitter_update_func = NULL,
|
||||||
};
|
};
|
||||||
play_particle_emitter(&scene->part_sys, &emitter);
|
play_particle_emitter(&scene->part_sys, &emitter);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p_mstate->water_state & 1)
|
||||||
|
{
|
||||||
|
CEmitter_t* p_emitter = get_component(p_ent, CEMITTER_T);
|
||||||
|
if (p_emitter != NULL)
|
||||||
|
{
|
||||||
|
if (!is_emitter_handle_alive(&scene->part_sys, p_emitter->handle))
|
||||||
|
{
|
||||||
|
ParticleEmitter_t emitter = {
|
||||||
|
.spr = get_sprite(&scene->engine->assets, "p_water"),
|
||||||
|
.config = get_emitter_conf(&scene->engine->assets, "pe_bubbling"),
|
||||||
|
.position = p_ctransform->position,
|
||||||
|
.n_particles = 5,
|
||||||
|
.user_data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data),
|
||||||
|
.update_func = &floating_particle_system_update,
|
||||||
|
.emitter_update_func = &check_in_water,
|
||||||
|
};
|
||||||
|
p_emitter->handle = play_particle_emitter(&scene->part_sys, &emitter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void update_entity_emitter_system(Scene_t* scene)
|
||||||
|
{
|
||||||
|
CEmitter_t* p_emitter;
|
||||||
|
unsigned long ent_idx;
|
||||||
|
sc_map_foreach(&scene->ent_manager.component_map[CEMITTER_T], ent_idx, p_emitter)
|
||||||
|
{
|
||||||
|
Entity_t* p_ent = get_entity(&scene->ent_manager, ent_idx);
|
||||||
|
CTransform_t* p_ctransform = get_component(p_ent, CTRANSFORM_COMP_T);
|
||||||
|
CBBox_t* p_bbox = get_component(p_ent, CBBOX_COMP_T);
|
||||||
|
if (is_emitter_handle_alive(&scene->part_sys, p_emitter->handle))
|
||||||
|
{
|
||||||
|
update_emitter_handle_position(&scene->part_sys, p_emitter->handle, p_ctransform->position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2067,6 +2108,30 @@ void level_end_detection_system(Scene_t* scene)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool is_point_in_water(Vector2 pos, TileGrid_t tilemap)
|
||||||
|
{
|
||||||
|
unsigned int tile_idx = get_tile_idx(
|
||||||
|
pos.x,
|
||||||
|
pos.y,
|
||||||
|
tilemap.width
|
||||||
|
);
|
||||||
|
int tile_x = tile_idx % tilemap.width;
|
||||||
|
int tile_y = tile_idx / tilemap.width;
|
||||||
|
uint32_t water_height = tilemap.tiles[tile_idx].water_level * WATER_BBOX_STEP;
|
||||||
|
Vector2 tl = {tile_x * tilemap.tile_size, (tile_y + 1) * tilemap.tile_size - water_height};
|
||||||
|
return point_in_AABB(
|
||||||
|
pos,
|
||||||
|
(Rectangle){tl.x, tl.y, tilemap.tile_size, water_height}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool check_in_water(const ParticleEmitter_t* emitter)
|
||||||
|
{
|
||||||
|
LevelSceneData_t* lvl_data = (LevelSceneData_t*)emitter->user_data;
|
||||||
|
TileGrid_t tilemap = lvl_data->tilemap;
|
||||||
|
return is_point_in_water(emitter->position, tilemap);
|
||||||
|
}
|
||||||
|
|
||||||
void simple_particle_system_update(Particle_t* part, void* user_data)
|
void simple_particle_system_update(Particle_t* part, void* user_data)
|
||||||
{
|
{
|
||||||
LevelSceneData_t* lvl_data = (LevelSceneData_t*)user_data;
|
LevelSceneData_t* lvl_data = (LevelSceneData_t*)user_data;
|
||||||
|
@ -2093,18 +2158,53 @@ void simple_particle_system_update(Particle_t* part, void* user_data)
|
||||||
Vector2Scale(part->velocity, delta_time)
|
Vector2Scale(part->velocity, delta_time)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Vector2 center = Vector2AddValue(
|
||||||
|
part->position,
|
||||||
|
part->size / 2
|
||||||
|
);
|
||||||
// Level boundary collision
|
// Level boundary collision
|
||||||
unsigned int level_width = tilemap.width * TILE_SIZE;
|
unsigned int level_width = tilemap.width * TILE_SIZE;
|
||||||
unsigned int level_height = tilemap.height * TILE_SIZE;
|
unsigned int level_height = tilemap.height * TILE_SIZE;
|
||||||
{
|
|
||||||
|
|
||||||
if(
|
if(
|
||||||
part->position.x < 0 || part->position.x + part->size > level_width
|
center.x < 0 || center.x + part->size > level_width
|
||||||
|| part->position.y < 0 || part->position.y + part->size > level_height
|
|| center.y < 0 || center.y + part->size > level_height
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
part->timer = 0;
|
part->timer = 0;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void floating_particle_system_update(Particle_t* part, void* user_data)
|
||||||
|
{
|
||||||
|
LevelSceneData_t* lvl_data = (LevelSceneData_t*)user_data;
|
||||||
|
TileGrid_t tilemap = lvl_data->tilemap;
|
||||||
|
|
||||||
|
float delta_time = DELTA_T; // TODO: Will need to think about delta time handling
|
||||||
|
part->position = Vector2Add(
|
||||||
|
part->position,
|
||||||
|
Vector2Scale(part->velocity, delta_time)
|
||||||
|
);
|
||||||
|
|
||||||
|
Vector2 center = Vector2AddValue(
|
||||||
|
part->position,
|
||||||
|
part->size / 2
|
||||||
|
);
|
||||||
|
// Level boundary collision
|
||||||
|
unsigned int level_width = tilemap.width * TILE_SIZE;
|
||||||
|
unsigned int level_height = tilemap.height * TILE_SIZE;
|
||||||
|
|
||||||
|
if(
|
||||||
|
center.x < 0 || center.x + part->size > level_width
|
||||||
|
|| center.y < 0 || center.y + part->size > level_height
|
||||||
|
)
|
||||||
|
{
|
||||||
|
part->timer = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
center.y = part->position.y;
|
||||||
|
if (!is_point_in_water(center, tilemap))
|
||||||
|
{
|
||||||
|
part->timer = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ void global_external_forces_system(Scene_t* scene);
|
||||||
void movement_update_system(Scene_t* scene);
|
void movement_update_system(Scene_t* scene);
|
||||||
void player_ground_air_transition_system(Scene_t* scene);
|
void player_ground_air_transition_system(Scene_t* scene);
|
||||||
void state_transition_update_system(Scene_t* scene);
|
void state_transition_update_system(Scene_t* scene);
|
||||||
|
void update_entity_emitter_system(Scene_t* scene);
|
||||||
void update_tilemap_system(Scene_t* scene);
|
void update_tilemap_system(Scene_t* scene);
|
||||||
void hitbox_update_system(Scene_t* scene);
|
void hitbox_update_system(Scene_t* scene);
|
||||||
void edge_velocity_check_system(Scene_t* scene);
|
void edge_velocity_check_system(Scene_t* scene);
|
||||||
|
|
|
@ -183,6 +183,15 @@ Entity_t* create_bomb(EntityManager_t* ent_manager, Vector2 launch_dir)
|
||||||
p_ctransform->position.y += (TILE_SIZE - 25) / 2;
|
p_ctransform->position.y += (TILE_SIZE - 25) / 2;
|
||||||
|
|
||||||
p_ctransform->velocity = Vector2Scale(Vector2Normalize(launch_dir), 500);
|
p_ctransform->velocity = Vector2Scale(Vector2Normalize(launch_dir), 500);
|
||||||
|
|
||||||
|
if (launch_dir.x > 0)
|
||||||
|
{
|
||||||
|
p_ctransform->position.x += TILE_SIZE/ 2;
|
||||||
|
}
|
||||||
|
else if (launch_dir.x < 0)
|
||||||
|
{
|
||||||
|
p_ctransform->position.x -= TILE_SIZE / 2;
|
||||||
|
}
|
||||||
return p_bomb;
|
return p_bomb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -105,6 +105,8 @@ Entity_t* create_player(EntityManager_t* ent_manager)
|
||||||
p_cspr->sprites = player_sprite_map;
|
p_cspr->sprites = player_sprite_map;
|
||||||
p_cspr->transition_func = &player_sprite_transition_func;
|
p_cspr->transition_func = &player_sprite_transition_func;
|
||||||
|
|
||||||
|
add_component(p_ent, CEMITTER_T);
|
||||||
|
|
||||||
return p_ent;
|
return p_ent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue