首页 > 解决方案 > 白色方形 SFML

问题描述

我在尝试显示带纹理的按钮时遇到了SFML C++的白色方块问题。我有一个ImageButton.hwhich 继承自Button.h. 纹理已成功加载(在调试器中检查)。但最后,我看到了一个白色的方块。如何解决?

按钮.h

#ifndef BUTTON_H
#define BUTTON_H

#include<SFML/Graphics.hpp>

class Button
{
public:
    Button();
    Button(sf::Vector2f size, sf::Vector2f pos,sf::Color outlineColor, float sizeOutline);
    void virtual draw(sf::RenderWindow* w) = 0;
protected:
    sf::RectangleShape frame;
};



#endif // !BUTTON_H

按钮.cpp

#include "Button.h"

Button::Button()
{
}

Button::Button(sf::Vector2f size, sf::Vector2f pos,sf::Color outlineColor, float sizeOutline)
{
    frame.setPosition(pos);
    frame.setSize(size);
    frame.setOutlineColor(outlineColor);
    frame.setOutlineThickness(sizeOutline);
}


图像按钮.h

#ifndef IMAGE_BUTTON_H
#define IMAGE_BUTTON_H

#include"Button.h"

class ImageButton : public Button
{
public:
    ImageButton();
    ImageButton(sf::Vector2f size, sf::Vector2f pos, sf::Color outlineColor, float sizeOutline, std::string path);
    void draw(sf::RenderWindow* w);
private:
    sf::Texture backTexture;
    sf::Sprite background;
};


#endif // !IMAGE_BUTTON_H

图像按钮.cpp

#include "ImageButton.h"

ImageButton::ImageButton()
{
}

ImageButton::ImageButton(sf::Vector2f size, sf::Vector2f pos, sf::Color outlineColor, float sizeOutline, std::string path)
    : Button(size,pos,outlineColor,sizeOutline)
{
    
    backTexture.loadFromFile(path, sf::IntRect(sf::Vector2i(pos.x,pos.y),sf::Vector2i(size.x,size.y)));
    backTexture.setSmooth(true);
    background.setTexture(backTexture);
    background.setPosition(pos);
}

void ImageButton::draw(sf::RenderWindow* w)
{
    w->draw(this->background);
    w->draw(this->frame);
}

程序.h

#ifndef PROGRAMM_H
#define PROGRAMM_H

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


class programm
{
public:
    programm();
    void run();
private:
    ImageButton b;
    sf::RenderWindow* window;
    sf::Event e;
    void render();
    void update();

};
#endif // !PROGRAMM_H

程序.cpp

#include "programm.h"

programm::programm()
{
    this->window = new sf::RenderWindow(sf::VideoMode(600, 600), "Novel Editor", sf::Style::Close);
    this->window->setPosition(sf::Vector2i(0, 0));
    this->window->setFramerateLimit(60);
    this->b = ImageButton(sf::Vector2f(50.f, 50.f), sf::Vector2f(50.f, 50.f), sf::Color::Yellow, 5.f, "images\\putin.png");
}

void programm::run()
{
    while (this->window->isOpen())
    {
        while (this->window->pollEvent(e))
        {
            update();
        }
    }
}

void programm::render()
{
    this->window->clear();
    b.draw(this->window);
    this->window->display();
}

void programm::update()
{
    switch (e.type)
    {
    case sf::Event::Closed:
    {
        this->window->close();
        break;
    }
    default:
        break;
    }

    render();
}

截屏

在此处输入图像描述

标签: c++sfml

解决方案


programm::programm()
{
    ...
    this->b = ImageButton(...); //< this line cause the bug
}

您正在this->b通过从本地分配来初始化图像按钮ImageButton。现在精灵将拥有本地实例纹理的纹理引用,当本地实例“死亡”时,纹理将被释放。您需要保持纹理的生命周期

解决方案1:覆盖赋值运算符并像这样设置纹理

ImageButton& operator=(const ImageButton& ref) {
        backTexture = ref.backTexture;
        background = ref.background;
        background.setTexture(backTexture);
        return *this;
}

解决方案 2:创建一个TextureManager并将其作为您所有程序的纹理 API,通过它维护您的纹理生命周期。

解决方案 3programm :在构造函数中初始化图像按钮

programm::programm()
    :b (sf::Vector2f(50.f, 50.f), sf::Vector2f(50.f, 50.f), sf::Color::Yellow, 5.f, "img.jpg")
{
   ...
}

另一个错误

void ImageButton::draw(sf::RenderWindow* w)
{
    w->draw(this->background);
    w->draw(this->frame);
}

您在背景之后绘制框架,默认情况下框架的填充颜色为白色

解决方案1:先画框,再画背景

解决方案 2:将框架填充颜色 alpha 设置为 0

Button::Button(sf::Vector2f size, sf::Vector2f pos, sf::Color outlineColor, float sizeOutline)
{
    frame.setPosition(pos);
    frame.setSize(size);
    frame.setOutlineColor(outlineColor);
    frame.setFillColor(sf::Color(0, 0, 0, 0)); // <----
    frame.setOutlineThickness(sizeOutline);
}

推荐阅读