#include <cmath> #include <ctime> #include "../api/ParticleEmitter.h" #include "../ComponentManager.h" #include "ParticleSystem.h" using namespace crepe; ParticleSystem::ParticleSystem() : elapsed_time(0.0f) {} void ParticleSystem::update() { ComponentManager & mgr = ComponentManager::get_instance(); std::vector<std::reference_wrapper<ParticleEmitter>> emitters = mgr.get_components_by_type<ParticleEmitter>(); float delta_time = 0.10; for (ParticleEmitter & emitter : emitters) { float update_amount = 1 / static_cast<float>(emitter.emission_rate); for (float i = 0; i < delta_time; i += update_amount) { emit_particle(emitter); } for (size_t j = 0; j < emitter.particles.size(); j++) { if (emitter.particles[j].active) { emitter.particles[j].update(delta_time); } } } } void ParticleSystem::emit_particle(ParticleEmitter & emitter) { Position initial_position = {emitter.position.x, emitter.position.y}; float random_angle = 0.0f; if (emitter.max_angle < emitter.min_angle) { random_angle = ((emitter.min_angle + (std::rand() % (static_cast<uint32_t>(emitter.max_angle + 360 - emitter.min_angle + 1)))) % 360); } else { random_angle = emitter.min_angle + (std::rand() % (static_cast<uint32_t>(emitter.max_angle - emitter.min_angle + 1))); } float angle_in_radians = random_angle * (M_PI / 180.0f); float random_speed_offset = (static_cast<float>(std::rand()) / RAND_MAX) * (2 * emitter.speed_offset) - emitter.speed_offset; float velocity_x = (emitter.speed + random_speed_offset) * std::cos(angle_in_radians); float velocity_y = (emitter.speed + random_speed_offset) * std::sin(angle_in_radians); Position initial_velocity = {velocity_x, velocity_y}; for (size_t i = 0; i < emitter.particles.size(); i++) { if (!emitter.particles[i].active) { emitter.particles[i].reset(emitter.end_lifespan, initial_position, initial_velocity); break; } } }