diff --git a/engine/particle_sys.c b/engine/particle_sys.c index 805a6c5..068e10f 100644 --- a/engine/particle_sys.c +++ b/engine/particle_sys.c @@ -61,15 +61,35 @@ uint16_t load_in_particle_emitter(ParticleSystem_t* system, const ParticleEmitte { system->emitters[idx].n_particles = MAX_PARTICLES; } + system->emitter_list[idx].playing = false; return idx; } void play_emitter_handle(ParticleSystem_t* system, uint16_t handle) { if (handle == 0) return; - system->emitter_list[system->tail_idx].next = handle; - system->tail_idx = handle; - system->emitter_list[handle].next = 0; + if (!system->emitter_list[handle].playing) + { + ParticleEmitter_t* emitter = system->emitters + handle; + if (emitter->config->type == EMITTER_BURST) + { + for (uint32_t i = 0; i < emitter->n_particles; ++i) + { + spawn_particle(emitter, i); + } + } + else if (emitter->config->type == EMITTER_STREAM) + { + // TODO: deal with stream type + //spawn_particle(emitter, 0); + } + system->emitter_list[system->tail_idx].next = handle; + system->tail_idx = handle; + system->emitter_list[handle].next = 0; + system->emitter_list[handle].playing = true; + } + system->emitters[handle].active = true; + } // An emitter cannot be unloaded or paused mid-way when particles to still @@ -77,10 +97,18 @@ void play_emitter_handle(ParticleSystem_t* system, uint16_t handle) void pause_emitter_handle(ParticleSystem_t* system, uint16_t handle) { if (handle == 0) return; + if (!system->emitter_list[handle].playing) return; system->emitters[handle].active = false; } +void update_emitter_handle_position(ParticleSystem_t* system, EmitterHandle handle, Vector2 pos) +{ + if (handle == 0) return; + + system->emitters[handle].position = pos; +} + void unload_emitter_handle(ParticleSystem_t* system, uint16_t handle) { if (handle == 0) return; @@ -94,17 +122,6 @@ void play_particle_emitter(ParticleSystem_t* system, const ParticleEmitter_t* in uint16_t idx = load_in_particle_emitter(system, in_emitter); if (idx == 0) return; - ParticleEmitter_t* emitter = system->emitters + idx; - // Generate particles based on type - // Burst type need to generate all at once - // TODO: stream type need to generate one at a time - if (emitter->config->type == EMITTER_BURST) - { - for (uint32_t i = 0; i < emitter->n_particles; ++i) - { - spawn_particle(emitter, i); - } - } play_emitter_handle(system, idx); } @@ -134,29 +151,32 @@ void update_particle_system(ParticleSystem_t* system) if (emitter->particles[i].timer == 0) { emitter->particles[i].alive = false; + } + } + + if (!emitter->particles[i].alive) + { + if (emitter->config->one_shot || !emitter->active) + { inactive_count++; } - // TODO: If streaming and not one shot, immediately revive the particle - } - else - { - inactive_count++; + else + { + // If not one shot, immediately revive the particle + spawn_particle(emitter, i); + } } } if (inactive_count == emitter->n_particles) { - // TODO: If burst and not one shot, revive all particles - emitter->active = false; - } - - if (!emitter->active) - { + // Stop playing only if all particles is inactive if (!emitter->finished && emitter->config->one_shot) { emitter->finished = true; } system->emitter_list[prev_idx].next = system->emitter_list[emitter_idx].next; system->emitter_list[emitter_idx].next = 0; + system->emitter_list[emitter_idx].playing = false; if (system->tail_idx == emitter_idx) { system->tail_idx = prev_idx; diff --git a/engine/particle_sys.h b/engine/particle_sys.h index 3d458c5..eccf8b5 100644 --- a/engine/particle_sys.h +++ b/engine/particle_sys.h @@ -11,8 +11,9 @@ typedef uint16_t EmitterHandle; typedef enum PartEmitterType { - EMITTER_BURST = 0, - EMITTER_UNKNOWN, + EMITTER_UNKNOWN = 0, + EMITTER_BURST, + EMITTER_STREAM, } PartEmitterType_t; typedef struct Particle @@ -56,6 +57,7 @@ typedef struct ParticleEmitter typedef struct IndexList { uint32_t next; + bool playing; }IndexList_t; typedef struct ParticleSystem @@ -77,6 +79,7 @@ void play_particle_emitter(ParticleSystem_t* system, const ParticleEmitter_t* in EmitterHandle load_in_particle_emitter(ParticleSystem_t* system, const ParticleEmitter_t* in_emitter); void play_emitter_handle(ParticleSystem_t* system, EmitterHandle handle); void pause_emitter_handle(ParticleSystem_t* system, EmitterHandle handle); +void update_emitter_handle_position(ParticleSystem_t* system, EmitterHandle handle, Vector2 pos); void unload_emitter_handle(ParticleSystem_t* system, EmitterHandle handle); void update_particle_system(ParticleSystem_t* system); diff --git a/particle_test.c b/particle_test.c index 8e68fe4..dd7907f 100644 --- a/particle_test.c +++ b/particle_test.c @@ -69,6 +69,7 @@ int main(void) .launch_range = {0, 360}, .speed_range = {400, 2000}, .particle_lifetime = {30, 110}, + .type = EMITTER_BURST, }; ParticleEmitter_t emitter = { @@ -78,20 +79,59 @@ int main(void) .spr = (tex.width == 0) ? NULL : &spr, }; + EmitterConfig_t conf2 ={ + .one_shot = false, + .launch_range = {0, 360}, + .speed_range = {300, 800}, + .particle_lifetime = {15, 30}, + .type = EMITTER_BURST, + }; + + ParticleEmitter_t emitter2 = { + .config = &conf2, + .n_particles = MAX_PARTICLES, + .update_func = &simple_particle_system_update, + .spr = (tex.width == 0) ? NULL : &spr, + }; + + EmitterHandle han = load_in_particle_emitter(&part_sys, &emitter2); + assert(han != 0); + bool key_press = false; + uint8_t key2_press = 0; char text_buffer[32]; while(!WindowShouldClose()) { + Vector2 mouse_pos = GetMousePosition(); if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) { key_press = true; } else if (key_press && IsMouseButtonReleased(MOUSE_BUTTON_LEFT)) { - emitter.position = GetMousePosition(); + emitter.position = mouse_pos; play_particle_emitter(&part_sys, &emitter); key_press = false; } + + key2_press <<= 1; + key2_press |= IsMouseButtonDown(MOUSE_RIGHT_BUTTON)? 1: 0; + key2_press &= 0b11; + + if (key2_press == 0b01) + { + update_emitter_handle_position(&part_sys, han, mouse_pos); + play_emitter_handle(&part_sys, han); + } + else if(key2_press == 0b11) + { + update_emitter_handle_position(&part_sys, han, mouse_pos); + } + else if (key2_press == 0b10) + { + pause_emitter_handle(&part_sys, han); + } + update_particle_system(&part_sys); sprintf(text_buffer, "free: %u", get_number_of_free_emitter(&part_sys)); BeginDrawing();