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

问题描述

我的程序中有一个 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,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",font);
    Button startButton("",{30,30},20,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,170));
                    }else{
                        openNotepad.setBackColor(Color(0,110,51));
                        openNotepad.setoutThick(0);
                    }if(opencalc.isMouSEOver(window)){
                        opencalc.setBackColor(Color(42,83));
                        opencalc.setoutThick(1.5f);
                        opencalc.setoutColor(Color(255,170));
                    }else{
                        opencalc.setBackColor(Color(0,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,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 的程序

解决方法

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

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

这是预期的行为吗?

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

>

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

enter image description here

,

更新帖子后: 我发现

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

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

,

尝试包含