SFML community forums

Help => Graphics => Topic started by: amited on September 12, 2018, 10:55:31 pm

Title: Delete sprite from vector
Post by: amited on September 12, 2018, 10:55:31 pm
I want to delete sprite form my vector but all function dont work xd... and return this error:
(https://i.imgur.com/OaGckDA.jpg)
I saw all topics with similar like my but any dont work for me ;/
Code:
void Weapon::Draw(RenderWindow &window, Map &m)
{
        iterator = 0;
        for (i = pociski.begin(); i < pociski.end(); i++)
        {
                pocisk = *i;
                pocisk.move(Velocity[iterator]);
                pociski[iterator] = pocisk;
                for (m.i = m.walls.begin(); m.i < m.walls.end(); m.i++)
                {
                        if (areColliding(pocisk, *m.i, 2))
                        {
                                // bullet touch wall
                                 pociski.erase(i);
                        }
                }
                window.draw(*i);
                iterator++;
        }
}
 
Title: Re: Delete sprite from vector
Post by: Stauricus on September 13, 2018, 12:31:39 pm
the error link seems dead
Title: Re: Delete sprite from vector
Post by: amited on September 13, 2018, 02:12:54 pm
Look now
Title: Re: Delete sprite from vector
Post by: eXpl0it3r on September 13, 2018, 02:49:16 pm
This is a general C++ question and better suited for StackOverflow or similar.

If you erase an element from a vector you're iterating over, you need to account for that. Google "erase iterator in for loop" or similar.
Title: Re: Delete sprite from vector
Post by: amited on September 13, 2018, 09:55:21 pm
Thanks for answer but i tested all in google answers and any dont work ;/ Can you made a vector of sprites and erase some of object? Or redo my code? Maybe im doing some wrong but i dont thing so.
Title: Re: Delete sprite from vector
Post by: Gleade on September 14, 2018, 02:09:24 am
eXpl0it3r told you what you're doing wrong:

Quote
If you erase an element from a vector you're iterating over, you need to account for that.

Perhaps:
Code: [Select]
i = pociski.erase(i);
Title: Re: Delete sprite from vector
Post by: amited on September 14, 2018, 02:06:39 pm
Okay, these code do not work:
void Weapon::Draw(RenderWindow &window, Map &m)
{
        iterator = 0;
        for (i=begin(pociski);i!=end(pociski);)
        {
                pocisk = *i;
                pocisk.move(Velocity[iterator]);
                pociski[iterator] = pocisk;
                for (vector<Sprite>::iterator j = m.walls.begin(); j < m.walls.end(); j++)
                {
                        Sprite sciana = *j;
                        if (areColliding(pocisk, sciana, 2))
                        {
                                i = pociski.erase(i);
                        }
                }
                window.draw(*i);
                iterator++;
        }
}

        for (;i!=pociski.end();)
        {
                pocisk = *i;
                pocisk.move(Velocity[iterator]);
                pociski[iterator] = pocisk;
                for (vector<Sprite>::iterator j = m.walls.begin(); j < m.walls.end(); j++)
                {
                        Sprite sciana = *j;
                        if (areColliding(pocisk, sciana, 2))
                        {
                                i = pociski.erase(i);
                        }
                        else
                        {
                                ++i;
                        }
                }
                window.draw(*i);
                iterator++;
        }

        for (i=pociski.begin();i!=pociski.end();)
        {
                pocisk = *i;
                pocisk.move(Velocity[iterator]);
                pociski[iterator] = pocisk;
                for (vector<Sprite>::iterator j = m.walls.begin(); j < m.walls.end(); j++)
                {
                        Sprite sciana = *j;
                        if (areColliding(pocisk, sciana, 2))
                        {
                                vector<Sprite>::iterator curr = i++;
                                pociski.erase(curr);
                        }
                        else
                        {
                                ++i;
                        }
                }
                window.draw(*i);
                iterator++;
        }

        for (auto i = pociski.begin(); i != pociski.end();)
        {
                pocisk = *i;
                pocisk.move(Velocity[iterator]);
                pociski[iterator] = pocisk;
                for (vector<Sprite>::iterator j = m.walls.begin(); j < m.walls.end(); j++)
                {
                        Sprite sciana = *j;
                        if (areColliding(pocisk, sciana, 2))
                        {
                                i = pociski.erase(i);
                        }
                        else
                        {
                                i++;
                        }
                }
                window.draw(*i);
                iterator++;
        }

It's answers by googe when type "c++ erase vector iterator in loop" Any dont work. Any other sugestions? ;/
Title: Re: Delete sprite from vector
Post by: Laurent on September 14, 2018, 06:16:57 pm
This is not a code issue, it's your logic that is flawed. You update, collide and draw sprites within the same loop. And you draw even those that have been erased. You need to split your code into an update loop, and a draw loop. And then, in the update loop, use the idiomatic way to erase sprites in order to avoid issues.

void Weapon::Draw(RenderWindow &window, Map &m)
{
    // update loop (should not be in a Draw function...)
    for (auto it = pociski.begin(); it != pociski.end(); )
    {
        it->move(Velocity[iterator]); // this won't compile with this code, you should store velocities in the same container as sprites (in a struct that aggregates both, for example)

        bool collides = false;
        for (auto& wall : m.walls)
        {
            if (areColliding(*it, wall, 2))
            {
                collides = true;
                break;
            }
        }

        if (collides)
            it = pociski.erase(it);
        else
            ++it;
    }

    // draw loop
    for (const auto& pocisk : pociski)
        window.draw(pocisk);
}

And please avoid declaring local variables in a wider scope.