문제

I am making this space based shooter using SFML and MS Visual Studio 10 in C++. So, my enemy sprites are declared in a std::list. In order to keep them coming indefinitely, I used a large size for the list. But, this affects performance and will eventually terminate after a period of time. So, instead I opted to push_back() an element into the list every time I erase an element, so as to keep the size of the list constant and spawn enemies indefinite number of times. This does not affect performance. However, every time an enemy sprite is erased, a new sprite is being generated at position (0,0) i.e. top left corner. So, in order to randomly generate their positions off-screen, I used the same RNG I used to initialize their positions at the start of the program. Now, they are being randomly generated off-screen but the whole list is being erased and a new list is being generated again. Here's my code:

std::list<sf::Sprite>::iterator enemyit = enemy.begin(), next;
    while(enemyit != enemy.end())
    {
        next = enemyit;
        next++;
        if(enemyit->getGlobalBounds().intersects(player.getGlobalBounds()))
        {
            enemy.erase(enemyit);
            enemy.push_back(sf::Sprite(enemytex));
            srand(time(NULL));
            float y = -200;
            for(std::list<sf::Sprite>::iterator enemyit = enemy.begin(); enemyit != enemy.end(); enemyit++)
            {
                float x = rand() % dist + wastage;
                enemyit->setPosition(x, y);
                y = y - enemyit->getGlobalBounds().height * 2;
            }
        }
        enemyit = next;
    }

Obviously, it's the for loop. I am iterating the whole list. How do I change it so that only one element is generated when only one is erased? What is the condition I should set? I've tried everything to the best of my knowledge, but nothing. Please help me on this.

도움이 되었습니까?

해결책

first of all, your actual code would give you a lot of problems with that loops ( while and for ), and adding or removing items of a list while you are using iterators.

The best solution to your problem is to do a first loop to check all the enemies that have destroyed, and after the check, make a loop to generate them.

std::list<sf::Sprite>::iterator enemyit = enemy.begin(), next;
int erasedEnemies = 0;
while(enemyit != enemy.end())
{
    next = enemyit;
    next++;
    if(enemyit->getGlobalBounds().intersects(player.getGlobalBounds()))
    {
        enemy.erase(enemyit);
        ++erasedEnemies;
    }
    enemyit = next;
}

for( int i = 0; i < erasedEnemies; ++i )
{
    sf::Sprite tempSprite(enemytex);    
    srand(time(NULL));
    float y = -200;
    float x = rand() % dist + wastage;
    tempSprite.setPosition(x, y);
    y = y - tempSprite.getGlobalBounds().height * 2;
    enemy.push_back(tempSprite);
}

Hope it helps you.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top