开始使用课程

时间:2018-03-17 09:21:51

标签: c++ c++11 sfml

我必须使用课程画一朵花(" cvijet"克罗地亚语)。这是代码:

#include <SFML/Graphics.hpp>
#include "Cvijet.h"

int main()
{
    sf::RenderWindow window(sf::VideoMode(400, 400), "Hello, SFML world!");
    window.setFramerateLimit(60);
    Cvijet cvijet(&window);

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

        window.clear();
        cvijet.draw();
        window.display();
    }

    return 0;
}

我不明白的是我应该如何开始绘画(.draw()开始绘画,但如果这条线不起作用则没有任何反应),使用这一行:

Cvijet cvijet(&window);

它需要一个指向窗口的指针。我已经在.h文件中实现了这样的构造函数:

Cvijet(sf::RenderWindow *window);

这应该如何运作?我该如何在.cpp文件中实现它? 我真的不知道如何解释这个问题,因为我不知道这条线应该做什么,所以如果问题不好就很抱歉。

期待一些帮助! :)

1 个答案:

答案 0 :(得分:0)

我采取不同的方法。 SFML甚至提供了基类来实现这样的简单方法:sf::Drawablesf::Transformable

实现虚拟成员的最小类看起来像这样:

class Flower : public sf::Drawable, public sf::Transformable {
public:
    void draw(sf::RenderTarget &target, sf::RenderStates states) const {
        // Apply the transform and draw our flower
    }
};

因此,你只需要以一种有意义的方式填充空白,并基本上画出你的花。

draw()的简短版本:

  • 应用您的转换(这是可选的,但允许您致电setPosition()和类似成员)。
  • 绘制自定义形状,多边形等

听起来很简单?是的,因为它是。

如果您想尝试自己,请立即停止阅读,给它一个旋转。如果你仍然无法弄清楚,请继续一个简单的例子。如果你这样做,请尝试理解代码,而不是仅仅复制所有内容并完成。

对于这个例子,我将使用sf::CircleShape的几个实例,但你基本上可以使用你想要的任何东西。简单的形状,纹理多边形,精灵等等。它总是一样的。

这是一个完整的例子,而不是一步一步地进行:

#include <SFML/Graphics.hpp>
#include <vector>
#include <math.h>

class Flower : public sf::Drawable, public sf::Transformable {
private:
    std::vector<sf::CircleShape> mParts;

public:
    Flower(sf::Color color, unsigned int petals = 8, float centerRadius = 10, float petalRadius = 10) :
        mParts(petals + 1) // Resize the vector for all our plant parts
    {
        // Setup the flower's center
        mParts[0].setRadius(centerRadius);
        mParts[0].setFillColor(sf::Color::Yellow);
        mParts[0].setOrigin(centerRadius, centerRadius);
        mParts[0].setOutlineColor(sf::Color::Black);
        mParts[0].setOutlineThickness(1);

        // No petals? Avoid a division by 0
        if (!petals)
            return;

        // Determine the angle between the individual petals
        float delta = 2 * 3.1415 / petals;

        // Iterate over all petals and set them up
        for (unsigned int i = 1; i <= petals; ++i) {

            // Using a reference here for readability
            sf::CircleShape &petal(mParts[i]);

            petal.setRadius(petalRadius);
            petal.setFillColor(color);
            petal.setOrigin(petalRadius + (petalRadius + centerRadius) * std::sin(i * delta), petalRadius + (petalRadius + centerRadius) * std::cos(i * delta));
            petal.setOutlineColor(sf::Color::Black);
            petal.setOutlineThickness(1);
        }
    }

    void draw(sf::RenderTarget &target, sf::RenderStates states) const {

        // Apply our own transform (from sf::Transformable)
        states.transform *= getTransform();

        // Draw the parts
        for (const sf::CircleShape &part : mParts)
            target.draw(part, states);
    }
};

int main(int argc, char **argv) {
    sf::RenderWindow window(sf::VideoMode(256, 256), "Flowers");

    Flower flower1(sf::Color::Red, 5, 20, 20);
    flower1.setPosition(sf::Vector2f(75, 75));
    Flower flower2(sf::Color::Blue, 8, 10, 10);
    flower2.setPosition(sf::Vector2f(200, 100));

    while (window.isOpen()) {
        sf::Event event;
        // Your typical event loop
        while (window.pollEvent(event)) {
            switch (event.type) {
                case sf::Event::Closed:
                    window.close();
                    break;
            }
        }

        // Draw and display our flowers
        window.clear();
        window.draw(flower1);
        window.draw(flower2);
        window.display();
    }

    return 0;
}

生成的程序将显示如下窗口:

Example Screenshot

请注意,这不是最完美的解决方案(因为我们每个花使用几个绘图调用),但根据您的使用情况等,这应该绰绰有余。

仍然要做最初的想法(因为它显然是一项要求),你可以这样做:

class Cvijet {
private:
    sf::RenderWindow *mWindow;
    std::vector<sf::CircleShape> mParts;
public:
    Cvijet(sf::RenderWindow *window) : mWindow(window) {
        // Setup mParts similar to the example above
    }

    void draw() const {
        sf::RenderStates state;
        // Apply the proper transform for the flower position

        // Draw the flower parts
        for (const sf::CircleShape &part : mParts)
            mTarget->draw(part, state);
    }
}

分割标题和实现:暂时不要担心。只在您的标题中实现该类,只要它不在多个其他文件中使用,这不应该是一个问题。

一旦完成并正常工作,您只需将实现移动到自己的cpp文件即可。最新的代码片段会变成这样的东西(为了简单起见,我省略了标题,包括警卫等):

<强> cvijet.hpp

class Cvijet {
private:
    sf::RenderWindow *mWindow;
    std::vector<sf::CircleShape> mParts;
public:
    Cvijet(sf::RenderWindow *window);
    void draw() const;
}

<强> cvijet.cpp:

#include "cvijet.hpp"

Cvijet::Cvijet(sf::RenderWindow *window) : mWindow(window) {
    // Setup mParts similar to the example above
}

void Cvijet::draw() const {
    sf::RenderStates state;
    // Apply the proper transform for the flower position

    // Draw the flower parts
    for (const sf::CircleShape &part : mParts)
        mTarget->draw(part, state);
}