diff --git a/src/framework/CMakeLists.txt b/src/framework/CMakeLists.txt index 659fc10a..bb87210c 100644 --- a/src/framework/CMakeLists.txt +++ b/src/framework/CMakeLists.txt @@ -142,6 +142,8 @@ SET(framework_SOURCES ${framework_SOURCES} ${CMAKE_CURRENT_LIST_DIR}/graphics/texturemanager.cpp ${CMAKE_CURRENT_LIST_DIR}/graphics/borderimage.cpp ${CMAKE_CURRENT_LIST_DIR}/graphics/image.cpp + ${CMAKE_CURRENT_LIST_DIR}/graphics/particlesmanager.cpp + ${CMAKE_CURRENT_LIST_DIR}/graphics/particlessystem.cpp # framework otml ${CMAKE_CURRENT_LIST_DIR}/otml/otmldocument.cpp diff --git a/src/framework/application.cpp b/src/framework/application.cpp index 25542cc3..c2ff5caa 100644 --- a/src/framework/application.cpp +++ b/src/framework/application.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include Application *g_app = nullptr; @@ -207,12 +208,16 @@ void Application::poll() // poll application genareted events g_dispatcher.poll(); + + g_particlesManager.update(); } void Application::render() { // everything is rendered by UI components g_ui.render(); + + g_particlesManager.render(); } void Application::resize(const Size& size) diff --git a/src/framework/graphics/particlesmanager.cpp b/src/framework/graphics/particlesmanager.cpp new file mode 100644 index 00000000..f96faa53 --- /dev/null +++ b/src/framework/graphics/particlesmanager.cpp @@ -0,0 +1,21 @@ +#include "particlesmanager.h" + +ParticlesManager g_particlesManager; + +void ParticlesManager::add(ParticlesSystem particleSystem) +{ + // check it has emitters + m_particlesSystems.push_back(particleSystem); +} + +void ParticlesManager::render() +{ + for(auto it = m_particlesSystems.begin(), end = m_particlesSystems.end(); it != end; ++it) + (*it).render(); +} + +void ParticlesManager::update() +{ + for(auto it = m_particlesSystems.begin(), end = m_particlesSystems.end(); it != end; ++it) + (*it).update(); +} diff --git a/src/framework/graphics/particlesmanager.h b/src/framework/graphics/particlesmanager.h new file mode 100644 index 00000000..cb6f8f0a --- /dev/null +++ b/src/framework/graphics/particlesmanager.h @@ -0,0 +1,14 @@ +#include "particlessystem.h" + +class ParticlesManager { +public: + void add(ParticlesSystem particleSystem); + + void render(); + void update(); + +private: + std::list m_particlesSystems; +}; + +extern ParticlesManager g_particlesManager; diff --git a/src/framework/graphics/particlessystem.cpp b/src/framework/graphics/particlessystem.cpp new file mode 100644 index 00000000..5339a70c --- /dev/null +++ b/src/framework/graphics/particlessystem.cpp @@ -0,0 +1,75 @@ +#include "particlessystem.h" +#include "graphics.h" +#include + +Particle::Particle(const Rect& rect, float vx, float vy, float ax, float ay, const Color& color, TexturePtr texture) +{ + m_rect = rect; + m_vx = vx; m_vy = vy; + m_ax = ax; m_ay = ay; + m_color = color; + m_texture = texture; + m_finished = false; +} + +void Particle::render() +{ + g_graphics.bindColor(m_color); + + if(!m_texture) + g_graphics.drawFilledRect(m_rect); + else + g_graphics.drawTexturedRect(m_rect, m_texture); +} + +Emitter::Emitter(const Point& position, int duration, int particlesPerSecond) +{ + m_position = position; + m_duration = duration; + m_particlesPerSecond = particlesPerSecond; + m_createdParticles = 0; + m_startTicks = g_clock.ticks(); + m_finished = false; +} + +void Emitter::render() +{ + for(auto it = m_particles.begin(), end = m_particles.end(); it != end; ++it) + (*it).render(); +} + +void Emitter::update() +{ + ticks_t elapsedTicks = g_clock.ticks() - m_startTicks; + + // check if finished + if(m_duration > 0 && elapsedTicks > m_duration * 1000) + m_finished = true; + + // 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); + } +} + +void ParticlesSystem::add(Emitter emitter) +{ + m_emitters.push_back(emitter); +} + +void ParticlesSystem::render() +{ + for(auto it = m_emitters.begin(), end = m_emitters.end(); it != end; ++it) + (*it).render(); +} + +void ParticlesSystem::update() +{ + for(auto it = m_emitters.begin(), end = m_emitters.end(); it != end;) { + Emitter emitter = *it; + emitter.update(); + ++it; + } +} diff --git a/src/framework/graphics/particlessystem.h b/src/framework/graphics/particlessystem.h new file mode 100644 index 00000000..6eed56e5 --- /dev/null +++ b/src/framework/graphics/particlessystem.h @@ -0,0 +1,78 @@ +#include +#include + +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); + void render(); + +private: + Rect m_rect; + float m_vx, m_vy; + float m_ax, m_ay; + + Color m_color; + TexturePtr m_texture; + bool m_finished; +}; + +class Emitter { +public: + + Emitter(const Point& position, int duration, int particlesPerSecond); + + void render(); + void update(); + +private: + // self related + Point m_position; + int m_duration; + ticks_t m_startTicks; + bool m_finished; + int m_particlesPerSecond, m_createdParticles; + std::list m_particles; + + // particles initial position related to emitter position + float positionMinRadius, positionMaxRadius; + float positionMinAngle, positionMaxAngle; + + // particles initial velocity + float minVelocity, maxVelocity; + float minVelocityAngle, maxVelocityAngle; + + // particles initial acceleration + float minAcceleration, maxAcceleration; + float minAccelerationAngle, maxAccelerationAngle; + + // color ralated + Color color; + + + // texture related +}; + +class Affector { +public: + virtual void update() {}; +}; + +class Gravity270Affector : public Affector { +public: + void update() { + + } +}; + +class ParticlesSystem { +public: + void add(Emitter emitter); + + void render(); + void update(); + +private: + std::list m_emitters; + std::list m_affectors; +}; diff --git a/src/otclient/net/protocolgameparse.cpp b/src/otclient/net/protocolgameparse.cpp index b7caa765..1985c73c 100644 --- a/src/otclient/net/protocolgameparse.cpp +++ b/src/otclient/net/protocolgameparse.cpp @@ -32,6 +32,7 @@ #include #include #include +#include void ProtocolGame::parseMessage(InputMessage& msg) { @@ -527,6 +528,14 @@ void ProtocolGame::parseMagicEffect(InputMessage& msg) TilePtr tile = g_map.getTile(pos); tile->addEffect(effect); + + // test particles + ParticlesSystem particlesSystem; + + Emitter emitter = Emitter(Point(100, 100), 30, 30); + particlesSystem.add(emitter); + + g_particlesManager.add(particlesSystem); } void ProtocolGame::parseAnimatedText(InputMessage& msg)