Tak się składa że coś takiego napisałem parę dni temu. System przystosowany do silnika ale jak się porywasz na system cząstek to pewnie dasz radę przerobić
.cpp
#include "../../headers/TextureParticle.h"
TextureParticle::TextureParticle(string path, unsigned int count, int _lifeTime, int _size, int _status):
m_particles(count),
m_vertices(sf::Quads, count*4),
m_lifetime(sf::milliseconds(lifeTime)),
m_emitter(0, 0),
status(_status),
size(_size),
lifeTimeDifference(1.f),
gravityAcceleration(0.f),
m_speed( 50.f , 100.f ),
m_angel( 0, 360),
justCreated( true ),
lifeTime(_lifeTime),
isGravityRequied( false ),
activity( Activity::Active )
{
if(!m_texture.loadFromFile(PATH + path))
{
cout << "Texture missing! " << endl;
exit(0);
}
sf::Vector2u textureSize = m_texture.getSize();
for(int i=0; i<count-1; i++)
{
m_vertices[(3*i)+i%4].texCoords = sf::Vector2f(0, 0);
m_vertices[(3*i)+1+i%4].texCoords = sf::Vector2f( textureSize.x, 0);
m_vertices[(3*i)+2+i%4].texCoords = sf::Vector2f( textureSize.x, textureSize.y );
m_vertices[(3*i)+3+i%4].texCoords = sf::Vector2f(0, textureSize.y );
}
}
void TextureParticle::Update(float elapsed)
{
for (size_t i = 0; i < m_particles.size(); ++i)
{
Particle& p = m_particles[i];
sf::Time dTime = sf::seconds(elapsed);
p.lifetime -= dTime;
int currentIndex = ( 3 * i ) + ( i % 4 );
if (p.lifetime <= sf::Time::Zero)
{
if(status == STATUS::Repeat)
{
resetParticle(i);
continue;
}
else if(status == STATUS::Once)
{
}
}
//float TTL = ((p.lifetime.asSeconds())/p.beginTime.asSeconds()*100);
if(isGravityRequied)
{
sf::Vector2f gravity(0, gravityAcceleration);
m_vertices[currentIndex].position += p.velocity * dTime.asSeconds() + gravity * dTime.asSeconds();
m_vertices[currentIndex + 1].position += p.velocity * dTime.asSeconds() + gravity * dTime.asSeconds() ;
m_vertices[currentIndex + 2].position += p.velocity * dTime.asSeconds() + gravity * dTime.asSeconds();
m_vertices[currentIndex + 3].position += p.velocity * dTime.asSeconds() + gravity * dTime.asSeconds() ;
}
else
{
m_vertices[currentIndex].position += p.velocity * dTime.asSeconds();
m_vertices[currentIndex + 1].position += p.velocity * dTime.asSeconds();
m_vertices[currentIndex + 2].position += p.velocity * dTime.asSeconds();
m_vertices[currentIndex + 3].position += p.velocity * dTime.asSeconds();
}
}
}
void TextureParticle::draw(sf::RenderTarget& target, sf::RenderStates states) const
{
if(activity == Activity::Active)
{
states.transform *= getTransform();
states.texture = &m_texture;
target.draw( m_vertices, states );
}
}
void TextureParticle::resetParticle( size_t index )
{
float angle = ( m_angel.x + ( rand() % int (m_angel.y) ) ) * 3.1415f / 180.f;
float speed = ( rand() % int (abs( m_speed.y - m_speed.x )) ) + m_speed.x;
int currentIndex = ( 3 * index ) + (index % 4);
m_particles[index].velocity = sf::Vector2f(( cos(angle)) * speed, ( sin(angle)) * speed);
m_particles[index].lifetime = sf::milliseconds( ( rand() % int(lifeTime) ) + lifeTimeDifference );
m_particles[index].beginTime = m_particles[index].lifetime;
// reset the position of the corresponding vertex
m_vertices[currentIndex].position = m_emitter;
m_vertices[currentIndex + 1].position = sf::Vector2f(( size + m_emitter.x ), ( m_emitter.y ));
m_vertices[currentIndex + 2].position = sf::Vector2f(( size + m_emitter.x ), ( size + m_emitter.y ));
m_vertices[currentIndex + 3].position = sf::Vector2f(( m_emitter.x ), ( size + m_emitter.y ));
}
// If object is not currently in use deleting from container.
bool TextureParticle::Destroy()
{
if(destroyQueue == false)
{
return false;
}
else
{
destroyQueue = false;
return true;
}
}
void TextureParticle::setActive( int _activity )
{
if(_activity == Activity::Active)
{
activity = _activity;
return;
}
if(_activity == Activity::Disactive)
activity = _activity;
}
void TextureParticle::outOfContrainet()
{
destroyQueue = true;
}
void TextureParticle::setEmitter( sf::Vector2f position )
{
m_emitter = position;
}
void TextureParticle::setlifeTimeDifference( int time )
{
if(time == 0)
time = 1;
lifeTimeDifference = time;
}
void TextureParticle::setGravity( float acceleration )
{
if(acceleration == 0)
return;
gravityAcceleration = acceleration;
}
void TextureParticle::setGravityState( bool isRequied )
{
if(isRequied == true)
isGravityRequied = true;
else
isGravityRequied = false;
}
void TextureParticle::setSpeed(float x, float y)
{
sf::Vector2f speed( x, y);
m_speed = speed;
}
void TextureParticle::setAngel(float x, float y)
{
sf::Vector2f angel( x, y);
m_angel = angel;
}
.h
#include <SFML/Graphics.hpp>
#include <iostream>
#include <vector>
#include <conio.h>
#include "Updateable.h"
#define PATH "system\\data\\particle\\"
#define SHADERS_P "system\\data\shaders\\"
using namespace std;
class TextureParticle : public sf::Drawable, public sf::Transformable, public Updateable
{
public:
TextureParticle(string path = "", unsigned int count = 100, int lifeTime = 100, int _size = 32, int _status = STATUS::Once);
protected: // Protected functions
virtual void Update( float ); // Updating state
public:
void setEmitter(sf::Vector2f ); // The position when all particles will be created
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const; // Virtual funcion based on sf::Drawable
void setActive(int /* if true update state */ );
void outOfContrainet(); // If u do not want to continue updating data in container u can use this function
void setSpeed(float, float); // Set new particle speed left min right max
void setAngel(float, float); // Set an angel for direction of particles.
void setGravity(float); // Set gravity acceleration pixel per second
void setlifeTimeDifference( int ); // If you want to make some of the particle from 0 to longer for this value set some number
void setGravityState( bool ); // Decide to run on gravity or leave it of if u dont need
private:// Private functions
virtual bool Destroy(); // Function charge of delete object from memory when bool in constructor is TRUE
void resetParticle( size_t index );
private: // Private variables
struct Particle // Particle structs
{
sf::Vector2f velocity; // Direction of updating position of particle
sf::Time lifetime; // How long particle will be exit
sf::Time beginTime; // The time randed after reset id demend how long we have to draw it.
};
vector < Particle > m_particles; // Contrainer of particles
sf::VertexArray m_vertices;
sf::Time m_lifetime;
sf::Vector2f m_emitter;
sf::Texture m_texture;
sf::Vector2f m_speed;
sf::Vector2f m_angel;
bool destroyQueue; // If true delete from contrainer
bool justCreated; // Create new particles data if true
bool isGravityRequied; // The same in name
int activity; // demend if it suppose to be draw or no
int status; // Repeat all time or just once
int size; // Size of particles
int lifeTimeDifference; //
int lifeTime;
float gravityAcceleration;
};