particles improvements

master
Henrique Santiago 13 years ago
parent 8638c980ec
commit 24022317be

@ -27,6 +27,8 @@
namespace Fw namespace Fw
{ {
static const double pi = 3.14159265;
// NOTE: AABBGGRR order // NOTE: AABBGGRR order
enum GlobalColor : uint32 { enum GlobalColor : uint32 {
alpha = 0x00000000, alpha = 0x00000000,

@ -1,7 +1,25 @@
#include "particlesmanager.h" #include "particlesmanager.h"
#include <framework/core/resourcemanager.h>
#include <framework/otml/otml.h>
ParticlesManager g_particlesManager; ParticlesManager g_particlesManager;
bool ParticlesManager::load(const std::string& filename)
{
if(!g_resources.fileExists(filename))
return false;
try {
OTMLDocumentPtr doc = OTMLDocument::parse(filename);
//for(const OTMLNodePtr& child : doc->children())
//m_confsMap[child->tag()] = child->value();
return true;
} catch(Exception& e) {
logError("could not load configurations: ", e.what());
return false;
}
}
void ParticlesManager::add(ParticlesSystem particleSystem) void ParticlesManager::add(ParticlesSystem particleSystem)
{ {
// check it has emitters // check it has emitters

@ -2,6 +2,8 @@
class ParticlesManager { class ParticlesManager {
public: public:
bool load(const std::string& filename);
void add(ParticlesSystem particleSystem); void add(ParticlesSystem particleSystem);
void render(); void render();

@ -29,9 +29,9 @@ void Particle::render()
if(!m_texture) if(!m_texture)
g_painter.drawFilledRect(m_rect); g_painter.drawFilledRect(m_rect);
else { else {
g_painter.setCompositionMode(Painter::CompositionMode_AdditiveSource); //g_painter.setCompositionMode(Painter::CompositionMode_AdditiveSource);
g_painter.drawTexturedRect(m_rect, m_texture); g_painter.drawTexturedRect(m_rect, m_texture);
g_painter.setCompositionMode(Painter::CompositionMode_SourceOver); //g_painter.setCompositionMode(Painter::CompositionMode_SourceOver);
} }
} }
@ -50,28 +50,33 @@ void Particle::update()
m_iy + (m_vy * t / 1000.0) + (m_ay * t*t / (2.0 * 1000 * 1000))); m_iy + (m_vy * t / 1000.0) + (m_ay * t*t / (2.0 * 1000 * 1000)));
} }
ParticleEmitter::ParticleEmitter(const Point& position, float duration, int particlesPerSecond) ParticleEmitter::ParticleEmitter(const Point& position, float duration, float burstRate, float burstCount)
{ {
m_position = position; m_position = position;
m_duration = duration; m_duration = duration;
m_particlesPerSecond = particlesPerSecond; m_burstRate = burstRate; m_burstCount = burstCount;
m_createdParticles = 0; m_currentBurst = 0;
m_startTicks = g_clock.ticks(); m_startTicks = g_clock.ticks();
m_finished = false; m_finished = false;
// particles default configuration. (make them reasonable detect missing properties on scripts) // particles default configuration. (make them reasonable for user detect missing properties on scripts)
m_pPositionMinRadius = 0; m_pPositionMaxRadius = 3; m_pPositionMinRadius = 0; m_pPositionMaxRadius = 3;
m_pPositionMinAngle = 0; m_pPositionMaxAngle = 90; m_pPositionMinAngle = -Fw::pi; m_pPositionMaxAngle = Fw::pi;
m_pMinSize = Size(32, 32); m_pMaxSize = Size(32, 32); m_pMinSize = Size(32, 32); m_pMaxSize = Size(32, 32);
m_pMinDuration = 0; m_pMaxDuration = 10; m_pMinDuration = 0; m_pMaxDuration = 10;
m_pMinVelocity = 32; m_pMaxVelocity = 64;
m_pMinVelocityAngle = -Fw::pi; m_pMaxVelocityAngle = Fw::pi;
m_pMinAcceleration = 32; m_pMaxAcceleration = 64;
m_pMinAccelerationAngle = -Fw::pi; m_pMaxAccelerationAngle = Fw::pi;
m_pColor = Color(255, 0, 0, 128);
m_pTexture = nullptr;
} }
void ParticleEmitter::render() void ParticleEmitter::render()
{ {
// testing
//g_graphics.bindColor(Color(255, 255, 255));
//g_graphics.drawFilledRect(Rect(0, 0, 400, 400));
for(auto it = m_particles.begin(), end = m_particles.end(); it != end; ++it) for(auto it = m_particles.begin(), end = m_particles.end(); it != end; ++it)
(*it)->render(); (*it)->render();
} }
@ -98,24 +103,37 @@ void ParticleEmitter::update()
} }
// create some particles // create some particles
TexturePtr tex = g_textures.getTexture("circle2.png"); m_pTexture = g_textures.getTexture("circle2.png"); // remove this, 'll be parsed on loader
int currentParticles = 1 + elapsedTicks / 1000.0 * m_particlesPerSecond; int currentBurst = elapsedTicks / 1000.0 / m_burstRate + 1;
for(int i = m_createdParticles; i < currentParticles; ++i) { for(int b = m_currentBurst; b < currentBurst; ++b) {
// \/ not working properly // every burst created at same position.
float pRadius = Fw::randomRange(m_pPositionMinRadius, m_pPositionMaxRadius); float pRadius = Fw::randomRange(m_pPositionMinRadius, m_pPositionMaxRadius);
float pAngle = Fw::randomRange(m_pPositionMinAngle, m_pPositionMaxAngle) * 3.141592 / 180.0; float pAngle = Fw::randomRange(m_pPositionMinAngle, m_pPositionMaxAngle);
Point pPosition = Point(pRadius * cos(pAngle), pRadius * sin(pAngle));
Point pPosition = Point(cos(pAngle * pRadius), sin(pAngle * pRadius)); for(int p = 0; p < m_burstCount; ++p) {
Size pSize = Size(Fw::randomRange(m_pMinSize.width(), m_pMaxSize.width()), Fw::randomRange(m_pMinSize.height(), m_pMaxSize.height())); Size pSize = Size(Fw::randomRange(m_pMinSize.width(), m_pMaxSize.width()), Fw::randomRange(m_pMinSize.height(), m_pMaxSize.height()));
float pDuration = Fw::randomRange(m_pMinDuration, m_pMaxDuration); float pDuration = Fw::randomRange(m_pMinDuration, m_pMaxDuration);
// todo: add random data generation // particles initial velocity
m_particles.push_back(ParticlePtr(new Particle(Rect(m_position + pPosition, pSize), 16, 8, 0, 0, pDuration, Color(255, 0, 0, 32), tex))); float pVelocity = Fw::randomRange(m_pMinVelocity, m_pMaxVelocity);
float pVelocityAngle = Fw::randomRange(m_pMinVelocityAngle, m_pMaxVelocityAngle);
// particles initial acceleration
float pAcceleration = Fw::randomRange(m_pMinAcceleration, m_pMaxAcceleration);
float pAccelerationAngle = Fw::randomRange(m_pMinAccelerationAngle, m_pMaxAccelerationAngle);
m_particles.push_back(ParticlePtr(new Particle(Rect(m_position + pPosition, pSize),
pVelocity * cos(pVelocityAngle), pVelocity * sin(pVelocityAngle),
pAcceleration * cos(pAccelerationAngle), pAcceleration * sin(pAccelerationAngle),
pDuration, m_pColor, m_pTexture)));
}
} }
m_createdParticles = currentParticles;
m_currentBurst = currentBurst;
} }
void ParticlesSystem::add(const ParticleEmitterPtr& emitter) void ParticlesSystem::add(const ParticleEmitterPtr& emitter)

@ -31,7 +31,7 @@ typedef std::shared_ptr<Particle> ParticlePtr;
class ParticleEmitter { class ParticleEmitter {
public: public:
ParticleEmitter(const Point& position, float duration, int particlesPerSecond); ParticleEmitter(const Point& position, float duration, float burstRate, float burstCount);
void render(); void render();
void update(); void update();
@ -44,7 +44,8 @@ private:
int m_duration; int m_duration;
ticks_t m_startTicks; ticks_t m_startTicks;
bool m_finished; bool m_finished;
int m_particlesPerSecond, m_createdParticles; float m_burstRate, m_burstCount;
int m_currentBurst;
std::list<ParticlePtr> m_particles; std::list<ParticlePtr> m_particles;
// particles size // particles size
@ -55,21 +56,19 @@ private:
float m_pPositionMinAngle, m_pPositionMaxAngle; float m_pPositionMinAngle, m_pPositionMaxAngle;
// particles initial velocity // particles initial velocity
float minVelocity, maxVelocity; float m_pMinVelocity, m_pMaxVelocity;
float minVelocityAngle, maxVelocityAngle; float m_pMinVelocityAngle, m_pMaxVelocityAngle;
// particles initial acceleration // particles initial acceleration
float minAcceleration, maxAcceleration; float m_pMinAcceleration, m_pMaxAcceleration;
float minAccelerationAngle, maxAccelerationAngle; float m_pMinAccelerationAngle, m_pMaxAccelerationAngle;
// particles duration // particles duration
float m_pMinDuration, m_pMaxDuration; float m_pMinDuration, m_pMaxDuration;
// color ralated // visual ralated
Color color; Color m_pColor;
TexturePtr m_pTexture;
// texture related
}; };
typedef std::shared_ptr<ParticleEmitter> ParticleEmitterPtr; typedef std::shared_ptr<ParticleEmitter> ParticleEmitterPtr;
@ -81,7 +80,7 @@ public:
class Gravity270Affector : public Affector { class Gravity270Affector : public Affector {
public: public:
void update() { void update() {
// earth gravity is 9.8 m/s². -> in tibia, 32 pixels are equal to 1 meter -> 32 pixels/m -> 9.8 * 32 is gravity constant
} }
}; };

@ -344,15 +344,12 @@ void Creature::setHealthPercent(uint8 healthPercent)
void Creature::setDirection(Otc::Direction direction) void Creature::setDirection(Otc::Direction direction)
{ {
if(direction >= 4) { if(direction == Otc::NorthEast || direction == Otc::SouthEast)
if(direction == Otc::NorthEast || direction == Otc::SouthEast) m_xPattern = Otc::East;
m_xPattern = Otc::East; else if(direction == Otc::NorthWest || direction == Otc::SouthWest)
else if(direction == Otc::NorthWest || direction == Otc::SouthWest) m_xPattern = Otc::West;
m_xPattern = Otc::West; else
}
else {
m_xPattern = direction; m_xPattern = direction;
}
m_direction = direction; m_direction = direction;
} }

@ -532,7 +532,7 @@ void ProtocolGame::parseMagicEffect(InputMessage& msg)
// test particles // test particles
ParticlesSystem particlesSystem; ParticlesSystem particlesSystem;
particlesSystem.add(ParticleEmitterPtr(new ParticleEmitter(Point(100, 100), -1, 40))); particlesSystem.add(ParticleEmitterPtr(new ParticleEmitter(Point(100, 100), -1, 2, 10)));
g_particlesManager.add(particlesSystem); g_particlesManager.add(particlesSystem);
} }

Loading…
Cancel
Save