particles colors

master
Henrique Santiago 13 years ago
parent eed6fab4b1
commit 6973e1639a

@ -1,15 +1,15 @@
ParticleSystem ParticleSystem
AttractionAffector AttractionAffector
delay: 0 delay: 0
duration: 12 duration: 999
destination: 200 200 position: 200 200
acceleration: 64 acceleration: 64
velocity-reduction-percent: 0 velocity-reduction-percent: 0
Emitter Emitter
position: 200 264 position: 200 264
duration: 2 duration: 2
burstRate: 0.2 burstRate: 3
burstCount: 1 burstCount: 1
delay: 0 delay: 0
@ -21,22 +21,6 @@ ParticleSystem
particle-velocity-angle: 0 particle-velocity-angle: 0
particle-acceleration: 0 particle-acceleration: 0
particle-size: 32 32 particle-size: 32 32
particle-color: #33ff33ff particle-colors: #00ff00ff #ff0000ff #0000ffff #00ff00ff #00ff0000
particle-texture: circle2.png particle-colors-stops: 3 6 9 12
Emitter
position: 200 200
burstRate: 13
burstCount: 1
duration: 12
particle-duration: 12
particle-position-radius: 0
particle-velocity: 0
particle-velocity-angle: 0
particle-acceleration: 0
particle-size: 32 32
particle-color: #33ff33ff
particle-texture: circle2.png particle-texture: circle2.png

@ -24,14 +24,17 @@
#include "graphics.h" #include "graphics.h"
#include <framework/core/clock.h> #include <framework/core/clock.h>
Particle::Particle(const Point& pos, const Size& size, const PointF& velocity, const PointF& acceleration, float duration, float ignorePhysicsAfter, const Color& color, TexturePtr texture) Particle::Particle(const Point& pos, const Size& size, const PointF& velocity, const PointF& acceleration, float duration, float ignorePhysicsAfter, const std::vector<Color>& colors, const std::vector<float>& colorsStops, TexturePtr texture)
{ {
m_colors = colors;
m_colorsStops = colorsStops;
m_rect = Rect(pos, size); m_rect = Rect(pos, size);
m_position = PointF(pos.x, pos.y); m_position = PointF(pos.x, pos.y);
m_size = size; m_size = size;
m_velocity = velocity; m_velocity = velocity;
m_acceleration = acceleration; m_acceleration = acceleration;
m_color = color;
m_texture = texture; m_texture = texture;
m_duration = duration; m_duration = duration;
m_ignorePhysicsAfter = ignorePhysicsAfter; m_ignorePhysicsAfter = ignorePhysicsAfter;
@ -55,13 +58,14 @@ void Particle::render()
void Particle::update(double elapsedTime) void Particle::update(double elapsedTime)
{ {
// check if finished // check if finished
if(m_duration > 0 && m_elapsedTime >= m_duration) { if(m_duration >= 0 && m_elapsedTime >= m_duration) {
m_finished = true; m_finished = true;
return; return;
} }
m_elapsedTime += elapsedTime; updateColor();
// update position
if(m_ignorePhysicsAfter < 0 || m_elapsedTime < m_ignorePhysicsAfter ) { if(m_ignorePhysicsAfter < 0 || m_elapsedTime < m_ignorePhysicsAfter ) {
// update position // update position
PointF delta = m_velocity * elapsedTime; PointF delta = m_velocity * elapsedTime;
@ -73,4 +77,25 @@ void Particle::update(double elapsedTime)
m_rect.moveTo((int)m_position.x - m_size.width() / 2, (int)m_position.y - m_size.height() / 2); m_rect.moveTo((int)m_position.x - m_size.width() / 2, (int)m_position.y - m_size.height() / 2);
} }
m_elapsedTime += elapsedTime;
}
void Particle::updateColor()
{
if(m_elapsedTime < m_colorsStops[1]) {
m_color.setRGBA(m_colors[0].r() + (m_colors[1].r() - m_colors[0].r()) / (m_colorsStops[1] - m_colorsStops[0]) * (m_elapsedTime - m_colorsStops[0]),
m_colors[0].g() + (m_colors[1].g() - m_colors[0].g()) / (m_colorsStops[1] - m_colorsStops[0]) * (m_elapsedTime - m_colorsStops[0]),
m_colors[0].b() + (m_colors[1].b() - m_colors[0].b()) / (m_colorsStops[1] - m_colorsStops[0]) * (m_elapsedTime - m_colorsStops[0]),
m_colors[0].a() + (m_colors[1].a() - m_colors[0].a()) / (m_colorsStops[1] - m_colorsStops[0]) * (m_elapsedTime - m_colorsStops[0]));
}
else {
if(m_colors.size() > 1) {
m_colors.erase(m_colors.begin());
m_colorsStops.erase(m_colorsStops.begin());
}
else {
m_color = m_colors[0];
}
}
} }

@ -28,7 +28,7 @@
class Particle { class Particle {
public: public:
Particle(const Point& pos, const Size& size, const PointF& velocity, const PointF& acceleration, float duration, float ignorePhysicsAfter, const Color& color = Fw::white, TexturePtr texture = nullptr); Particle(const Point& pos, const Size& size, const PointF& velocity, const PointF& acceleration, float duration, float ignorePhysicsAfter, const std::vector<Color>& colors, const std::vector<float>& colorsStops, TexturePtr texture = nullptr);
void render(); void render();
void update(double elapsedTime); void update(double elapsedTime);
@ -42,7 +42,11 @@ public:
void setVelocity(const PointF& velocity) { m_velocity = velocity; } void setVelocity(const PointF& velocity) { m_velocity = velocity; }
private: private:
void updateColor();
Color m_color; Color m_color;
std::vector<Color> m_colors;
std::vector<float> m_colorsStops;
TexturePtr m_texture; TexturePtr m_texture;
PointF m_position; PointF m_position;
PointF m_velocity; PointF m_velocity;

@ -37,7 +37,7 @@ ParticleAffector::ParticleAffector()
void ParticleAffector::update(double elapsedTime) void ParticleAffector::update(double elapsedTime)
{ {
if(m_duration > 0 && m_elapsedTime >= m_duration + m_delay) { if(m_duration >= 0 && m_elapsedTime >= m_duration + m_delay) {
m_finished = true; m_finished = true;
return; return;
} }
@ -114,8 +114,8 @@ bool AttractionAffector::load(const OTMLNodePtr& node)
m_acceleration = 32; m_acceleration = 32;
for(const OTMLNodePtr& childNode : node->children()) { for(const OTMLNodePtr& childNode : node->children()) {
if(childNode->tag() == "destination") if(childNode->tag() == "position")
m_destination = childNode->value<Point>(); m_position = childNode->value<Point>();
else if(childNode->tag() == "acceleration") else if(childNode->tag() == "acceleration")
m_acceleration = childNode->value<float>(); m_acceleration = childNode->value<float>();
else if(childNode->tag() == "velocity-reduction-percent") else if(childNode->tag() == "velocity-reduction-percent")
@ -130,7 +130,7 @@ void AttractionAffector::updateParticle(const ParticlePtr& particle, double elap
return; return;
PointF pPosition = particle->getPosition(); PointF pPosition = particle->getPosition();
PointF d = PointF(m_destination.x - pPosition.x, pPosition.y - m_destination.y); PointF d = PointF(m_position.x - pPosition.x, pPosition.y - m_position.y);
if(d.length() == 0) if(d.length() == 0)
return; return;

@ -58,7 +58,7 @@ public:
void updateParticle(const ParticlePtr& particle, double elapsedTime); void updateParticle(const ParticlePtr& particle, double elapsedTime);
private: private:
Point m_destination; Point m_position;
float m_acceleration, m_reduction; float m_acceleration, m_reduction;
}; };

@ -40,6 +40,7 @@ ParticleEmitter::ParticleEmitter(const ParticleSystemPtr& parent)
m_currentBurst = 0; m_currentBurst = 0;
m_elapsedTime = 0; m_elapsedTime = 0;
m_finished = false; m_finished = false;
m_active = false;
// particles default configuration. (make them reasonable for user detect missing properties on scripts) // particles default configuration. (make them reasonable for user detect missing properties on scripts)
m_pMinPositionRadius = 0; m_pMinPositionRadius = 0;
@ -59,7 +60,6 @@ ParticleEmitter::ParticleEmitter(const ParticleSystemPtr& parent)
m_pMaxAcceleration = 64; m_pMaxAcceleration = 64;
m_pMinAccelerationAngle = 0; m_pMinAccelerationAngle = 0;
m_pMaxAccelerationAngle = 360; m_pMaxAccelerationAngle = 360;
m_pColor = Color(255, 255, 255, 128);
} }
bool ParticleEmitter::load(const OTMLNodePtr& node) bool ParticleEmitter::load(const OTMLNodePtr& node)
@ -152,55 +152,70 @@ bool ParticleEmitter::load(const OTMLNodePtr& node)
m_pMinSize = childNode->value<Size>(); m_pMinSize = childNode->value<Size>();
else if(childNode->tag() == "particle-max-size") else if(childNode->tag() == "particle-max-size")
m_pMaxSize = childNode->value<Size>(); m_pMaxSize = childNode->value<Size>();
else if(childNode->tag() == "particle-color")
m_pColor = childNode->value<Color>(); else if(childNode->tag() == "particle-colors")
m_pColors = Fw::split<Color>(childNode->value());
else if(childNode->tag() == "particle-colors-stops")
m_pColorsStops = Fw::split<float>(childNode->value());
else if(childNode->tag() == "particle-texture") else if(childNode->tag() == "particle-texture")
m_pTexture = g_textures.getTexture(childNode->value()); m_pTexture = g_textures.getTexture(childNode->value());
} }
if(m_pColors.empty())
m_pColors.push_back(Color(255, 255, 255, 128));
m_pColorsStops.insert(m_pColorsStops.begin(), 0);
if(m_pColors.size() != m_pColorsStops.size()) {
logError("particle colors must be equal to colorstops-1");
return false;
}
return true; return true;
} }
void ParticleEmitter::update(double elapsedTime) void ParticleEmitter::update(double elapsedTime)
{ {
// check if finished // check if finished
if(m_duration > 0 && m_elapsedTime >= m_duration + m_delay) { if(m_duration >= 0 && m_elapsedTime >= m_duration + m_delay) {
m_finished = true; m_finished = true;
return; return;
} }
m_elapsedTime += elapsedTime; if(!m_active && m_elapsedTime > m_delay)
m_active = true;
if(m_elapsedTime - elapsedTime < m_delay)
return;
int currentBurst = std::floor((m_elapsedTime - m_delay) / m_burstRate) + 1; if(m_active) {
for(int b = m_currentBurst; b < currentBurst; ++b) { int currentBurst = std::floor((m_elapsedTime - m_delay) / m_burstRate) + 1;
for(int b = m_currentBurst; b < currentBurst; ++b) {
// every burst created at same position. // every burst created at same position.
float pRadius = Fw::randomRange(m_pMinPositionRadius, m_pMaxPositionRadius); float pRadius = Fw::randomRange(m_pMinPositionRadius, m_pMaxPositionRadius);
float pAngle = Fw::randomRange(m_pMinPositionAngle, m_pMaxPositionAngle); float pAngle = Fw::randomRange(m_pMinPositionAngle, m_pMaxPositionAngle);
Point pPosition = m_position + Point(pRadius * cos(pAngle), pRadius * sin(pAngle)); Point pPosition = m_position + Point(pRadius * cos(pAngle), pRadius * sin(pAngle));
for(int p = 0; p < m_burstCount; ++p) { 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);
// particles initial velocity // particles initial velocity
float pVelocityAbs = Fw::randomRange(m_pMinVelocity, m_pMaxVelocity); float pVelocityAbs = Fw::randomRange(m_pMinVelocity, m_pMaxVelocity);
float pVelocityAngle = Fw::randomRange(m_pMinVelocityAngle, m_pMaxVelocityAngle); float pVelocityAngle = Fw::randomRange(m_pMinVelocityAngle, m_pMaxVelocityAngle);
PointF pVelocity(pVelocityAbs * cos(pVelocityAngle), pVelocityAbs * sin(pVelocityAngle)); PointF pVelocity(pVelocityAbs * cos(pVelocityAngle), pVelocityAbs * sin(pVelocityAngle));
// particles initial acceleration // particles initial acceleration
float pAccelerationAbs = Fw::randomRange(m_pMinAcceleration, m_pMaxAcceleration); float pAccelerationAbs = Fw::randomRange(m_pMinAcceleration, m_pMaxAcceleration);
float pAccelerationAngle = Fw::randomRange(m_pMinAccelerationAngle, m_pMaxAccelerationAngle); float pAccelerationAngle = Fw::randomRange(m_pMinAccelerationAngle, m_pMaxAccelerationAngle);
PointF pAcceleration(pAccelerationAbs * cos(pAccelerationAngle), pAccelerationAbs * sin(pAccelerationAngle)); PointF pAcceleration(pAccelerationAbs * cos(pAccelerationAngle), pAccelerationAbs * sin(pAccelerationAngle));
ParticleSystemPtr particleSystem = m_parent.lock(); ParticleSystemPtr particleSystem = m_parent.lock();
particleSystem->addParticle(ParticlePtr(new Particle(pPosition, pSize, pVelocity, pAcceleration, pDuration, m_pIgnorePhysicsAfter, m_pColor, m_pTexture))); particleSystem->addParticle(ParticlePtr(new Particle(pPosition, pSize, pVelocity, pAcceleration, pDuration, m_pIgnorePhysicsAfter, m_pColors, m_pColorsStops, m_pTexture)));
}
} }
m_currentBurst = currentBurst;
} }
m_currentBurst = currentBurst; m_elapsedTime += elapsedTime;
} }

@ -47,7 +47,7 @@ private:
Point m_position; Point m_position;
float m_duration, m_delay; float m_duration, m_delay;
double m_elapsedTime; double m_elapsedTime;
bool m_finished; bool m_finished, m_active;
float m_burstRate; float m_burstRate;
int m_currentBurst, m_burstCount; int m_currentBurst, m_burstCount;
@ -70,7 +70,8 @@ private:
float m_pMinDuration, m_pMaxDuration, m_pIgnorePhysicsAfter; float m_pMinDuration, m_pMaxDuration, m_pIgnorePhysicsAfter;
// visual ralated // visual ralated
Color m_pColor; std::vector<Color> m_pColors;
std::vector<float> m_pColorsStops;
TexturePtr m_pTexture; TexturePtr m_pTexture;
}; };

@ -35,7 +35,8 @@ bool ParticleSystem::load(const OTMLNodePtr& node)
for(const OTMLNodePtr& childNode : node->children()) { for(const OTMLNodePtr& childNode : node->children()) {
if(childNode->tag() == "Emitter") { if(childNode->tag() == "Emitter") {
ParticleEmitterPtr emitter = ParticleEmitterPtr(new ParticleEmitter(shared_from_this())); ParticleEmitterPtr emitter = ParticleEmitterPtr(new ParticleEmitter(shared_from_this()));
emitter->load(childNode); if(!emitter->load(childNode))
return false;
m_emitters.push_back(emitter); m_emitters.push_back(emitter);
} }
else if(childNode->tag().find("Affector") != std::string::npos) { else if(childNode->tag().find("Affector") != std::string::npos) {
@ -47,7 +48,8 @@ bool ParticleSystem::load(const OTMLNodePtr& node)
affector = ParticleAffectorPtr(new AttractionAffector); affector = ParticleAffectorPtr(new AttractionAffector);
if(affector) { if(affector) {
affector->load(childNode); if(!affector->load(childNode))
return false;
m_affectors.push_back(affector); m_affectors.push_back(affector);
} }
} }

Loading…
Cancel
Save