SFML community forums

Help => General => Topic started by: Finn on October 05, 2010, 08:44:11 pm

Title: Better way of enemy-list
Post by: Finn on October 05, 2010, 08:44:11 pm
Hey!
I have some problems with my enemylist. All enemys are saved in a std::vector. So...I can't change them on the fly. I have to do:
Code: [Select]

std::vector<enemy>::iterator It;
enemy Enemy;
for(It = List.begin(), int i = 0; i < List.size(); i++, It++)
{
    Enemy = List.at(i);
    List.erase(It);

    //change things like position and stuff...
   
   List.push_back(It);
}


But this produces some lag for the enemys. So it seems!
What's a better way of doin' this?
thx,
Finn
Title: Better way of enemy-list
Post by: NoIdea on October 05, 2010, 08:50:38 pm
if you are going to delete/add enemies very often and you almost never get them through there index (0,1,2,3,...), use a std::list. However, I do not think it should improve performance so much.
Title: Better way of enemy-list
Post by: Spidyy on October 05, 2010, 10:46:47 pm
If you use an iterator, access them through your iterator :
Code: [Select]

for(std::vector<Ennemy>::iterator It = List.begin(); It != List.end(); ++It)
{
    //change things like position and stuff...
    It->GetPosition();
    It->SetLife(20);
}


or else, access them directly through the index
Code: [Select]
for(int i = 0; i < List.size(); i++)
{
List[i].GetPosition();
List[i].SetLife(20);
}


With your solution, you recreate an ennemy at each loop of your for, no strange it's lagging.
Title: Better way of enemy-list
Post by: Canadadry on October 05, 2010, 10:49:08 pm
Why don't you store a pointer to your enemy instead of the enemy. That way you could change the enemy propreties without changing the pointer.
Title: Better way of enemy-list
Post by: panithadrum on October 05, 2010, 11:00:07 pm
Accesing through the iterator is the way (Spiddy's solution)
Title: Better way of enemy-list
Post by: Finn on October 06, 2010, 07:20:53 am
So changes will take place without having to refill the vector?
Title: Better way of enemy-list
Post by: WitchD0ctor on October 06, 2010, 08:03:15 am
yes
Title: Better way of enemy-list
Post by: panithadrum on October 06, 2010, 12:21:38 pm
Of course. The iterator is not read-only. It is an "accessor" to the elements.
If you need a read-only iterator (for example inside a const function) you must use const_iterator.
Title: Better way of enemy-list
Post by: Finn on October 06, 2010, 12:56:55 pm
Damn. If I knew that earlier I I haven't had that problems :D
Title: Re: Better way of enemy-list
Post by: Nexus on October 06, 2010, 08:07:39 pm
Quote from: "Finn"
Code: [Select]
std::vector<enemy>::iterator It;
enemy Enemy;
for(It = List.begin(), int i = 0; i < List.size(); i++, It++)
{
    Enemy = List.at(i);
    List.erase(It);

    //change things like position and stuff...
   
   List.push_back(It);
}
You don't need the index, just dereference the iterator. Besides, use pre- instead of post-increment (++It), as it avoids unnecessary copies. And I would declare the iterator inside the for loop's header to keep the scope local.

By the way, I would avoid at() since out-of-range access is almost always a programming mistake that can't be handled by exceptions. Use the operator[] which is faster and checks with assert (given you are using a reasonable standard library implementation).