首页 > 解决方案 > SFML 即使在覆盖虚拟绘图功能后也无法绘制对象

问题描述

我创建了一个实现 Drawable 类的卡片类,并且我还重写了函数 draw,但是在我创建卡片对象并尝试使用 window.draw 绘制它之后,它给了我一个错误,说我创建的卡片对象不是可绘制的类型。当我尝试使用 (sf::Drawable)card 将卡片对象转换为可绘制对象时,它说绘制函数未实现。我很困扰。

这是我的代码


#include <iostream>
#include <SFML/Graphics.hpp>

using namespace std;

class Card: public sf::Drawable, sf::Transformable
{
public:

    Card();
    Card(int v, char c);

    void setPos(sf::Vector2f v);
    sf::Vector2f getPos();

private:

    virtual void draw(sf::RenderTarget &window, sf::RenderStates state) const;
    void creatCard();

    sf::RectangleShape cardBackground;
    sf::Text faceValue;
    sf::Sprite suit;
    int _value;
    char _suit;
    sf::Vector2f pos;

};

Card::Card()
{
    _value = 1;
    _suit = 'H';

    creatCard();
}

void Card::draw(sf::RenderTarget &window, sf::RenderStates state) const
{

    window.draw(cardBackground);
    window.draw(faceValue);

}

void Card::creatCard()
{
    sf::Image img;
    sf::Texture texture;

    switch (toupper(_suit)) {
        case 'S':
            if(!img.loadFromFile("card_suits.png"))
                cout << "Fail to load card_suits.png" << endl;
            break;
        case 'H':
            if(!img.loadFromFile("card_suits2.png"))
                cout << "Fail to load card_suits.png" << endl;
            break;
        case 'D':
            if(!img.loadFromFile("card_suits3.png"))
                cout << "Fail to load card_suits.png" << endl;
            break;
        case 'C':
            if(!img.loadFromFile("card_suits4.png"))
                cout << "Fail to load card_suits.png" << endl;
    }

    texture.loadFromImage(img);
    suit.setTexture(texture);

    cardBackground.setSize(sf::Vector2f(300, 600));
    cardBackground.setFillColor(sf::Color::White);
}

int main() {
    sf::RenderWindow window(sf::VideoMode(500, 500, 32), "Test");
    Card card();

    while(window.isOpen())
    {
        sf::Event event;
        while(window.pollEvent(event)){
            if (event.type == sf::Event::Closed){
                window.close();
            }
        }
        window.clear(sf::Color::Black);
        window.draw(card);
        window.display();
    }
    return 0;
}

标签: c++sfml

解决方案


这张牌是平局,但你只是看不到它。SFML 中的 Sprite 使用对 Texture 的引用:

当您设置精灵的纹理时,它在内部所做的只是存储指向纹理实例的指针。因此,如果纹理被破坏或移动到内存中的其他位置,则精灵最终会得到一个无效的纹理指针。

要解决此问题,您需要存储纹理。

参见:https ://www.sfml-dev.org/tutorials/2.5/graphics-sprite.php#the-white-square-problem


推荐阅读