如何绘制存储在矢量中的SFML形状

时间:2015-12-19 17:24:44

标签: c++ vector draw sfml shape

我正在复制游戏"小行星"使用SFML。

为了存储我的所有小行星,我使用了std::vector<sf::ConvexShape>向量,它存储了所有的小行星形状。问题是从矢量中绘制形状。我看了this post并看到我可以用一个迭代器来绘制我的形状(我知道他在那个帖子中使用了精灵,但我认为如果我使用形状则没有任何区别。)

所以我试过了:

for(std::vector<sf::ConvexShape>::iterator it=allShapes.begin();it!= allShapes.end(); ++it){
    window.draw(*it);
}

然后抛出异常,终止我的程序。 仅供参考:以上allShapes包含sf::ConvexShape个形状。

所以问题是:如何绘制存储在矢量中的形状?

全酱:

using namespace std;

class asteroid{
public:
    sf::Vector2f pos;
    double angle;
    void update(sf::Vector2f);
    void create(std::vector<sf::ConvexShape>);
};
/* Will be implemented later
void asteroid::update(sf::Vector2f a){
    pos += a;
};
*/
void asteroid::create(std::vector<sf::ConvexShape> a){
    cout << "Creating..." << endl;
    a.push_back(sf::ConvexShape()); //New asteroid SHAPE
    std::vector<sf::ConvexShape>::iterator tempIt = a.end();
    tempIt->setPointCount(4);

    for(int i = 0; i < tempIt->getPointCount()+1; i++){ //Drawing asteroid
        tempIt->setPoint(i, sf::Vector2f(i*100, i*100));
    }
    tempIt->setFillColor(sf::Color::White);
    cout << "Done!" << endl;
};

int main()
{
    // Init //
    sf::RenderWindow window(sf::VideoMode(200, 200), "SFML works!");

    std::vector<sf::ConvexShape> allShapes; //List of all asteroid SHAPES
    std::vector<asteroid> allAsteroids; //List of asteroid CLASS OBJECTS

    allAsteroids.push_back(asteroid()); //New asteroid CLASS OBJECT

    for(std::vector<asteroid>::iterator it = allAsteroids.begin(); it != allAsteroids.end(); ++it){ //Creating asteroids
        it->create(allShapes);
    }


    // Loop //
    while (window.isOpen())
    {
        // Event //
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();
        }

        // Display //
        window.clear();
        for(std::vector<sf::ConvexShape>::iterator it = allShapes.begin(); it != allShapes.end(); ++it){
            window.draw(*it);
        }
        window.display();
    }

    return 0;
}

1 个答案:

答案 0 :(得分:1)

这里有一些问题......

首先:

0 = Red,
1 = Green,
2 = Blue,

std::vector<sf::ConvexShape>::iterator tempIt = a.end(); tempIt->setPointCount(4); 没有给你一个向量中最后一个元素的迭代器 - 它给你一个#34;元素的迭代器&#34;刚过去,用于边界检查(例如在for循环中)。换句话说,它不指向有效数据,因此第二行无效。你可以在这里使用很多方法;以下两个是最正确的&#34;虽然:

end()

其次:

//with iterators using a.end() - 1
std::vector<sf::ConvexShape>::iterator tempIt = a.end() - 1;
tempIt->setPointCount(4);

//with back, accessing the element directly
a.back().setPointCount(4);

小行星有四个点,所以for(int i = 0; i < tempIt->getPointCount()+1; i++) = 5.这意味着循环执行i = 0,1,2,3和4 - 太多次了。

第三

getPointCount()+1

这条线为每个i运行一次。假设您进行了上述更改,则会产生点(0,0),(100,100),(200,200)和(300,300)。这是一条线,而不是凸形。你需要修改你的公式。直接设置点也是一个很好的选择,因为只有4个设置。

您也可能希望通过引用传递向量,以避免做出任何不必要的副本:

tempIt->setPoint(i, sf::Vector2f(i*100, i*100));