Problem with simple particle system from "Hello Cinder!" tour

I am currently following the “Hello Cinder” tutorial. I know it’s outdated, but with some help from the “Transition to Cinder 0.9” Guide and the Docs, I had no major problems translating the concepts to the current version so far.

However, now that I am trying to generate particles when clicking the mouse at the curser position with random velocity, it does not work properly at all. I checked the code multiple times, but I can not find my error. I posted it in a github repository here: GitHub - michaelmariaott/FlockingSimulation

This is how it looks for me:

They should spread evenly (well evenly at a random speed…) from the mouse coursor.

I would be grateful for any help.

Just had a cursory glance, but you’re not initializing all your members in Particle, so mIsDead is just getting assigned random garbage memory. If you explicitly set it to false in the constructor or at the declaration site that should fix it.

Thank you, I fixed that now.

Another observation: If I change the number of particles that are created per frame in FlocksApp::update(), the behaviour changes.
1: No particles are created.
2: Particles are created and move as expected, but the spot where they where created stays white as well (but they don’t leave a trail, so the rest of the gl::clear still clears the rest of the background)
3: like 1
4: like 2
5: as seen in the video in my first post
6: like 2, 4
7: like 1,3

You’re iterating over the list incorrectly. For starters i wouldn’t recommend a list in the first place, though I recognise this code from some old flight404 tutorial and I’m sure he had his reasons, but IMO a vector is better suited for this kind of usage.

That said, you can’t iterate with a for loop if you’re going to invalidate the iterator by erasing. Try this:

void ParticleController::update()
{
    auto it = mParticles.begin();
    while ( it != mParticles.end() )
    {
        auto& p = *it;
        if( p.mIsDead )
        {
            it = mParticles.erase(it);
        }else
        {
            p.update();
            it++;
        }
    }
}

A slightly more modern / expressive approach could be:

mParticles.erase( std::remove_if ( mParticles.begin(), mParticles.end(),
                                   [] ( const Particle& p ) { return p.mIsDead; } ),
                                   mParticles.end() );
    
for ( auto& p : mParticles ) p.update();

If you’re on c++20 this gets even nicer with std::erase_if :slight_smile:

Thank you! That fixed it!

I guess I’ll stick to the old school approach for the tutorial and will then switch to a vector.

Im pretty sure that the tutorial I’m following is the one you referenced from flight404, since some defunct links in it point to that server. Did the syntax for lists change so dramatically, that the syntax used in the tutorial does not work anymore?

It still works, If anything c++ is pathologically backwards compatible, but for you?

for ( auto& p : mParticles ) p.update();

is much nicer :slight_smile:

You’re completely render-bound in this problem though, so while container choice is important, your rendering is what’s going to cost you from doing anything high performance right from the jump :slight_smile: