【问题标题】:How to apply a texture from a function in sfml如何从 sfml 中的函数应用纹理
【发布时间】:2021-05-14 12:20:25
【问题描述】:

我正在尝试从函数应用纹理,但它似乎不起作用,那么如何将纹理应用到 sfml 中的函数?当我尝试从以下函数应用纹理时,也会出现错误:button.h|18|error: no matching function for call to 'sf::RectangleShape::setTexture(sf::Texture&)'|。您可以通过找到一种方法从函数应用纹理或修复错误并应用纹理来解决此问题。我有 2 个文件,一个名为 main.cpp,另一个名为 button.h。这是他们的代码。

ma​​in.cpp

#include <SFML/Graphics.hpp>
#include <iostream>
#include <windows.h>
#include "button.h"
using namespace std;
using namespace sf;
int main(){
    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);
    }
    Button openNotepad("Notepad", {90, 90}, 20, Color::Green, startTetxure);
    openNotepad.setPosition({100, 300});
    openNotepad.setFont(font);
    while (window.isOpen())
    {
        Event event;
        while (window.pollEvent(event))
        {
            switch(event.type){
                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.5);
                        openNotepad.setOutColor(Color(255, 255, 255, 100));
                    }else{
                        openNotepad.setBackColor(Color(0,110,51));
                        openNotepad.setOutThick(0);
                    }
                    break;
                case Event::MouseButtonPressed:
                    if(openNotepad.isMouseOver(window)){
                        cout << "You clicked the button" << endl;
                    }
                    break;
            }
        if(Keyboard::isKeyPressed(Keyboard::Key::S) && !isStartOpen){
            startMenu.setPosition(0.0f, 75.0f);
            isStartOpen = true;
        }else{
            startMenu.setPosition(0.0f, 500.0f);
            isStartOpen = false;
        }
        window.draw(startMenu);
        window.draw(player);
        openNotepad.drawTo(window);
        window.display();
        window.clear(Color(1, 159, 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){
            text.setString(t);
            text.setColor(Color::White);
            text.setCharacterSize(charSize);
            text.setScale(0.7f, 0.7f);
            button.setSize(size);
            button.setFillColor(bgColor);
            button.setTexture(texture);
        }
        void setFont(Font &font){
            text.setFont(font);
        }
        void setBackColor(Color color){
            button.setFillColor(color);
        }
        void setTextColor(Color color){
            text.setColor(color);
        }
        void setPosition(Vector2f pos){
            button.setPosition(pos);
            float xPos = (pos.x + button.getLocalBounds().width / 30) - (text.getLocalBounds().width / 2);
            float yPos = (pos.y + button.getLocalBounds().height / 1.3) - (text.getLocalBounds().height / 2);
            text.setPosition({xPos, 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;
};

【问题讨论】:

  • 我不再需要答案了,因为我已经有了答案

标签: c++ c file textures sfml


【解决方案1】:

让我们剖析一下错误。

button.h|18|error: no matching function for call to 'sf::RectangleShape::setTexture(sf::Texture&)'

这意味着您正在尝试调用一个不存在的函数。

我们试图调用什么函数?看起来我们正在尝试调用 sf::RectangleShape 内部的 setTexture 函数。

我们来看看documentation中sf::RectangleShape中的同名函数。

此函数将const Texture* texture 作为其第一个参数。我们再来看看错误信息的结尾。它试图找到一个以sf::Texture&amp; 作为参数的函数。它期望的类型和你提供的类型是不同的。 sf::Texture&amp; 不等于const Texture*,并且没有以sf::Texture&amp; 作为参数的重载函数。

解决方案是从sf::Texture&amp; 获取const Texture*。

前者称为指针,(特别是 const 指针),后者是引用(特别是非常量引用)。
您可以使用地址运算符 (&amp;) 从引用中获取指针。所以通过调用&amp;texture你可以获得纹理的非常量指针。反向操作可以使用间接运算符 (*)。
非 const 指针/引用可以隐式更改为 const 指针/引用。这是一种方式,反之则不然。

【讨论】:

  • 它消除了错误,但它没有应用纹理
  • 如果我修复编译器的错误(调用已弃用的sf::Text::setColor(),以及拼写错误的startTexture)并使用这个:i.stack.imgur.com/uq2ZV.png 纹理为startButton.png,我得到这个:i.stack.imgur.com/vLtP3.png,这是应用于按钮的纹理。你得到不同的结果吗?
  • 是的,在我的记事本按钮上,上面什么都没有
  • 你能告诉我你的代码来制作那个按钮吗
  • 除了我提到的更改之外,它与您的代码几乎完全相同。这是一个 7z 文件,其中包含一个 Visual Studio 解决方案和一个位于 /x64/Release/ 中的可执行文件:gist.github.com/JordanPowersUsername/…。提取它,运行可执行文件以确保它工作(尽管小心运行陌生人的可执行文件),然后比较代码。您的个人资料似乎表明您使用的是 CodeBlocks 而不是 Visual Studio,因此您可能无法打开解决方案,但 IDE 应该不是问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-14
  • 2014-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多