SFML Вектор спрайтов и ошибка столкновения спрайтов

#c #sfml

#c #sfml

Вопрос:

Я создаю игру на C и SFML, и у меня с этим серьезная проблема. Что я хочу сделать, так это то, что когда мой игрок (он же человеческий персонаж) сталкивается с одним элементом, тогда только этот элемент должен быть удален. Например, когда игрок сталкивается с элементом ‘chicken’, тогда должен быть удален только элемент ‘chicken’, а не другие элементы. Однако, когда я запускаю свою программу и когда проигрыватель сталкивается с элементом «цыпленок», все остальные элементы удаляются. И я не знаю почему. Мне действительно нужна ваша помощь. Несмотря на мой плохой английский, спасибо за чтение!

И вот мой код :

      #include <SFML/Graphics.hpp>
     ...
     using namespace std;
     using namespace sf;
     ...

     int main () {
     ...

     //item Sprites

     Texture bombTex;
     bombTex.loadFromFile("images/bomb.png");
     Sprite bomb;
     ...
     Texture bomb2Tex;
     bomb2Tex.loadFromFile("images/bomb_2.png");
     Sprite bomb_2;
     ...
     Texture cakeTex;
     cakeTex.loadFromFile("images/cake.png");
     Sprite cake;
     ...
     Texture coffeeTex;
     coffeeTex.loadFromFile("images/coffee.png");
     Sprite coffee;
     ...
    Texture chickenTex;
    chickenTex.loadFromFile("images/chicken.png");
    Sprite chicken;
    ...
    Texture pizzaTex;
    pizzaTex.loadFromFile("images/pizza.png");
    Sprite pizza;

    //item array (I made an item array to display amp; render various items in the game screen.)
    Sprite item[10];
    item[0] = bomb;
    item[1] = coffee;
    item[2] = bomb_2;
    item[3] = chicken;
    item[4] = pizza;

    std::vector<Sprite> items;
    items.push_back(Sprite(item[4]));

    ...

   while (window.isOpen())
  {   ...
      ...
    for (size_t i = 0; i < items.size(); i  )
    {
        if (humanArr[index].getGlobalBounds().intersects(item[i].getGlobalBounds())) 
        //humanArr[index] is a player Sprite.
        {
            ...
            items.erase(items.begin());
        }
     }
    ...
   window.clear();
    ...
   for (size_t i = 0; i < items.size(); i  )
        {
            window.draw(item[i]);
        }

    ...
   window.display();
   }
   return 0;
}
  

Ответ №1:

     for (size_t i = 0; i < items.size(); i  )
    {
        // first problem: you are accessing item[i] instead of items[i]
        if (humanArr[index].getGlobalBounds().intersects(item[i].getGlobalBounds())) 
        {
            ...
            items.erase(items.begin()); // <---------- second problem is here
        }
     }
  

Вы не удаляете элемент, над которым выполняете итерацию, вместо этого вы удаляете первый элемент. Вы также обращаетесь к неправильному массиву. Я рекомендую изменить имя item , чтобы избежать этого в будущем. Вот как вы решаете эту проблему:

     // Pull human bounds out of the loop so that we dont' access them each
    // iteration.
    const humanBounds = humanArr[index];
    for (auto iter = items.begin(); iter != items.end();)
    {
        if (humanBounds.intersects(iter->getGlobalBounds()))
        {
            iter = items.erase(iter); 
        }
        else
        {
              iter;
        }
    }
  

Смотрите std::vector::erase для получения дополнительной информации.

Комментарии:

1. Спасибо за ваш ответ! Я действительно ценю это. Однако теперь это хорошо работает с первым столкнувшимся элементом, я имею в виду, что первый элемент хорошо стирается при столкновении с плеером, но это не работает со следующими элементами. Точно, следующие элементы не удаляются, даже если они сталкиваются с плеером. Кроме того, это вызывает ошибку исключения в последнем коде: ‘for (size_t i = 0; i < items.size(); i ) { window.draw(item[i]); }’ В любом случае, спасибо за ваш вклад в мой проект!