diff options
| author | jaroWMR <jarorutjes07@gmail.com> | 2024-10-07 16:02:09 +0200 | 
|---|---|---|
| committer | jaroWMR <jarorutjes07@gmail.com> | 2024-10-07 16:02:09 +0200 | 
| commit | 096e0d0a7199ec9a4059fd5ef8a06a3cf8fcae83 (patch) | |
| tree | e88e612ac8836ad14abf6b6daff5f2508f0456b2 /src | |
| parent | 094ce1806156e191ffb554d4e88e636421cb0242 (diff) | |
created a particel system
Diffstat (limited to 'src')
| -rw-r--r-- | src/crepe/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/crepe/Particle.cpp | 5 | ||||
| -rw-r--r-- | src/crepe/Particle.hpp | 5 | ||||
| -rw-r--r-- | src/crepe/ParticleEmitter.cpp | 63 | ||||
| -rw-r--r-- | src/crepe/ParticleEmitter.hpp | 11 | ||||
| -rw-r--r-- | src/crepe/ParticleSystem.cpp | 62 | ||||
| -rw-r--r-- | src/crepe/ParticleSystem.hpp | 14 | ||||
| -rw-r--r-- | src/crepe/main.cpp | 37 | 
8 files changed, 109 insertions, 89 deletions
| 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<int>(velocity.x * deltaTime); -    position.y += static_cast<int>(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 <cmath> -#include <cstdlib>  #include <ctime> -#include <iostream>  // 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<unsigned int>(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<Particle>::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<int>(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<float>(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<int>(velocityX), // set x velocity -        static_cast<int>(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<Particle>& 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<Particle>& 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 <cmath> +// #include <cstdlib> +#include <ctime> +#include <iostream>  // 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<ParticleEmitter>& 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<Particle>::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<int>(emitter.m_maxAngle + 360 - emitter.m_minAngle + 1))))%360); +    } +    else +    { +        randomAngle = emitter.m_minAngle + (std::rand() % (static_cast<int>(emitter.m_maxAngle - emitter.m_minAngle + 1))); +    } +     +    std::cout << "randomAngle:" << randomAngle << std::endl; +    float angleInRadians = randomAngle * (M_PI / 180.0f); +    float randomSpeedOffset = (static_cast<float>(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 <vector> +#include "ParticleEmitter.hpp" + +class ParticleSystem { +public: +    ParticleSystem(); +    void update(float deltaTime, std::vector<ParticleEmitter>& 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 <chrono>  #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<ParticleEmitter> 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<Particle>& 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(); |