• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Fire particles

Object Storage Arubacloud
0 głosów
91 wizyt
pytanie zadane 14 grudnia 2015 w C i C++ przez GameProgrammer Obywatel (1,140 p.)

Pracuję na SFML2 i trudzę się z efektami cząsteczek. Czy możecie mi pomóc w osiągnięciu podobnego efektu ognia jak na obrazku?

2 odpowiedzi

0 głosów
odpowiedź 14 grudnia 2015 przez Patrycjerz Mędrzec (192,320 p.)
Po prostu generujesz pojedyncze cząstki z jednego punktu, o różnych wektorach prędkości i czasie żywotu oraz uwzględniasz siłę grawitacji.
0 głosów
odpowiedź 14 grudnia 2015 przez arek01996 Stary wyjadacz (12,100 p.)

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;

};



 

Podobne pytania

0 głosów
1 odpowiedź 170 wizyt
pytanie zadane 30 sierpnia 2019 w JavaScript przez Majonez.exe Gaduła (3,490 p.)
0 głosów
1 odpowiedź 113 wizyt
pytanie zadane 17 kwietnia 2018 w HTML i CSS przez Śwież4k Bywalec (2,570 p.)
+2 głosów
0 odpowiedzi 216 wizyt
pytanie zadane 25 września 2017 w Nasze poradniki przez Kacper Cieluch Nowicjusz (140 p.)

92,568 zapytań

141,420 odpowiedzi

319,622 komentarzy

61,954 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...