DSFML icon indicating copy to clipboard operation
DSFML copied to clipboard

VertexArray Particle System Example fix

Open nikibobi opened this issue 9 years ago • 2 comments

The example on dsfml.com Isn't compiling cause of some minor syntax mistakes. I made it work here is the full code:

import std.conv;
import std.random;
import dsfml.graphics;

class ParticleSystem : Drawable
{

    private
    {
        Particle[] m_particles;
        VertexArray m_vertices;
        Time m_lifetime;
        Vector2f m_emitter;
    }


    this(size_t count)
    {
        m_particles = new Particle[count];
        m_vertices = new VertexArray(PrimitiveType.Points, count);
        m_lifetime = seconds(3);
        m_emitter = Vector2f(0, 0);
    }

    void setEmitter(Vector2f position)
    {
        m_emitter = position;
    }

    void update(Time elapsed)
    {
        for (uint i = 0; i < m_particles.length; ++i)
        {
            // update the particle lifetime
            Particle* p = &m_particles[i];
            p.lifetime -= elapsed;

            // if the particle is dead, respawn it
            if (p.lifetime <= Time.Zero)
                resetParticle(i);

            // update the position of the corresponding vertex
            m_vertices[i].position += p.velocity * elapsed.asSeconds();

            // update the alpha (transparency) of the particle according to its lifetime
            float ratio = p.lifetime.asSeconds() / m_lifetime.asSeconds();
            m_vertices[i].color.a = to!ubyte(ratio * 255);
        }
    }

    override void draw(RenderTarget target, RenderStates states)
    {
        // our particles don't use a texture
        states.texture = null;

        // draw the vertex array
        target.draw(m_vertices, states);
    }

    void resetParticle(int index)
    {
        // give a random velocity and lifetime to the particle
        float angle = (uniform!(uint)() % 360) * 3.14f / 180f;
        float speed = (uniform!(uint)() % 50) + 50f;
        m_particles[index].velocity = Vector2f(cos(angle) * speed, sin(angle) * speed);
        m_particles[index].lifetime = milliseconds((uniform!(uint)() % 2000) + 1000);

        // reset the position of the corresponding vertex
        m_vertices[index].position = m_emitter;
    }
}

struct Particle
{
    Vector2f velocity;
    Time lifetime;
}

void main()
{
    // create the window
    auto window = new RenderWindow(VideoMode(512, 256), "Particles");

    // create the particle system
    auto particles = new ParticleSystem(1000);

    // create a clock to track the elapsed time
    Clock clock = new Clock();

    // run the main loop
    while (window.isOpen())
    {
        // handle events
        Event event;
        while (window.pollEvent(event))
        {
            if(event.type == Event.EventType.Closed)
                window.close();
        }

        // make the particle system emitter follow the mouse
        Vector2i mouse = Mouse.getPosition(window);
        particles.setEmitter(window.mapPixelToCoords(mouse));

        // update it
        Time elapsed = clock.restart();
        particles.update(elapsed);

        // draw it
        window.clear();
        window.draw(particles);
        window.display();
    }

}

I found it on the gh-pages branch but it was mixed with html that is probably generated so I don't know if I should make a pull request.

nikibobi avatar Feb 03 '16 15:02 nikibobi

Thanks, this is great.

I'll take care of this, but I'll also start thinking of ways to make it easier for others to work on the website. Maybe put it into its own repository?

You've also now made me want to put the tutorial code into an auto tester. I'll start working on that soon as well.

Jebbs avatar Feb 03 '16 16:02 Jebbs

You could put the code for the tutorials in separate .d files. I think the gh-pages branch is a good place for the website, because its a easy to find standard place.

nikibobi avatar Feb 04 '16 09:02 nikibobi