为什么我的 sfml RectangleShape 没有显示在窗口上

时间:2021-02-18 17:22:22

标签: c++ draw sfml

我的程序中有一个 RectangleShape,它应该显示在某处,但由于某种原因,该 RectangleShape 没有显示。程序中没有错误,只是 RectangleShape 没有显示。我有三个文件:main.cpp、button.h 和 textbox.h。 RectangleShape 在 textbox.h 头文件中声明。以下是文件:

ma​​in.cpp

#include <SFML/Graphics.hpp>
#include <iostream>
#include <windows.h>
#include "button.h"
#include "textbox.h"
using namespace std;
using namespace sf;
static const float viewHeight = 500.f;
void resizeView(const RenderWindow &window, View &view){
    float aspectRatio = float(window.getSize().x) / float(window.getSize().y);
    view.setSize(viewHeight * aspectRatio, viewHeight);
}
int main(){
    View view(Vector2f(0.f, 0.f), Vector2f(viewHeight, viewHeight));
    Event event;
    bool isStartOpen = false;
    RenderWindow window(VideoMode(500, 500), "Operating System", Style::Close | Style::Resize);
    RectangleShape player(Vector2f(500.0f, 30.0f));
    RectangleShape startMenu(Vector2f(300.0f, 400.0f));
    Texture startTexture;
    if(!startTexture.loadFromFile("startButton.png")){
        MessageBox(NULL, "Error loading image file: startButton.png in the system", "Image File Error", MB_OK | MB_ICONERROR);
    }
    startMenu.setFillColor(Color(0, 0, 0, 200));
    startMenu.setPosition(0.0f, 500.0f);
    player.setFillColor(Color::Black);
    player.setPosition(0.0f, 473.0f);
    Font font;
    if(!font.loadFromFile("Calibri Regular.ttf")){
       MessageBox(NULL, "Error loading font file: buttonFont.ttf in the system", "Font File Error", MB_OK | MB_ICONERROR);
    }
    Textbox passCreate(15, Color::Black, false, Color::White, 4, {100, 100});
    Button openNotepad("Notepad", {90, 90}, 14, Color::Green, startTexture, font);
    Button openCalc("Calculator", {90, 90}, 14, Color::Green, startTexture, font);
    Button startButton("", {30, 30}, 20, Color::White, startTexture, font);
    startButton.setPosition({0, 473});
    openNotepad.setPosition({0, 500});
    openCalc.setPosition({0, 500});
    passCreate.setFont(font);
    passCreate.setPosition({100, 100});
    passCreate.setLimit(true, 10);
    while (window.isOpen())
    {
        if(Keyboard::isKeyPressed(Keyboard::Return)){
            passCreate.setSelected(true);
        }else if(Keyboard::isKeyPressed(Keyboard::Escape)){
            passCreate.setSelected(false);
        }
        while (window.pollEvent(event))
        {
            switch(event.type){
                case Event::Resized:
                    resizeView(window, view);
                    break;
                case Event::TextEntered:
                    passCreate.typedOn(event);
                    break;
                case Event::Closed:
                    window.close();
                    cout << "Window has been removed" << endl;
                    break;
                case Event::MouseMoved:
                    if(openNotepad.isMouseOver(window)){
                        openNotepad.setBackColor(Color(42,150,83));
                        openNotepad.setOutThick(1.5f);
                        openNotepad.setOutColor(Color(255, 255, 255, 170));
                    }else{
                        openNotepad.setBackColor(Color(0,110,51));
                        openNotepad.setOutThick(0);
                    }if(openCalc.isMouseOver(window)){
                        openCalc.setBackColor(Color(42,150,83));
                        openCalc.setOutThick(1.5f);
                        openCalc.setOutColor(Color(255, 255, 255, 170));
                    }else{
                        openCalc.setBackColor(Color(0,110,51));
                        openCalc.setOutThick(0);
                    }if(startButton.isMouseOver(window)){
                        startButton.setBackColor(Color(1, 159, 255));
                    }else{
                        startButton.setBackColor(Color::White);
                    }
                    break;
                case Event::MouseButtonPressed:
                    if(openNotepad.isMouseOver(window)){
;                        system("notepad");
                    }else if(startButton.isMouseOver(window) && !isStartOpen){
                        startMenu.setPosition(0.f, 75.f);
                        openNotepad.setPosition({18, 90});
                        openCalc.setPosition({116, 90});
                        isStartOpen = true;
                    }else if(startButton.isMouseOver(window) && isStartOpen){
                        startMenu.setPosition(0.f, 500.f);
                        openNotepad.setPosition({0, 500});
                        openCalc.setPosition({0, 500});
                        isStartOpen = false;
                    }else if(openCalc.isMouseOver(window)){
                        system("calc");
                    }
                    break;
            }
        view.setCenter(250.f, 250.f);
        window.setView(view);
        window.draw(startMenu);
        passCreate.drawTo(window);
        window.draw(player);
        openNotepad.drawTo(window);
        openCalc.drawTo(window);
        startButton.drawTo(window);
        window.display();
        window.clear(Color(144, 0, 255));
    }
}
}

button.h

#pragma once
#include <iostream>
#include <SFML/graphics.hpp>
using namespace sf;
using namespace std;
class Button{
    public:
        Button(){

        }
        Button(string t, Vector2f size, int charSize, Color bgColor, Texture &texture, Font &font){
            text.setString(t);
            text.setColor(Color::White);
            text.setCharacterSize(charSize);
            text.setFont(font);
            button.setSize(size);
            button.setFillColor(bgColor);
            button.setPosition(0.f, 500.f);
            button.setTexture(&texture);
        }
        void setBackColor(Color color){
            button.setFillColor(color);
        }
        void setTextColor(Color color){
            text.setColor(color);
        }
        void setPosition(Vector2f pos){
            button.setPosition(pos);
            float yPos = (pos.y + button.getLocalBounds().height / 1.3);
            text.setPosition({pos.x + 5, yPos});
        }
        void drawTo(RenderWindow &window){
            window.draw(button);
            window.draw(text);
        }
        void setOutColor(Color outColor){
            button.setOutlineColor(outColor);
        }
        void setOutThick(float outThick){
            button.setOutlineThickness(outThick);
        }
        bool isMouseOver(RenderWindow &window){
            float mouseX = Mouse::getPosition(window).x;
            float mouseY = Mouse::getPosition(window).y;
            float btnPosX = button.getPosition().x;
            float btnPosY = button.getPosition().y;
            float btnxPosWidth = button.getPosition().x + button.getLocalBounds().width;
            float btnyPosWidth = button.getPosition().y + button.getLocalBounds().height;
            if(mouseX < btnxPosWidth && mouseX > btnPosX && mouseY < btnyPosWidth && mouseY > btnPosY){
                return true;
            }
            return false;
        }
    private:
       RectangleShape button;
       Text text;
};

textbox.h

#pragma once
#include <iostream>
#include <SFML/Graphics.hpp>
#include <sstream>
#include <fstream>
#include <windows.h>
#define DELETE_KEY 8
#define ENTER_KEY 13
#define ESCAPE_KEY 27
using namespace std;
class Textbox{
public:
    Textbox(){

    }
    Textbox(int size, Color textColor, bool sel, Color boxColor, int borderThick, Vector2f boxSize, Font &font, bool tof, int lim){
        textbox.setCharacterSize(size);
        textbox.setColor(textColor);
        textbox.setFont(font);
        hasLimit = tof;
        limit = lim - 1;
        typeArea.setFillColor(boxColor);
        typeArea.setOutlineThickness(borderThick);
        typeArea.setScale(boxSize);
        isSelected = sel;
        if(sel){
            textbox.setString("|");
        }else{
            textbox.setString("");
        }
        string passAttempt;
        string password;
        ifstream getPassword("password.txt");
        getline(getPassword, password);
        cout << "Enter your password";
        cin >> passAttempt;
        passAttempt.compare(password) == 0 ? cout << "correct password" : cout << "incorrect password";
        getPassword.close();
    }
    void setPosition(Vector2f pos){
        textbox.setPosition(pos);
        typeArea.setPosition(pos);
    }
    void setLimit(bool tof){
        hasLimit = tof;
    }
    void setSelected(bool sel){
        isSelected = sel;
        if(!sel){
            string t = text.str();
            string newT = "";
            for(int i = 0;i < t.length();i++){
                newT += t[i];
            }
            textbox.setString(newT);
        }
    }
    string getText(){
        return text.str();
    }
    void drawTo(RenderWindow &window){
        window.draw(textbox);
        window.draw(typeArea);
    }
    void typedOn(Event input){
        if(isSelected){
            int charTyped = input.text.unicode;
            if(charTyped < 128){
                if(hasLimit){
                    if(text.str().length() <= limit){
                        inputLogic(charTyped);
                    }else if(text.str().length() > limit && charTyped == DELETE_KEY){
                        deleteLastChar();
                    }
                }else{
                    inputLogic(charTyped);
                }
            }
        }
    }
    void saveText(){
        if(isSelected){
            ofstream passFile("password.txt");
            passFile.is_open() ? MessageBox(NULL, "Sucessfully saved password", "Saved Password", MB_OK | MB_ICONINFORMATION) : MessageBox(NULL, "Error saving password: Password is in password.txt", "File Error", MB_OK | MB_ICONERROR);
            passFile << text.str();
            passFile.close();
        }
    }
private:
    Text textbox;
    RectangleShape typeArea;
    ostringstream text;
    bool isSelected = false;
    bool hasLimit = false;
    int limit;
    void inputLogic(int charTyped){
        if(charTyped != DELETE_KEY && charTyped != ENTER_KEY && charTyped != ESCAPE_KEY){
            text << static_cast<char>(charTyped);
        }else if(charTyped == DELETE_KEY){
            if(text.str().length() > 0){
                deleteLastChar();
            }
        }
        textbox.setString(text.str() + "|");
    }
    void deleteLastChar(){
        string t = text.str();
        string newT = "";
        for(int i = 0; i < t.length() - 1; i++){
            newT += t[i];
        }
        text.str("");
        text << newT;
        textbox.setString(text.str());
    }
};

请帮助修复显示 RectangleShape 的程序

3 个答案:

答案 0 :(得分:0)

我将您的项目加载到我的 Code::Blocks 环境中,不包括 textbox.h 并调用它。我用原来的code::blocks logo cb.bmp 替换了图像调用。我选择了手头的替换字体。

当我编译项目时,我发现了一个任务栏式按钮,带有两个子按钮。悬停子按钮时,会出现一个白色边框。您的 sf::RectangleShape(没有显示?)被称为 button

这是预期的行为吗?

如果这是预期的行为,如果您还没有(删除所有目标文件),请尝试从头开始重建您的项目。也许这会让编译器告诉您是否有任何它不知道的错误。

>

孤立的 .o 文件(意味着它们不再有源文件)会导致很多麻烦。删除源文件时不会删除对应的.o文件。

enter image description here

答案 1 :(得分:0)

更新帖子后: 我发现

using namespace sf;

不在你的 textbox.h 中

您还有两种不同的 SFML 图形标头包含类型

#include <SFML/graphics.hpp>

#include <SFML/Graphics.hpp>

假设您有 SFML 的库存安装,

#include <SFML/Graphics.hpp>

通常是正确的。

提示: 使用命名空间调用可能非常危险,因为您可能会忘记函数的来源。您可以通过在调用前加上命名空间名称来调用命名空间中的命令。例如:

RectangleShape typeArea;

会变成

sf::RectangleShape typeArea;

编辑:修复这些东西后,我做了一些调试:

error: class 'Textbox' has no member named 'setFont';

这是真的。当你调用 .setFont();在您的实例 passCreate 上,您没有调用 .setFont();来自 SFML,但是 .setFont();在您的班级 Textbox 中 - 不存在。将此添加到您的类中解决了这个问题。

void setFont(sf::Font font){
    textbox.setFont(font);
};

这实质上是获取您传递给它的字体,并将其应用到您调用 setFont() 的实例文本框;

编译器还抱怨 textbox.setLimit(bool, int) 没有候选。您现在正在传递一个 bool AND 整数。这是因为类 Textbox 中的函数 setLimit() 没有整数传递。 我变了

void setLimit(bool tof){
    hasLimit = tof;
}

void setLimit(bool tof, int setlimit){
    hasLimit = tof;
    limit = setlimit;
}

现在 setLimit 接受您发送的整数,并将其分配给类 Textbox 中的整数变量“limit”。

此后,不再有编译器错误。剩下的交给你!故障排除可能很有趣。看看编译器怎么说。它会告诉你出了什么问题。 enter image description here

最后提示: 我是否还补充说,输入错误的密码并不能阻止我“登录”; 当控制台询问我的密码时,主屏幕显示为冻结状态。也许您可以设置一个消隐精灵来覆盖所有内容?不过我相信有更好的解决方案!

答案 2 :(得分:-1)

尝试包含

相关问题