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

Author Topic: How to remove class/sprite  (Read 8294 times)

0 Members and 1 Guest are viewing this topic.

prchakal

  • Full Member
  • ***
  • Posts: 142
    • View Profile
How to remove class/sprite
« on: December 03, 2010, 10:30:26 pm »
Hi,

On my game i have a vector with all my enemies, and i want that when it collide with some other objects, be removed from vector and destroyed.

My vector:

Code: [Select]
static std::vector<Enemy*> *enemies;

What i have tested:

Code: [Select]
void Enemy::remove()
{
//GameObjects::enemies->erase(*this);
//delete this;

for (std::vector<Enemy*>::iterator it = GameObjects::enemies->begin(); it!=GameObjects::enemies->end(); ++it) {
if (((Enemy*)*it) == this)
{
GameObjects::enemies->erase(it);
}
}
}


But allways that i do it, i get a fatal error.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
How to remove class/sprite
« Reply #1 on: December 03, 2010, 10:37:39 pm »
First solution:
Code: [Select]
void Enemy::remove()
{
    GameObjects::enemies->erase(std::find(GameObjects::enemies.begin(), GameObjects::enemies.end(), this));
}


Second one:
Code: [Select]
void Enemy::remove()
{
    for (std::vector<Enemy*>::iterator it = GameObjects::enemies->begin(); it != GameObjects::enemies->end(); ++it)
    {
        if (*it == this)
        {
            GameObjects::enemies->erase(it);
            break;
        }
    }
}
Laurent Gomila - SFML developer

Orwel

  • Full Member
  • ***
  • Posts: 208
    • View Profile
How to remove class/sprite
« Reply #2 on: December 03, 2010, 11:26:33 pm »
You should remove your entity from GameObjects at end of loop. You can use a message for GameObjects as

Code: [Select]

void Enemy::remove()
{
       GameObjects::atRemove(this);
}
....
void GameObjects::atRemove(Enemy *e)
{
       listAtRemove.push_back(e);
}

//Call end of loop, to avoid calls of entity
void GameObjects::removeEnemys()
{
  ....//Remove the objects of the list in GameObjects::enemies
}

prchakal

  • Full Member
  • ***
  • Posts: 142
    • View Profile
How to remove class/sprite
« Reply #3 on: December 04, 2010, 07:29:00 am »
Hi,

I resolve the problem with:

Code: [Select]

for (long x = 0; x < (long)GameObjects::enemies->size(); ++x)
{
Enemy *enemy = GameObjects::enemies->at(x);

if (enemy == this)
{
GameObjects::enemies->erase(GameObjects::enemies->begin() + x);
}

}



When i erase an element from vector, it is all removed from the memory?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
How to remove class/sprite
« Reply #4 on: December 04, 2010, 09:18:32 am »
Quote
I resolve the problem with

Not the best one. You shouldn't ignore our replies ;)

Quote
When i erase an element from vector, it is all removed from the memory?

The pointer is removed from the vector, but the object is not destroyed, you still have to call delete.
Laurent Gomila - SFML developer

Svenstaro

  • Full Member
  • ***
  • Posts: 222
    • View Profile
How to remove class/sprite
« Reply #5 on: December 04, 2010, 01:05:36 pm »
You should really use boost::ptr_vector<Enemy> or std::vector< boost::shared_ptr<Enemy> > instead.

prchakal

  • Full Member
  • ***
  • Posts: 142
    • View Profile
How to remove class/sprite
« Reply #6 on: December 04, 2010, 05:05:15 pm »
Hey laurent,

Sorry man, i dont see your posts.

Now i change my solution for yours, its simply perfect.

Thanks very much, it help a lot.

prchakal

  • Full Member
  • ***
  • Posts: 142
    • View Profile
How to remove class/sprite
« Reply #7 on: December 04, 2010, 05:16:39 pm »
Hi,

The problem is that if im in the loop, and a method in this loop remove an element from the vector, the program crashes, an example:

Code: [Select]

for (std::vector<Enemy*>::iterator it = GameObjects::enemies->begin(); it!=GameObjects::enemies->end(); ++it) {
((Enemy*)*it)->update();
}


The update check the collision and call remove method:

Code: [Select]
if (Collision::PixelPerfectTest(sprite, GameObjects::planet->getSprite()))
{
GameObjects::enemies->erase(std::find(GameObjects::enemies->begin(), GameObjects::enemies->end(), this));
}



When ERASE method is called, the program crashes.

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
How to remove class/sprite
« Reply #8 on: December 04, 2010, 05:33:22 pm »
maybe something about vector::erase
Quote
Erasing N elements causes N destructor calls and an assignment for each of the elements between the insertion point and the end of the sequence. No reallocation occurs, so iterators and references become invalid only from the first element erased through the end of the sequence.
SFML / OS X developer

prchakal

  • Full Member
  • ***
  • Posts: 142
    • View Profile
How to remove class/sprite
« Reply #9 on: December 04, 2010, 07:05:55 pm »
Hi,

What i do to prevent it, is make a loop on this vector objects without look it, an example:

Code: [Select]
for (long x = 0; x < (long)GameObjects::enemies->size(); ++x)
{
    Enemy *enemy = GameObjects::enemies->at(x);
    ...
    enemy->remove();
}


The remove method is:

Code: [Select]
GameObjects::enemies->erase(std::find(GameObjects::enemies->begin(), GameObjects::enemies->end(), this));

So, when i need loop vectors, i will use FOR without iterator, then i can remove without problems.

With this solution my problem is solved.

This is a good practice?

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
How to remove class/sprite
« Reply #10 on: December 04, 2010, 11:53:27 pm »
Yes, it seems good to me.
SFML / OS X developer

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
How to remove class/sprite
« Reply #11 on: December 06, 2010, 08:02:12 pm »
To me, it doesn't.
  • Don't use at() when your indices are correct. In fact, I wouldn't even use it at all, since wrong indices mostly indicate programming mistakes.
  • Why do you cast the size to long? You should rather use an unsigned type like std::size_t.
  • If I see that correctly, you iterate through all enemies, and at each enemy, you search it again from beginning, although you actually know its position in the container. This is unnecessarily complicated.
  • When you allocate your objects dynamically with new, you have to use delete to free their memory.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
How to remove class/sprite
« Reply #12 on: December 06, 2010, 11:19:56 pm »
It seems to me I didn't read deep enough.  :roll:

Good advices here!
SFML / OS X developer

prchakal

  • Full Member
  • ***
  • Posts: 142
    • View Profile
How to remove class/sprite
« Reply #13 on: December 09, 2010, 09:46:43 pm »
So nexus, what you recommend?

prchakal

  • Full Member
  • ***
  • Posts: 142
    • View Profile
How to remove class/sprite
« Reply #14 on: December 09, 2010, 10:05:24 pm »
To delete the class from memory, i invoke:

Code: [Select]
delete this;

And now the destructor is called.