diff --git a/src/framework/graphics/particlessystem.cpp b/src/framework/graphics/particlessystem.cpp index 5339a70c..5b852065 100644 --- a/src/framework/graphics/particlessystem.cpp +++ b/src/framework/graphics/particlessystem.cpp @@ -5,13 +5,20 @@ Particle::Particle(const Rect& rect, float vx, float vy, float ax, float ay, const Color& color, TexturePtr texture) { m_rect = rect; + m_ix = rect.x(); m_iy = rect.y(); m_vx = vx; m_vy = vy; m_ax = ax; m_ay = ay; m_color = color; m_texture = texture; + m_startTicks = g_clock.ticks(); m_finished = false; } +Particle::~Particle() +{ + //dump << "deleted"; +} + void Particle::render() { g_graphics.bindColor(m_color); @@ -22,6 +29,14 @@ void Particle::render() g_graphics.drawTexturedRect(m_rect, m_texture); } +void Particle::update() +{ + ticks_t t = g_clock.ticks() - m_startTicks; + + m_rect.moveTo(m_ix + (m_vx * t / 1000.0) + (m_ax * t*t / 2000.0), + m_iy + (m_vy * t / 1000.0) + (m_ay * t*t / 2000.0)); +} + Emitter::Emitter(const Point& position, int duration, int particlesPerSecond) { m_position = position; @@ -43,15 +58,28 @@ void Emitter::update() ticks_t elapsedTicks = g_clock.ticks() - m_startTicks; // check if finished - if(m_duration > 0 && elapsedTicks > m_duration * 1000) + if(m_duration > 0 && elapsedTicks > m_duration * 1000) { m_finished = true; + return; + } + + // update particles + for(auto it = m_particles.begin(), end = m_particles.end(); it != end;) { + if((*it).hasFinished()) { + it = m_particles.erase(it); + continue; + } + (*it).update(); + ++it; + } // create some particles int currentParticles = elapsedTicks / 1000.0 * m_particlesPerSecond; for(int i = m_createdParticles; i < currentParticles; ++i) { - Particle particle = Particle(Rect(100, 100, 16, 16), 0, 0, 0, 0); - m_particles.push_back(particle); + // todo: add random data generation + m_particles.push_back(Particle(Rect(100, 100, 16, 16), 16, 8, 0, 0)); } + m_createdParticles = currentParticles; } void ParticlesSystem::add(Emitter emitter) @@ -68,8 +96,12 @@ void ParticlesSystem::render() void ParticlesSystem::update() { for(auto it = m_emitters.begin(), end = m_emitters.end(); it != end;) { - Emitter emitter = *it; - emitter.update(); + if((*it).hasFinished()) { + it = m_emitters.erase(it); + continue; + } + + (*it).update(); ++it; } } diff --git a/src/framework/graphics/particlessystem.h b/src/framework/graphics/particlessystem.h index 6eed56e5..67bc88e2 100644 --- a/src/framework/graphics/particlessystem.h +++ b/src/framework/graphics/particlessystem.h @@ -5,15 +5,24 @@ struct Particle { public: Particle(const Rect& rect, float vx, float vy, float ax, float ay, const Color& color = Color(255, 255, 255), TexturePtr texture = nullptr); + ~Particle(); + void render(); + void update(); + + bool hasFinished() { return m_finished; } private: Rect m_rect; + + int m_ix, m_iy; float m_vx, m_vy; float m_ax, m_ay; Color m_color; TexturePtr m_texture; + + ticks_t m_startTicks; bool m_finished; }; @@ -25,6 +34,8 @@ public: void render(); void update(); + bool hasFinished() { return m_finished; } + private: // self related Point m_position; diff --git a/src/otclient/net/protocolgameparse.cpp b/src/otclient/net/protocolgameparse.cpp index 1985c73c..4ed5c4d5 100644 --- a/src/otclient/net/protocolgameparse.cpp +++ b/src/otclient/net/protocolgameparse.cpp @@ -532,7 +532,7 @@ void ProtocolGame::parseMagicEffect(InputMessage& msg) // test particles ParticlesSystem particlesSystem; - Emitter emitter = Emitter(Point(100, 100), 30, 30); + Emitter emitter = Emitter(Point(100, 100), 5, 1); particlesSystem.add(emitter); g_particlesManager.add(particlesSystem);