Switch particle lifetimes to use std::chrono instead of sf::Clock
Also create emitter properties, fix some code and some other things.
This commit is contained in:
parent
c949d44d98
commit
bde19814a5
|
@ -4,10 +4,15 @@
|
||||||
// Email: seanomik@gmail.com
|
// Email: seanomik@gmail.com
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include "simpleengine/random.h"
|
||||||
|
#include <SFML/Graphics/CircleShape.hpp>
|
||||||
|
#include <SFML/Graphics/PrimitiveType.hpp>
|
||||||
#include <SFML/Graphics/Rect.hpp>
|
#include <SFML/Graphics/Rect.hpp>
|
||||||
#include <SFML/Graphics/RenderStates.hpp>
|
#include <SFML/Graphics/RenderStates.hpp>
|
||||||
|
#include <SFML/System/Vector2.hpp>
|
||||||
#include <SFML/System/Vector3.hpp>
|
#include <SFML/System/Vector3.hpp>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include <simpleengine/game.h>
|
#include <simpleengine/game.h>
|
||||||
#include <simpleengine/event.h>
|
#include <simpleengine/event.h>
|
||||||
#include <simpleengine/entity.h>
|
#include <simpleengine/entity.h>
|
||||||
|
@ -16,6 +21,7 @@
|
||||||
// Particle
|
// Particle
|
||||||
#include <simpleengine/particle/emitter.h>
|
#include <simpleengine/particle/emitter.h>
|
||||||
#include <simpleengine/particle/particle_property.h>
|
#include <simpleengine/particle/particle_property.h>
|
||||||
|
#include <simpleengine/particle/particle_emitter_property.h>
|
||||||
#include <simpleengine/particle/properties/random_lifetime_property.h>
|
#include <simpleengine/particle/properties/random_lifetime_property.h>
|
||||||
#include <simpleengine/particle/properties/random_velocity_property.h>
|
#include <simpleengine/particle/properties/random_velocity_property.h>
|
||||||
|
|
||||||
|
@ -25,6 +31,9 @@
|
||||||
#include <ios>
|
#include <ios>
|
||||||
#include <random>
|
#include <random>
|
||||||
|
|
||||||
|
#define _USE_MATH_DEFINES
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
namespace se = simpleengine;
|
namespace se = simpleengine;
|
||||||
|
|
||||||
class ParticleEmitter : public se::particle::ParticleEmitter {
|
class ParticleEmitter : public se::particle::ParticleEmitter {
|
||||||
|
@ -34,14 +43,17 @@ private:
|
||||||
sf::Sprite sprite;
|
sf::Sprite sprite;
|
||||||
sf::Texture texture;
|
sf::Texture texture;
|
||||||
|
|
||||||
Super::ParticlePropertyVector properties = {
|
Super::ParticlePropertyVector particle_properties;
|
||||||
std::make_shared<se::particle::RandomVelocityParticleProperty>(se::Range2f(-1.5f, 1.5f, -1.5f, 1.5f)),
|
Super::EmitterPropertyVector emitter_properties;
|
||||||
std::make_shared<se::particle::RandomLifetimeParticleProperty>(se::Rangef(1'500, 9'500))
|
|
||||||
};
|
|
||||||
public:
|
public:
|
||||||
ParticleEmitter() : Super(texture, sf::Vector2f(350, 350), 0.7, 5, 1500, se::Range2f(-50, 50, -50, 50), se::particle::ParticleAttributes{0, sf::Vector2f(), 5, sf::Vector2f(2, 2)}, properties) {
|
ParticleEmitter() : Super(texture, sf::Vector2f(350, 350), .5f, 10, 900, se::Range2f(-50, 50, -50, 50), se::particle::ParticleAttributes{2000, sf::Vector2f(.1f, .1f), 5, sf::Vector2f(2, 2)}, particle_properties, emitter_properties) {
|
||||||
texture.loadFromFile("particle.png"); // The particle I tested with was 5x5 pixels
|
texture.loadFromFile("particle.png"); // The particle I tested with was 5x5 pixels
|
||||||
texture.setSmooth(true);
|
texture.setSmooth(true);
|
||||||
|
|
||||||
|
particle_properties.emplace_back(std::make_unique<se::particle::RandomVelocityParticleProperty>(se::Range2f(-1.5f, 1.5f, -1.5f, 1.5f)));
|
||||||
|
|
||||||
|
using namespace std::chrono_literals;
|
||||||
|
particle_properties.emplace_back(std::make_unique<se::particle::RandomLifetimeParticleProperty>(2'500ms, 5'500ms));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Update(const float& delta_time) override {
|
void Update(const float& delta_time) override {
|
||||||
|
|
|
@ -21,7 +21,6 @@ namespace simpleengine {
|
||||||
virtual void Render(sf::RenderTarget* target) = 0;
|
virtual void Render(sf::RenderTarget* target) = 0;
|
||||||
protected:
|
protected:
|
||||||
sf::RenderWindow* window;
|
sf::RenderWindow* window;
|
||||||
bool quit = false;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#include "../event.h"
|
#include "../event.h"
|
||||||
#include "particle_property.h"
|
#include "particle_property.h"
|
||||||
|
#include "particle_emitter_property.h"
|
||||||
#include "particle.h"
|
#include "particle.h"
|
||||||
#include "../random.h"
|
#include "../random.h"
|
||||||
#include "../range_2.h"
|
#include "../range_2.h"
|
||||||
|
@ -19,7 +20,6 @@
|
||||||
#include <SFML/System/Clock.hpp>
|
#include <SFML/System/Clock.hpp>
|
||||||
|
|
||||||
#include <SFML/System/Vector2.hpp>
|
#include <SFML/System/Vector2.hpp>
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
namespace simpleengine {
|
namespace simpleengine {
|
||||||
namespace particle {
|
namespace particle {
|
||||||
|
@ -32,12 +32,15 @@ namespace simpleengine {
|
||||||
|
|
||||||
class ParticleEmitter : public simpleengine::Event {
|
class ParticleEmitter : public simpleengine::Event {
|
||||||
protected:
|
protected:
|
||||||
using ParticlePropertyPtr = std::shared_ptr<simpleengine::particle::ParticleProperty>;
|
using ParticlePropertyPtr = std::unique_ptr<simpleengine::particle::ParticleProperty>;
|
||||||
using ParticlePropertyVector = std::vector<ParticlePropertyPtr>;
|
using ParticlePropertyVector = std::vector<ParticlePropertyPtr>;
|
||||||
public:
|
|
||||||
ParticleEmitter(sf::Texture& texture, sf::Vector2f position, double emit_variance, uint32_t emit_count, uint32_t particle_count, Range2f particle_range, ParticleAttributes attributes, ParticlePropertyVector& properties);
|
|
||||||
|
|
||||||
void SetProperties(ParticlePropertyVector& properties);
|
using EmitterPropertyPtr = std::unique_ptr<simpleengine::particle::ParticleEmitterProperty>;
|
||||||
|
using EmitterPropertyVector = std::vector<EmitterPropertyPtr>;
|
||||||
|
public:
|
||||||
|
ParticleEmitter(sf::Texture& texture, sf::Vector2f position, double emit_variance, uint32_t emit_count, uint32_t particle_count, Range2f particle_range, ParticleAttributes attributes, ParticlePropertyVector& particle_properties, EmitterPropertyVector& emitter_properties);
|
||||||
|
|
||||||
|
void SetProperties(ParticlePropertyVector particle_properties);
|
||||||
|
|
||||||
virtual void Update(const float& delta_time) override;
|
virtual void Update(const float& delta_time) override;
|
||||||
virtual void Render(sf::RenderTarget* target) override;
|
virtual void Render(sf::RenderTarget* target) override;
|
||||||
|
@ -49,7 +52,8 @@ namespace simpleengine {
|
||||||
uint32_t particle_count;
|
uint32_t particle_count;
|
||||||
Range2f particle_range;
|
Range2f particle_range;
|
||||||
ParticleAttributes attributes;
|
ParticleAttributes attributes;
|
||||||
ParticlePropertyVector& properties;
|
ParticlePropertyVector& particle_properties;
|
||||||
|
EmitterPropertyVector& emitter_properties;
|
||||||
|
|
||||||
std::vector<simpleengine::particle::Particle> particles;
|
std::vector<simpleengine::particle::Particle> particles;
|
||||||
sf::Clock time;
|
sf::Clock time;
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include <SFML/System/Time.hpp>
|
#include <SFML/System/Time.hpp>
|
||||||
#include <SFML/System/Vector2.hpp>
|
#include <SFML/System/Vector2.hpp>
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace simpleengine {
|
namespace simpleengine {
|
||||||
|
@ -23,25 +24,47 @@ namespace simpleengine {
|
||||||
private:
|
private:
|
||||||
using Super = simpleengine::Event;
|
using Super = simpleengine::Event;
|
||||||
protected:
|
protected:
|
||||||
using ParticlePropertyPtr = std::shared_ptr<simpleengine::particle::ParticleProperty>;
|
using ParticlePropertyPtr = std::unique_ptr<simpleengine::particle::ParticleProperty>;
|
||||||
using ParticlePropertyVector = std::vector<ParticlePropertyPtr>;
|
using ParticlePropertyVector = std::vector<ParticlePropertyPtr>;
|
||||||
public:
|
public:
|
||||||
Particle(sf::Texture& texture, sf::Vector2f velocity, uint32_t lifetime_ms, float rotation_velocity, ParticlePropertyVector properties);
|
friend class ParticleEmitter;
|
||||||
|
|
||||||
|
template<class DurRep, class DurPeriod>
|
||||||
|
Particle(sf::Texture& texture, sf::Vector2f velocity, std::chrono::duration<DurRep, DurPeriod> lifetime, float rotation_velocity,
|
||||||
|
ParticlePropertyVector properties)
|
||||||
|
: Super(nullptr), velocity(velocity), rotation_velocity(rotation_velocity), properties(std::move(properties)) {
|
||||||
|
sprite.setTexture(texture);
|
||||||
|
|
||||||
|
birth_point = std::chrono::high_resolution_clock::now();
|
||||||
|
death_point = birth_point + lifetime;
|
||||||
|
|
||||||
|
// Trigger OnParticleSpawn for particle properities.
|
||||||
|
for (ParticlePropertyPtr& property : this->properties) {
|
||||||
|
property->OnParticleSpawn(*this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Particle(const Particle& other);
|
||||||
|
Particle& operator=(Particle other);
|
||||||
|
|
||||||
virtual void Update(const float& delta_time) override;
|
virtual void Update(const float& delta_time) override;
|
||||||
virtual void Render(sf::RenderTarget* target) override;
|
virtual void Render(sf::RenderTarget* target) override;
|
||||||
|
|
||||||
sf::Sprite& GetSprite();
|
template<class DurRep, class DurPeriod>
|
||||||
const sf::Time GetAge() const;
|
void SetLifetime(std::chrono::duration<DurRep, DurPeriod> lifetime) {
|
||||||
|
death_point = std::chrono::high_resolution_clock::now() + lifetime;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::chrono::microseconds GetAge() const;
|
||||||
|
std::chrono::duration<long long, std::ratio<1, 1000000000>> GetLifetime() const;
|
||||||
|
|
||||||
sf::Sprite sprite;
|
sf::Sprite sprite;
|
||||||
sf::Vector2f velocity;
|
sf::Vector2f velocity;
|
||||||
uint32_t lifetime_ms;
|
|
||||||
float rotation_velocity;
|
float rotation_velocity;
|
||||||
ParticlePropertyVector properties;
|
ParticlePropertyVector properties;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
sf::Clock age_clock;
|
std::chrono::time_point<std::chrono::high_resolution_clock> birth_point;
|
||||||
|
std::chrono::time_point<std::chrono::high_resolution_clock> death_point;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
//
|
||||||
|
// Created by SeanOMik on 3/23/2021.
|
||||||
|
// Github: https://github.com/SeanOMik
|
||||||
|
// Email: seanomik@gmail.com
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef SIMPLEENGINE_PARTICLE_EMITTER_PROPERTY_H
|
||||||
|
#define SIMPLEENGINE_PARTICLE_EMITTER_PROPERTY_H
|
||||||
|
|
||||||
|
#include "../event.h"
|
||||||
|
|
||||||
|
namespace simpleengine {
|
||||||
|
namespace particle {
|
||||||
|
class Particle;
|
||||||
|
class ParticleEmitterProperty {
|
||||||
|
public:
|
||||||
|
//virtual void Clone() = 0;
|
||||||
|
virtual void BeforeParticleSpawn(simpleengine::particle::Particle& particle) = 0;
|
||||||
|
virtual void Update(simpleengine::particle::Particle& particle) = 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //SIMPLEENGINE_PARTICLE_EMITTER_PROPERTY_H
|
|
@ -8,14 +8,14 @@
|
||||||
#define SIMPLEENGINE_PARTICLE_PROPERTY_H
|
#define SIMPLEENGINE_PARTICLE_PROPERTY_H
|
||||||
|
|
||||||
#include "../event.h"
|
#include "../event.h"
|
||||||
|
#include <algorithm>
|
||||||
#include <SFML/Graphics/RenderStates.hpp>
|
|
||||||
|
|
||||||
namespace simpleengine {
|
namespace simpleengine {
|
||||||
namespace particle {
|
namespace particle {
|
||||||
class Particle;
|
class Particle;
|
||||||
class ParticleProperty {
|
class ParticleProperty {
|
||||||
public:
|
public:
|
||||||
|
virtual std::unique_ptr<ParticleProperty> Clone() const = 0;
|
||||||
virtual void OnParticleSpawn(simpleengine::particle::Particle& particle) = 0;
|
virtual void OnParticleSpawn(simpleengine::particle::Particle& particle) = 0;
|
||||||
virtual void Update(simpleengine::particle::Particle& particle) = 0;
|
virtual void Update(simpleengine::particle::Particle& particle) = 0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -12,28 +12,50 @@
|
||||||
#include "../../random.h"
|
#include "../../random.h"
|
||||||
#include "../particle.h"
|
#include "../particle.h"
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
#include <memory>
|
||||||
|
#include <iostream>
|
||||||
|
#include <ratio>
|
||||||
|
|
||||||
namespace simpleengine {
|
namespace simpleengine {
|
||||||
namespace particle {
|
namespace particle {
|
||||||
class RandomLifetimeParticleProperty : public ParticleProperty {
|
class RandomLifetimeParticleProperty : public ParticleProperty {
|
||||||
public:
|
public:
|
||||||
RandomLifetimeParticleProperty(simpleengine::Rangef range) : range(range) {
|
template<class DurRep, class DurPeriod>
|
||||||
|
RandomLifetimeParticleProperty(std::chrono::duration<DurRep, DurPeriod> min, std::chrono::duration<DurRep, DurPeriod> max)
|
||||||
|
: range(Range<std::chrono::milliseconds>(
|
||||||
|
std::chrono::duration_cast<std::chrono::milliseconds>(min),
|
||||||
|
std::chrono::duration_cast<std::chrono::milliseconds>(max))) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RandomLifetimeParticleProperty(float min, float max) : RandomLifetimeParticleProperty(Rangef(min, max)) {
|
template<class DurRep, class DurPeriod>
|
||||||
|
RandomLifetimeParticleProperty(const simpleengine::Range<std::chrono::duration<DurRep, DurPeriod>>& range) : RandomLifetimeParticleProperty(range.min, range.max) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RandomLifetimeParticleProperty(const RandomLifetimeParticleProperty& other) {
|
||||||
|
this->range = other.range;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<ParticleProperty> Clone() const override {
|
||||||
|
return std::make_unique<RandomLifetimeParticleProperty>(range);
|
||||||
|
}
|
||||||
|
|
||||||
void OnParticleSpawn(simpleengine::particle::Particle& particle) override {
|
void OnParticleSpawn(simpleengine::particle::Particle& particle) override {
|
||||||
simpleengine::Random<float> rand;
|
simpleengine::Random<double, std::random_device, std::mt19937_64> rand;
|
||||||
particle.lifetime_ms = rand.NextInRange(range.min, range.max);
|
|
||||||
|
int lifetime = rand.NextInRange(range.min.count(), range.max.count());
|
||||||
|
particle.SetLifetime(std::chrono::milliseconds(lifetime));
|
||||||
|
|
||||||
|
//std::cout << "Lifetime: " << lifetime << "ms" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Update(simpleengine::particle::Particle& particle) override {
|
void Update(simpleengine::particle::Particle& particle) override {
|
||||||
|
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
simpleengine::Rangef range;
|
simpleengine::Range<std::chrono::milliseconds> range;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,11 +12,14 @@
|
||||||
#include "../../random.h"
|
#include "../../random.h"
|
||||||
#include "../particle.h"
|
#include "../particle.h"
|
||||||
|
|
||||||
|
#include <random>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
namespace simpleengine {
|
namespace simpleengine {
|
||||||
namespace particle {
|
namespace particle {
|
||||||
class RandomVelocityParticleProperty : public ParticleProperty {
|
class RandomVelocityParticleProperty : public ParticleProperty {
|
||||||
public:
|
public:
|
||||||
RandomVelocityParticleProperty(simpleengine::Range2f range) : range(range) {
|
RandomVelocityParticleProperty(const simpleengine::Range2f& range) : range(range) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,11 +28,19 @@ namespace simpleengine {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RandomVelocityParticleProperty(const RandomVelocityParticleProperty& other) {
|
||||||
|
this->range = other.range;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<ParticleProperty> Clone() const override {
|
||||||
|
return std::make_unique<RandomVelocityParticleProperty>(range);
|
||||||
|
}
|
||||||
|
|
||||||
void OnParticleSpawn(simpleengine::particle::Particle& particle) override {
|
void OnParticleSpawn(simpleengine::particle::Particle& particle) override {
|
||||||
simpleengine::Random<float> rand;
|
simpleengine::Random<float, std::random_device, std::mt19937_64> rand;
|
||||||
sf::Vector2f velocity;
|
sf::Vector2f velocity;
|
||||||
velocity.x = rand.NextInRange(range.min_x, range.max_x);
|
velocity.x = rand.NextInRange<std::uniform_real_distribution<float>>(range.min_x, range.max_x);
|
||||||
velocity.y = rand.NextInRange(range.min_y, range.max_y);
|
velocity.y = rand.NextInRange<std::uniform_real_distribution<float>>(range.min_y, range.max_y);
|
||||||
|
|
||||||
particle.velocity = velocity;
|
particle.velocity = velocity;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,8 +11,6 @@
|
||||||
#include <SFML/Window/Keyboard.hpp>
|
#include <SFML/Window/Keyboard.hpp>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
simpleengine::MovementComponent::MovementComponent(Entity& owning_entity, Game& game, float max_velocity, float acceleration, float deceleration) :
|
simpleengine::MovementComponent::MovementComponent(Entity& owning_entity, Game& game, float max_velocity, float acceleration, float deceleration) :
|
||||||
Component(owning_entity), max_velocity(max_velocity), acceleration(acceleration), deceleration(deceleration) {
|
Component(owning_entity), max_velocity(max_velocity), acceleration(acceleration), deceleration(deceleration) {
|
||||||
|
|
||||||
|
|
|
@ -1,44 +1,75 @@
|
||||||
#include "particle/emitter.h"
|
#include "particle/emitter.h"
|
||||||
|
#include "destructable.h"
|
||||||
|
|
||||||
simpleengine::particle::ParticleEmitter::ParticleEmitter(sf::Texture& texture, sf::Vector2f position, double emit_variance, uint32_t emit_count, uint32_t particle_count, Range2f particle_range, ParticleAttributes attributes, ParticlePropertyVector& properties) : texture(texture), position(position), emit_variance(emit_variance), emit_count(emit_count), particle_count(particle_count), particle_range(particle_range), attributes(attributes), properties(properties) {
|
#include <chrono>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
simpleengine::particle::ParticleEmitter::ParticleEmitter(sf::Texture& texture, sf::Vector2f position, double emit_variance,
|
||||||
|
uint32_t emit_count, uint32_t particle_count, Range2f particle_range, ParticleAttributes attributes,
|
||||||
|
ParticlePropertyVector& particle_properties, EmitterPropertyVector& emitter_properties)
|
||||||
|
: texture(texture), position(position), emit_variance(emit_variance), emit_count(emit_count), particle_count(particle_count),
|
||||||
|
particle_range(particle_range), attributes(attributes), particle_properties(particle_properties), emitter_properties(emitter_properties) {
|
||||||
time.restart();
|
time.restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
void simpleengine::particle::ParticleEmitter::SetProperties(ParticlePropertyVector& properties) {
|
void simpleengine::particle::ParticleEmitter::SetProperties(ParticlePropertyVector particle_properties) {
|
||||||
this->properties = properties;
|
this->particle_properties = std::move(particle_properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
void simpleengine::particle::ParticleEmitter::Update(const float &delta_time) {
|
void simpleengine::particle::ParticleEmitter::Update(const float &delta_time) {
|
||||||
// Update particles and check if they are being destroyed. If they are, destroy them.
|
// Update each particle and remove it from the vector if it is ready to be destroyed.
|
||||||
for (std::vector<simpleengine::particle::Particle>::iterator it = particles.begin(); it != particles.end(); ) {
|
particles.erase(std::remove_if(particles.begin(), particles.end(),
|
||||||
it->Update(delta_time);
|
[&delta_time](simpleengine::particle::Particle& particle){
|
||||||
|
particle.Update(delta_time);
|
||||||
|
|
||||||
if (it->IsDestroying()) {
|
return particle.IsDestroying();
|
||||||
it = particles.erase(it);
|
}), particles.end());
|
||||||
} else {
|
|
||||||
it++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if we can spawn particles with max particle count, also use chance to check if we can.
|
// Check if we can spawn particles with max particle count, also use chance to check if we can.
|
||||||
if (particles.size() < particle_count && random.NextInRange(0, 1) < emit_variance) {
|
if (particles.size() + emit_count <= particle_count && random.NextInRange(0, 1) < emit_variance) {
|
||||||
// Make sure that we don't emit too many particles to go over the max particle count
|
// Make sure that we don't emit too many particles to go over the max particle count
|
||||||
uint32_t emitting_ct = (particles.size() + emit_count > particle_count) ? particle_count - particles.size() : emit_count;
|
//uint32_t emitting_ct = (particles.size() + emit_count > particle_count) ? particle_count - particles.size() : emit_count;
|
||||||
for (uint32_t i = 0; i < emitting_ct; i++) {
|
for (uint32_t i = 0; i < emit_count; i++) {
|
||||||
Particle particle(texture, attributes.start_velocity, attributes.lifetime_ms, attributes.rotation_velocity, properties);
|
|
||||||
|
ParticlePropertyVector particle_properties_clone;
|
||||||
|
for (ParticlePropertyPtr& property : particle_properties) {
|
||||||
|
particle_properties_clone.push_back(std::move(property->Clone()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Particle particle(texture, attributes.start_velocity, std::chrono::milliseconds(attributes.lifetime_ms), attributes.rotation_velocity, std::move(particle_properties_clone));
|
||||||
|
|
||||||
// Offset the position of the particle randomly
|
// Offset the position of the particle randomly
|
||||||
sf::Vector2f new_pos;
|
sf::Vector2f new_pos;
|
||||||
new_pos.x = random.NextInRange(particle_range.min_x, particle_range.max_x);
|
new_pos.x = random.NextInRange(particle_range.min_x, particle_range.max_x);
|
||||||
new_pos.y = random.NextInRange(particle_range.min_y, particle_range.max_y);
|
new_pos.y = random.NextInRange(particle_range.min_y, particle_range.max_y);
|
||||||
new_pos += position;
|
new_pos += position;
|
||||||
particle.GetSprite().setPosition(new_pos);
|
particle.sprite.setPosition(new_pos);
|
||||||
|
|
||||||
particle.GetSprite().setScale(attributes.scale.x, attributes.scale.y);
|
particle.sprite.setScale(attributes.scale.x, attributes.scale.y);
|
||||||
|
|
||||||
|
// Run the emitter properties.
|
||||||
|
for(EmitterPropertyPtr& emitter_property : emitter_properties) {
|
||||||
|
emitter_property->BeforeParticleSpawn(particle);
|
||||||
|
}
|
||||||
|
|
||||||
particles.emplace_back(std::move(particle));
|
particles.emplace_back(std::move(particle));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (particles.size() > 0) {
|
||||||
|
std::chrono::milliseconds avg_particle_lifetime(0);
|
||||||
|
std::chrono::milliseconds max_lifetime(0);
|
||||||
|
for (const Particle& particle : particles) {
|
||||||
|
auto lifetime = std::chrono::duration_cast<std::chrono::milliseconds>(particle.death_point - particle.birth_point);
|
||||||
|
avg_particle_lifetime += lifetime;
|
||||||
|
if (lifetime > max_lifetime) {
|
||||||
|
max_lifetime = lifetime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
avg_particle_lifetime /= particles.size();
|
||||||
|
|
||||||
|
//std::cout << "Particle Count: " << particles.size() << " - Avg. lifetime: " << avg_particle_lifetime.count() << "ms - Max lifetime: " << max_lifetime.count() << "ms" << std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void simpleengine::particle::ParticleEmitter::Render(sf::RenderTarget *target) {
|
void simpleengine::particle::ParticleEmitter::Render(sf::RenderTarget *target) {
|
||||||
|
|
|
@ -1,26 +1,58 @@
|
||||||
#include "particle/particle.h"
|
#include "particle/particle.h"
|
||||||
|
#include "particle/particle_property.h"
|
||||||
|
|
||||||
simpleengine::particle::Particle::Particle(sf::Texture& texture, sf::Vector2f velocity, uint32_t lifetime_ms, float rotation_velocity,
|
#include <chrono>
|
||||||
ParticlePropertyVector properties) : Super(nullptr), velocity(velocity), lifetime_ms(lifetime_ms),
|
#include <iostream>
|
||||||
rotation_velocity(rotation_velocity), properties(properties) {
|
|
||||||
age_clock.restart(); // Start age clock
|
|
||||||
sprite.setTexture(texture);
|
|
||||||
|
|
||||||
// Trigger OnParticleSpawn for particle properities.
|
simpleengine::particle::Particle::Particle(const simpleengine::particle::Particle& other) {
|
||||||
for (ParticlePropertyPtr property : properties) {
|
// From simpleengine::Destructable
|
||||||
property->OnParticleSpawn(*this);
|
this->destroying = other.destroying;
|
||||||
|
|
||||||
|
this->sprite = other.sprite;
|
||||||
|
this->velocity = other.velocity;
|
||||||
|
this->rotation_velocity = other.rotation_velocity;
|
||||||
|
|
||||||
|
// Copy the properties from the other particle. Make sure to empty properties.
|
||||||
|
this->properties.clear();
|
||||||
|
for(const ParticlePropertyPtr& property : other.properties) {
|
||||||
|
std::unique_ptr<ParticleProperty> ptr = property->Clone();
|
||||||
|
this->properties.push_back(std::move(ptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
birth_point = other.birth_point;
|
||||||
|
death_point = other.death_point;
|
||||||
|
}
|
||||||
|
|
||||||
|
simpleengine::particle::Particle& simpleengine::particle::Particle::operator=(Particle other) {
|
||||||
|
// From simpleengine::Destructable
|
||||||
|
this->destroying = other.destroying;
|
||||||
|
|
||||||
|
this->sprite = other.sprite;
|
||||||
|
this->velocity = other.velocity;
|
||||||
|
this->rotation_velocity = other.rotation_velocity;
|
||||||
|
|
||||||
|
// Copy the properties from the other particle. Make sure to empty properties.
|
||||||
|
this->properties.clear();
|
||||||
|
for(const ParticlePropertyPtr& property : other.properties) {
|
||||||
|
std::unique_ptr<ParticleProperty> ptr = property->Clone();
|
||||||
|
this->properties.push_back(std::move(ptr));
|
||||||
|
}
|
||||||
|
|
||||||
|
birth_point = other.birth_point;
|
||||||
|
death_point = other.death_point;
|
||||||
|
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void simpleengine::particle::Particle::Update(const float& delta_time) {
|
void simpleengine::particle::Particle::Update(const float& delta_time) {
|
||||||
// If the particle is older than its lifetime, destroy it.
|
// If death_point has passed then destroy the particle.
|
||||||
if (age_clock.getElapsedTime().asMilliseconds() >= lifetime_ms) {
|
if (std::chrono::high_resolution_clock::now().time_since_epoch() > death_point.time_since_epoch()) {
|
||||||
Super::Destroy();
|
Super::Destroy();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update all properties.
|
// Update all properties.
|
||||||
for (ParticlePropertyPtr property : properties) {
|
for (ParticlePropertyPtr& property : properties) {
|
||||||
property->Update(*this);
|
property->Update(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,10 +63,10 @@ void simpleengine::particle::Particle::Render(sf::RenderTarget* target) {
|
||||||
target->draw(sprite);
|
target->draw(sprite);
|
||||||
}
|
}
|
||||||
|
|
||||||
sf::Sprite& simpleengine::particle::Particle::GetSprite() {
|
std::chrono::microseconds simpleengine::particle::Particle::GetAge() const {
|
||||||
return sprite;
|
return std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now() - birth_point);
|
||||||
}
|
}
|
||||||
|
|
||||||
const sf::Time simpleengine::particle::Particle::GetAge() const {
|
std::chrono::duration<long long, std::ratio<1, 1000000000>> simpleengine::particle::Particle::GetLifetime() const {
|
||||||
return age_clock.getElapsedTime();
|
return death_point - birth_point;
|
||||||
}
|
}
|
Loading…
Reference in New Issue