aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/crepe/CMakeLists.txt1
-rw-r--r--src/crepe/ParticleEmitter.cpp70
-rw-r--r--src/crepe/ParticleEmitter.hpp32
-rw-r--r--src/crepe/SDLApp.cpp69
-rw-r--r--src/crepe/SDLApp.hpp25
-rw-r--r--src/crepe/main.cpp82
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;
}