particles colors

This commit is contained in:
Henrique Santiago 2011-12-18 00:21:12 -02:00
parent eed6fab4b1
commit 6973e1639a
8 changed files with 94 additions and 63 deletions

View File

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

View File

@ -24,14 +24,17 @@
#include "graphics.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_position = PointF(pos.x, pos.y);
m_size = size;
m_velocity = velocity;
m_acceleration = acceleration;
m_color = color;
m_texture = texture;
m_duration = duration;
m_ignorePhysicsAfter = ignorePhysicsAfter;
@ -55,13 +58,14 @@ void Particle::render()
void Particle::update(double elapsedTime)
{
// check if finished
if(m_duration > 0 && m_elapsedTime >= m_duration) {
if(m_duration >= 0 && m_elapsedTime >= m_duration) {
m_finished = true;
return;
}
m_elapsedTime += elapsedTime;
updateColor();
// update position
if(m_ignorePhysicsAfter < 0 || m_elapsedTime < m_ignorePhysicsAfter ) {
// update position
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_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];
}
}
}

View File

@ -28,7 +28,7 @@
class Particle {
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 update(double elapsedTime);
@ -42,7 +42,11 @@ public:
void setVelocity(const PointF& velocity) { m_velocity = velocity; }
private:
void updateColor();
Color m_color;
std::vector<Color> m_colors;
std::vector<float> m_colorsStops;
TexturePtr m_texture;
PointF m_position;
PointF m_velocity;

View File

@ -37,7 +37,7 @@ ParticleAffector::ParticleAffector()
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;
return;
}
@ -114,8 +114,8 @@ bool AttractionAffector::load(const OTMLNodePtr& node)
m_acceleration = 32;
for(const OTMLNodePtr& childNode : node->children()) {
if(childNode->tag() == "destination")
m_destination = childNode->value<Point>();
if(childNode->tag() == "position")
m_position = childNode->value<Point>();
else if(childNode->tag() == "acceleration")
m_acceleration = childNode->value<float>();
else if(childNode->tag() == "velocity-reduction-percent")
@ -130,7 +130,7 @@ void AttractionAffector::updateParticle(const ParticlePtr& particle, double elap
return;
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)
return;

View File

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

View File

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

View File

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

View File

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