From 096e0d0a7199ec9a4059fd5ef8a06a3cf8fcae83 Mon Sep 17 00:00:00 2001 From: jaroWMR Date: Mon, 7 Oct 2024 16:02:09 +0200 Subject: created a particel system --- src/crepe/CMakeLists.txt | 1 + src/crepe/Particle.cpp | 5 ++-- src/crepe/Particle.hpp | 5 ++-- src/crepe/ParticleEmitter.cpp | 63 ++----------------------------------------- src/crepe/ParticleEmitter.hpp | 11 ++------ src/crepe/ParticleSystem.cpp | 62 ++++++++++++++++++++++++++++++++++++++++++ src/crepe/ParticleSystem.hpp | 14 ++++++++++ src/crepe/main.cpp | 37 +++++++++++++++---------- 8 files changed, 109 insertions(+), 89 deletions(-) create mode 100644 src/crepe/ParticleSystem.cpp create mode 100644 src/crepe/ParticleSystem.hpp (limited to 'src/crepe') diff --git a/src/crepe/CMakeLists.txt b/src/crepe/CMakeLists.txt index 933f907..43a3835 100644 --- a/src/crepe/CMakeLists.txt +++ b/src/crepe/CMakeLists.txt @@ -2,6 +2,7 @@ target_sources(main PUBLIC main.cpp Particle.cpp ParticleEmitter.cpp + ParticleSystem.cpp SDLApp.cpp ) diff --git a/src/crepe/Particle.cpp b/src/crepe/Particle.cpp index 90957db..f6bbd34 100644 --- a/src/crepe/Particle.cpp +++ b/src/crepe/Particle.cpp @@ -1,12 +1,13 @@ #include "Particle.hpp" + Particle::Particle(float lifespan, Position position, Position velocity) : lifespan(lifespan), position(position), velocity(velocity), timeInLife(0.0f) {} void Particle::update(float deltaTime) { timeInLife += deltaTime; - position.x += static_cast(velocity.x * deltaTime); - position.y += static_cast(velocity.y * deltaTime); + position.x += velocity.x * deltaTime; + position.y += velocity.y * deltaTime; } bool Particle::isAlive() const { diff --git a/src/crepe/Particle.hpp b/src/crepe/Particle.hpp index f8d2770..f71fd67 100644 --- a/src/crepe/Particle.hpp +++ b/src/crepe/Particle.hpp @@ -3,8 +3,8 @@ class Particle { public: struct Position { - int x; - int y; + float x; + float y; }; Position position; @@ -14,6 +14,5 @@ public: Particle(float lifespan, Position position, Position velocity); void update(float deltaTime); bool isAlive() const; -private: float timeInLife; }; diff --git a/src/crepe/ParticleEmitter.cpp b/src/crepe/ParticleEmitter.cpp index f575e38..69f5ace 100644 --- a/src/crepe/ParticleEmitter.cpp +++ b/src/crepe/ParticleEmitter.cpp @@ -1,70 +1,11 @@ #include "ParticleEmitter.hpp" -#include -#include #include -#include // include iostream for std::cout ParticleEmitter::ParticleEmitter(unsigned int maxParticles, unsigned int emissionRate, unsigned int speed, unsigned int speedOffset, unsigned int angle, unsigned int angleOffset) - : m_maxParticles(maxParticles), m_emissionRate(emissionRate), m_elapsedTime(0.0f), m_speed(speed), m_speedOffset(speedOffset), m_position{0, 0} { + : m_maxParticles(maxParticles), m_emissionRate(emissionRate), m_speed(speed), m_speedOffset(speedOffset), m_position{0, 0} { std::srand(static_cast(std::time(nullptr))); // initialize random seed m_minAngle = (360 + angle - (angleOffset % 360)) % 360; // calculate minAngle m_maxAngle = (360 + angle + (angleOffset % 360)) % 360; // calculate maxAngle - std::cout << "Initialized ParticleEmitter with:" << std::endl; - std::cout << "Min Angle: " << m_minAngle << " Max Angle: " << m_maxAngle << std::endl; -} - -void ParticleEmitter::update(float deltaTime) { // keep deltaTime as float - m_elapsedTime += deltaTime; - - while (m_elapsedTime >= (1.0f / m_emissionRate) && particles.size() < m_maxParticles) { - m_elapsedTime -= (1.0f / m_emissionRate); - emitParticle(); - } - - std::vector::iterator it = particles.begin(); - while (it != particles.end()) { - it->update(deltaTime); // update particle - if (!it->isAlive()) { - it = particles.erase(it); // remove dead particle - } else { - ++it; // move to next particle - } - } -} - -void ParticleEmitter::emitParticle() { - Particle::Position initialPosition = { m_position.x, m_position.y }; // starting position of the particle - - // generate a random angle within the range [minAngle, maxAngle] - float randomAngle = m_minAngle + (std::rand() % (static_cast(m_maxAngle - m_minAngle + 1))); // random angle within the specified range - - // convert angle to radians for velocity calculation - float angleInRadians = randomAngle * (M_PI / 180.0f); - - // calculate velocity components based on the final angle - float randomSpeedOffset = (static_cast(std::rand()) / RAND_MAX) * (2 * m_speedOffset) - m_speedOffset; // random speed offset - float velocityX = (m_speed + randomSpeedOffset) * std::cos(angleInRadians); // x component of velocity - float velocityY = (m_speed + randomSpeedOffset) * std::sin(angleInRadians); // y component of velocity - - Particle::Position initialVelocity = { - static_cast(velocityX), // set x velocity - static_cast(velocityY) // set y velocity - }; - - std::cout << "Emitting particle with:" << std::endl; - std::cout << "Random Angle: " << randomAngle << " (Radians: " << angleInRadians << ")" << std::endl; - std::cout << "Velocity X: " << velocityX << " Velocity Y: " << velocityY << std::endl; - - particles.emplace_back(2.0f, initialPosition, initialVelocity); // create and store the new particle -} - -const std::vector& ParticleEmitter::getParticles() const { - return particles; // return the collection of particles -} - -void ParticleEmitter::setPosition(int x, int y) { - m_position.x = x; // set x position of the emitter - m_position.y = y; // set y position of the emitter -} +} \ No newline at end of file diff --git a/src/crepe/ParticleEmitter.hpp b/src/crepe/ParticleEmitter.hpp index 9b3f2ad..6826531 100644 --- a/src/crepe/ParticleEmitter.hpp +++ b/src/crepe/ParticleEmitter.hpp @@ -6,21 +6,14 @@ class ParticleEmitter { public: ParticleEmitter(unsigned int maxParticles, unsigned int emissionRate, unsigned int speed, unsigned int speedOffset, unsigned int angle, unsigned int angleOffset); - void update(float deltaTime); // Keep deltaTime as float - const std::vector& getParticles() const; //returns the collection of particles - void setPosition(int x, int y); //sets the position of the emitter -private: - void emitParticle(); //emits a new particle - struct Position { //struct to hold position - int x; - int y; + float x; + float y; }; Position m_position; //position of the emitter unsigned int m_maxParticles; //maximum number of particles unsigned int m_emissionRate; //rate of particle emission - float m_elapsedTime; //elapsed time since the last emission unsigned int m_speed; //base speed of the particles unsigned int m_speedOffset; //offset for random speed variation unsigned int m_minAngle; //min angle of particle emission diff --git a/src/crepe/ParticleSystem.cpp b/src/crepe/ParticleSystem.cpp new file mode 100644 index 0000000..367f56c --- /dev/null +++ b/src/crepe/ParticleSystem.cpp @@ -0,0 +1,62 @@ +#include "ParticleSystem.hpp" +#include +// #include +#include +#include // include iostream for std::cout +#include "ParticleEmitter.hpp" +#include "Particle.hpp" + +ParticleSystem::ParticleSystem() : m_elapsedTime(0.0f) {} // Initialize m_elapsedTime to 0 + +void ParticleSystem::update(float deltaTime, std::vector& emitters) { + for (ParticleEmitter& emitter : emitters) { + m_elapsedTime = deltaTime; + + //spawn new particles if enough time passed and the max is not achieved + while (m_elapsedTime >= (1.0f / emitter.m_emissionRate) && emitter.particles.size() < emitter.m_maxParticles) { + m_elapsedTime -= (1.0f / emitter.m_emissionRate); + emitParticle(emitter); + } + //update/move particles afterwards delete if not alive. + std::vector::iterator it = emitter.particles.begin(); + while (it != emitter.particles.end()) { + it->update(deltaTime); + if (!it->isAlive()) { + it = emitter.particles.erase(it); + } else { + ++it; + } + } + + } +} + +void ParticleSystem::emitParticle(ParticleEmitter& emitter) { + std::cout << "new emitter:" << std::endl; + Particle::Position initialPosition = { emitter.m_position.x, emitter.m_position.y }; + float randomAngle = 0.0f; + //check if value is overthe 360 degrees + if(emitter.m_maxAngle < emitter.m_minAngle) + { + randomAngle = ((emitter.m_minAngle + (std::rand() % (static_cast(emitter.m_maxAngle + 360 - emitter.m_minAngle + 1))))%360); + } + else + { + randomAngle = emitter.m_minAngle + (std::rand() % (static_cast(emitter.m_maxAngle - emitter.m_minAngle + 1))); + } + + std::cout << "randomAngle:" << randomAngle << std::endl; + float angleInRadians = randomAngle * (M_PI / 180.0f); + float randomSpeedOffset = (static_cast(std::rand()) / RAND_MAX) * (2 * emitter.m_speedOffset) - emitter.m_speedOffset; + float velocityX = (emitter.m_speed + randomSpeedOffset) * std::cos(angleInRadians); + float velocityY = (emitter.m_speed + randomSpeedOffset) * std::sin(angleInRadians); + std::cout << "velocityX:" << velocityX << std::endl; + std::cout << "velocityY:" << velocityY << std::endl; + Particle::Position initialVelocity = { + velocityX, + velocityY + }; + std::cout << "initialVelocityX:" << initialVelocity.x << std::endl; + std::cout << "initialVelocityY:" << initialVelocity.y << std::endl; + emitter.particles.emplace_back(2.0f, initialPosition, initialVelocity); +} diff --git a/src/crepe/ParticleSystem.hpp b/src/crepe/ParticleSystem.hpp new file mode 100644 index 0000000..f670415 --- /dev/null +++ b/src/crepe/ParticleSystem.hpp @@ -0,0 +1,14 @@ +#pragma once + +#include +#include "ParticleEmitter.hpp" + +class ParticleSystem { +public: + ParticleSystem(); + void update(float deltaTime, std::vector& emitters); +private: + void emitParticle(ParticleEmitter &emitter); //emits a new particle + + float m_elapsedTime; //elapsed time since the last emission +}; diff --git a/src/crepe/main.cpp b/src/crepe/main.cpp index fc307cc..40eb04f 100644 --- a/src/crepe/main.cpp +++ b/src/crepe/main.cpp @@ -3,6 +3,8 @@ #include #include "SDLApp.hpp" #include "ParticleEmitter.hpp" +#include "ParticleSystem.hpp" +#include "Particle.hpp" const int WINDOW_WIDTH = 800; const int WINDOW_HEIGHT = 600; @@ -15,37 +17,44 @@ int main(int argc, char* argv[]) { return 1; } + ParticleSystem particleSystem; - unsigned int maxParticles = 100; //maximum number of particles - unsigned int emissionRate = 10; //particles created per second - unsigned int speed = 50; //base speed of particles - unsigned int speedOffset = 10; //random offset for particle speed - unsigned int angle = 180; //base angle of particle emission - unsigned int angleOffset = 30; //random offset for particle angle + unsigned int maxParticles = 100; // maximum number of particles + unsigned int emissionRate = 10; // particles created per second + unsigned int speed = 50; // base speed of particles + unsigned int speedOffset = 10; // random offset for particle speed + unsigned int angle = 90; // base angle of particle emission + unsigned int angleOffset = 30; // random offset for particle angle + ParticleEmitter emitter1(maxParticles, emissionRate, speed, speedOffset, angle, angleOffset); + emitter1.m_position = {200, 200}; // set the position of the first emitter - ParticleEmitter emitter(maxParticles, emissionRate, speed, speedOffset, angle, angleOffset); + ParticleEmitter emitter2(maxParticles, emissionRate, speed, speedOffset, angle - 90, angleOffset); // Another emitter + emitter2.m_position = {200, 150}; // set the position of the second emitter - emitter.setPosition(400, 300); + std::vector emitters = { emitter2 }; // array of emitters float deltaTime = 0.1f; bool running = true; while (running) { app.handleEvents(running); - emitter.update(deltaTime); + + particleSystem.update(deltaTime, emitters); // update particle system with delta time and emitters app.clearScreen(); - //render particles using the drawSquare method - const std::vector& particles = emitter.getParticles(); - for (std::size_t i = 0; i < particles.size(); ++i) { - app.drawSquare(particles[i].position.x, particles[i].position.y, 5); + // render particles using the drawSquare method from SDLApp + for (const ParticleEmitter& emitter : emitters) { + for (const Particle& particle : emitter.particles) { + + app.drawSquare(particle.position.x, particle.position.y, 5); // draw each particle + } } app.presentScreen(); - std::this_thread::sleep_for(std::chrono::milliseconds(17)); + std::this_thread::sleep_for(std::chrono::milliseconds(20)); // simulate ~50 FPS } app.cleanUp(); -- cgit v1.2.3