Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Delete sprite from vector  (Read 3614 times)

0 Members and 1 Guest are viewing this topic.

amited

  • Newbie
  • *
  • Posts: 9
    • View Profile
    • Email
Delete sprite from vector
« 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:

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++;
        }
}
 
« Last Edit: September 13, 2018, 02:12:24 pm by amited »

Stauricus

  • Sr. Member
  • ****
  • Posts: 369
    • View Profile
    • A Mafia Graphic Novel
    • Email
Re: Delete sprite from vector
« Reply #1 on: September 13, 2018, 12:31:39 pm »
the error link seems dead
Visit my game site (and hopefully help funding it? )
Website | IndieDB

amited

  • Newbie
  • *
  • Posts: 9
    • View Profile
    • Email
Re: Delete sprite from vector
« Reply #2 on: September 13, 2018, 02:12:54 pm »
Look now

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
Re: Delete sprite from vector
« Reply #3 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.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

amited

  • Newbie
  • *
  • Posts: 9
    • View Profile
    • Email
Re: Delete sprite from vector
« Reply #4 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.

Gleade

  • Jr. Member
  • **
  • Posts: 55
    • View Profile
Re: Delete sprite from vector
« Reply #5 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);

amited

  • Newbie
  • *
  • Posts: 9
    • View Profile
    • Email
Re: Delete sprite from vector
« Reply #6 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? ;/

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Delete sprite from vector
« Reply #7 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.
Laurent Gomila - SFML developer