particles colors
This commit is contained in:
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-colors-stops: 3 6 9 12
|
||||||
particle-texture: circle2.png
|
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
|
|
||||||
|
|
||||||
|
|
|
@ -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,27 +152,39 @@ 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;
|
|
||||||
|
|
||||||
|
if(m_active) {
|
||||||
int currentBurst = std::floor((m_elapsedTime - m_delay) / m_burstRate) + 1;
|
int currentBurst = std::floor((m_elapsedTime - m_delay) / m_burstRate) + 1;
|
||||||
for(int b = m_currentBurst; b < currentBurst; ++b) {
|
for(int b = m_currentBurst; b < currentBurst; ++b) {
|
||||||
|
|
||||||
|
@ -198,9 +210,12 @@ void ParticleEmitter::update(double elapsedTime)
|
||||||
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…
Reference in New Issue