diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/crepe/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/crepe/ParticleEmitter.cpp | 70 | ||||
| -rw-r--r-- | src/crepe/ParticleEmitter.hpp | 32 | ||||
| -rw-r--r-- | src/crepe/SDLApp.cpp | 69 | ||||
| -rw-r--r-- | src/crepe/SDLApp.hpp | 25 | ||||
| -rw-r--r-- | src/crepe/main.cpp | 82 | 
6 files changed, 188 insertions, 91 deletions
| diff --git a/src/crepe/CMakeLists.txt b/src/crepe/CMakeLists.txt index c825529..933f907 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 +	SDLApp.cpp  )  target_include_directories(main PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/src/crepe/ParticleEmitter.cpp b/src/crepe/ParticleEmitter.cpp index 13aaeae..f575e38 100644 --- a/src/crepe/ParticleEmitter.cpp +++ b/src/crepe/ParticleEmitter.cpp @@ -1,40 +1,70 @@  #include "ParticleEmitter.hpp" +#include <cmath> +#include <cstdlib> +#include <ctime> +#include <iostream>  // include iostream for std::cout -ParticleEmitter::ParticleEmitter(int maxParticles, float emissionRate) -    : maxParticles(maxParticles), emissionRate(emissionRate), elapsedTime(0.0f) { -    position = { 0, 0 };   -    std::srand(static_cast<unsigned int>(std::time(nullptr))); / +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} { +    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) { -    elapsedTime += deltaTime; +void ParticleEmitter::update(float deltaTime) { // keep deltaTime as float +    m_elapsedTime += deltaTime; -    while (elapsedTime >= (1.0f / emissionRate) && particles.size() < maxParticles) { -        elapsedTime -= (1.0f / emissionRate); +    while (m_elapsedTime >= (1.0f / m_emissionRate) && particles.size() < m_maxParticles) { +        m_elapsedTime -= (1.0f / m_emissionRate);          emitParticle();      } -    for (auto it = particles.begin(); it != particles.end();) { -        it->update(deltaTime); +    std::vector<Particle>::iterator it = particles.begin(); +    while (it != particles.end()) { +        it->update(deltaTime); // update particle          if (!it->isAlive()) { -            it = particles.erase(it);  +            it = particles.erase(it); // remove dead particle          } else { -            ++it; +            ++it; // move to next particle          }      }  }  void ParticleEmitter::emitParticle() { -    Particle::Position initialPosition = { position.x, position.y }; +    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>(randFloat(-50.0f, 50.0f, 10.0f, 100.0f)),  -        static_cast<int>(randFloat(-50.0f, 50.0f, 10.0f, 100.0f)) +        static_cast<int>(velocityX), // set x velocity +        static_cast<int>(velocityY)  // set y velocity      }; -    particles.emplace_back(2.0f, initialPosition, initialVelocity);  + +    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  } -float ParticleEmitter::randFloat(float minangle, float maxangle, float minVel, float maxVel) { -    float angle = static_cast<float>(rand()) / RAND_MAX * (maxangle - minangle) + minangle; -    float velocity = static_cast<float>(rand()) / RAND_MAX * (maxVel - minVel) + minVel; -    return velocity * std::cos(angle);  +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  } diff --git a/src/crepe/ParticleEmitter.hpp b/src/crepe/ParticleEmitter.hpp index 682a2ae..9b3f2ad 100644 --- a/src/crepe/ParticleEmitter.hpp +++ b/src/crepe/ParticleEmitter.hpp @@ -1,28 +1,30 @@  #pragma once  #include <vector> -#include <cstdlib>   -#include <ctime>     #include "Particle.hpp" -#include <cmath>  class ParticleEmitter {  public: -    std::vector<Particle> particles; +    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 Position { //struct to hold position          int x;          int y; -    } position; - -    int maxParticles; -    float emissionRate; -    float elapsedTime; +    }; -    ParticleEmitter(int maxParticles, float emissionRate); -    void update(float deltaTime); +    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 +    unsigned int m_maxAngle; //max angle of particle emission -private: -    void emitParticle(); -    float randFloat(float minangle, float maxangle, float minVel, float maxVel); +    std::vector<Particle> particles; //collection of particles  }; diff --git a/src/crepe/SDLApp.cpp b/src/crepe/SDLApp.cpp new file mode 100644 index 0000000..a5e3621 --- /dev/null +++ b/src/crepe/SDLApp.cpp @@ -0,0 +1,69 @@ +#include "SDLApp.hpp" +#include <iostream> + +SDLApp::SDLApp(int windowWidth, int windowHeight) +    : windowWidth(windowWidth), windowHeight(windowHeight), window(nullptr), renderer(nullptr) {} + +SDLApp::~SDLApp() { +    cleanUp(); +} + +bool SDLApp::initialize() { +    if (SDL_Init(SDL_INIT_VIDEO) != 0) { +        std::cerr << "SDL Initialization Error: " << SDL_GetError() << std::endl; +        return false; +    } + +    window = SDL_CreateWindow("Particle System", +                              SDL_WINDOWPOS_CENTERED, +                              SDL_WINDOWPOS_CENTERED, +                              windowWidth, +                              windowHeight, +                              SDL_WINDOW_SHOWN); +    if (!window) { +        std::cerr << "Window Creation Error: " << SDL_GetError() << std::endl; +        return false; +    } + +    renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); +    if (!renderer) { +        std::cerr << "Renderer Creation Error: " << SDL_GetError() << std::endl; +        return false; +    } + +    return true; +} + +void SDLApp::handleEvents(bool& running) { +    SDL_Event event; +    while (SDL_PollEvent(&event)) { +        if (event.type == SDL_QUIT) { +            running = false; +        } +    } +} + +void SDLApp::clearScreen() { +    SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);  +    SDL_RenderClear(renderer); +} + +void SDLApp::presentScreen() { +    SDL_RenderPresent(renderer); +} + +void SDLApp::drawSquare(int x, int y, int size) { +    SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);  +    SDL_Rect rect = { x, y, size, size }; +    SDL_RenderFillRect(renderer, &rect); +} + +void SDLApp::cleanUp() { +    if (renderer) { +        SDL_DestroyRenderer(renderer); +    } +    if (window) { +        SDL_DestroyWindow(window); +    } +    SDL_Quit(); +} diff --git a/src/crepe/SDLApp.hpp b/src/crepe/SDLApp.hpp new file mode 100644 index 0000000..92a4e27 --- /dev/null +++ b/src/crepe/SDLApp.hpp @@ -0,0 +1,25 @@ +#ifndef SDLAPP_HPP +#define SDLAPP_HPP + +#include <SDL2/SDL.h> + +class SDLApp { +public: +    SDLApp(int windowWidth, int windowHeight); +    ~SDLApp(); + +    bool initialize(); +    void handleEvents(bool& running); +    void clearScreen(); +    void presentScreen(); +    void drawSquare(int x, int y, int size); +    void cleanUp(); + +private: +    int windowWidth; +    int windowHeight; +    SDL_Window* window; +    SDL_Renderer* renderer; +}; + +#endif diff --git a/src/crepe/main.cpp b/src/crepe/main.cpp index 73d041c..fc307cc 100644 --- a/src/crepe/main.cpp +++ b/src/crepe/main.cpp @@ -1,83 +1,53 @@  #include <iostream>  #include <thread>  #include <chrono> -#include <SDL.h> +#include "SDLApp.hpp"  #include "ParticleEmitter.hpp"  const int WINDOW_WIDTH = 800;  const int WINDOW_HEIGHT = 600; -void renderParticles(SDL_Renderer* renderer, const ParticleEmitter& emitter) { -    for (const auto& particle : emitter.particles) { -        SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);  -        SDL_Rect rect = { particle.position.x, particle.position.y, 5, 5 };  -        SDL_RenderFillRect(renderer, &rect); -    } -} -  int main(int argc, char* argv[]) { -   -    if (SDL_Init(SDL_INIT_VIDEO) != 0) { -        std::cerr << "SDL Initialization Error: " << SDL_GetError() << std::endl; -        return 1; -    } +    SDLApp app(WINDOW_WIDTH, WINDOW_HEIGHT); -    SDL_Window* window = SDL_CreateWindow("Particle System", -                                          SDL_WINDOWPOS_CENTERED, -                                          SDL_WINDOWPOS_CENTERED, -                                          WINDOW_WIDTH, -                                          WINDOW_HEIGHT, -                                          SDL_WINDOW_SHOWN); -    if (!window) { -        std::cerr << "Window Creation Error: " << SDL_GetError() << std::endl; -        SDL_Quit(); +    if (!app.initialize()) { +        std::cerr << "Failed to initialize SDLApp." << std::endl;          return 1;      } -    // Create SDL renderer -    SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); -    if (!renderer) { -        std::cerr << "Renderer Creation Error: " << SDL_GetError() << std::endl; -        SDL_DestroyWindow(window); -        SDL_Quit(); -        return 1; -    } -    ParticleEmitter emitter(100, 10.0f); -    emitter.position = { 400, 300 }; -    ParticleEmitter emitter2(100, 10.0f); -    emitter2.position = { 600, 600 };  +    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 -    float deltaTime = 0.1f; -    bool running = true; -    SDL_Event event; -    while (running) { +    ParticleEmitter emitter(maxParticles, emissionRate, speed, speedOffset, angle, angleOffset); -        while (SDL_PollEvent(&event)) { -            if (event.type == SDL_QUIT) { -                running = false; -            } -        } +    emitter.setPosition(400, 300); + +    float deltaTime = 0.1f; +    bool running = true; +    while (running) { +        app.handleEvents(running);          emitter.update(deltaTime); -        emitter2.update(deltaTime); -        SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);  -        SDL_RenderClear(renderer); +        app.clearScreen(); -        renderParticles(renderer, emitter); -        renderParticles(renderer, emitter2); +        //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); +        } -        SDL_RenderPresent(renderer); +        app.presentScreen(); -         +        std::this_thread::sleep_for(std::chrono::milliseconds(17));      } -   -    SDL_DestroyRenderer(renderer); -    SDL_DestroyWindow(window); -    SDL_Quit(); - +    app.cleanUp();      return 0;  } |