簡體   English   中英

SFML Sprite在制作多個紋理時是一個白色正方形

[英]SFML sprite is a white square when making multiple textures

我正在制作一個SFML框架,當我使用一次loadImage函數時,圖像會正確加載所有顏色,但是如果我將其兩次用於另一種紋理,則只會渲染一個精靈,並且全部為白色。 我讀到您不想刪除紋理或精靈,否則它將是白色的。 但是在這段代碼中,我將所有紋理存儲在矢量中。 有人知道這個功能有什么問題嗎?

FM::Image FM::graphics::loadImage(const char* fileName) {

        texturesindex++;
        sf::Texture texture;
        texture.loadFromFile(fileName);
        textures.push_back(texture);
        sf::Sprite sprite(textures[texturesindex]);
        Image image;
        image.sprite = sprite;
        return image;
}

這是所有代碼:

SFFM.cpp:

    #include "SFFM.h"
    #include <SFML/Graphics.hpp>
    #include <vector>
    #include <string>

    int backgroundcolor[3] = { 0,0,0};
    sf::RenderWindow Window(sf::VideoMode(800, 600), "MyGame");
    std::vector<sf::Texture> textures;
    int texturesindex = -1;

    void FM::window::setWindowOptions(unsigned int Width, unsigned int Height, const char* Title, int FrameLimit) {

        Window.setSize(sf::Vector2u(Width, Height));
        Window.setFramerateLimit(FrameLimit);
        Window.setTitle(Title);
    }

    void FM::window::setBackgroundColor(int r, int g, int b) {

        backgroundcolor[0] = r;
        backgroundcolor[1] = g;
        backgroundcolor[2] = b;
    }

    FM::Image FM::graphics::loadImage(const char* fileName) {

        texturesindex++;
        sf::Texture texture;
        texture.loadFromFile(fileName);
        textures.push_back(texture);
        sf::Sprite sprite(textures[texturesindex]);
        Image image;
        image.sprite = sprite;
        return image;
    }

    void FM::graphics::drawImage(Image image, int x, int y, int scalex, int scaley, int rotation) {

        image.sprite.setPosition(x, -y);
        image.sprite.setRotation(rotation);
        image.sprite.setScale(sf::Vector2f(scalex, scaley));
        Window.draw(image.sprite);
    }

    void FM::graphics::drawImage(Image image, int x, int y, int scalex, int scaley) {

        image.sprite.setPosition(x, -y);
        image.sprite.setScale(sf::Vector2f(scalex, scaley));
        Window.draw(image.sprite);
    }

    void FM::graphics::drawImage(Image image, int x, int y) {

        image.sprite.setPosition(x, -y);
        Window.draw(image.sprite);
    }

    int main()
    {   
        FM::Start();

        while (Window.isOpen())
        {
            sf::Event event;

            while (Window.pollEvent(event))
            {
                if (event.type == sf::Event::Closed)
                    Window.close();
                else if (event.type == sf::Event::Resized)
                {
                    Window.setView(sf::View(sf::FloatRect(0, 0, event.size.width, event.size.height)));
                }
            }

            Window.clear(sf::Color(backgroundcolor[0], backgroundcolor[1], backgroundcolor[2]));
            FM::Update();
            Window.display();
        }

        return 0;
    }

SFFM.h:

#pragma once
#include <SFML/Graphics.hpp>

namespace FM
{

void Update();

void Start();



class window {

public:

    static void setWindowOptions(unsigned int Width, unsigned int Height, const char * Title, int FrameLimit);

    static void setBackgroundColor(int r, int g, int b);
};

class Image {

public:
    sf::Sprite sprite;
};

class graphics {

public:

    static Image loadImage(const char* fileName);
    static void drawImage(Image image, int x, int y, int scalex, int scaley, int rotation);
    static void drawImage(Image image, int x, int y, int scalex, int scaley);
    static void drawImage(Image image, int x, int y);
};

class Input {

public:

};
};

main.cpp:

#include "SFFM.h"
#include <SFML\Graphics.hpp>
FM::Image Gangster;
FM::Image Block;
int x = 0;
int y = 0;

void FM::Start() {

window::setWindowOptions(1280, 720, "Platformer", 120);
window::setBackgroundColor(0, 127, 255); 
Gangster = graphics::loadImage("assets/Gangster.png");
}

void FM::Update() {

graphics::drawImage(Gangster, x, y, 5, 5);
graphics::drawImage(Block, 100, 100, 5, 5);

if (sf::Keyboard::isKeyPressed(sf::Keyboard::W)) {

    y += 1;
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::S)) {

    y -= 1;
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::D)) {

    x += 1;
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::A)) {

    x -= 1;
}

}

這是屏幕截圖:

在此處輸入圖片說明

TL; DR解決方案:

  • 使用std::vector<sf::Texture> std::list<sf::Texture>std::forward_list<sf::Texture>以外的容器。
  • 存儲指向紋理的指針std::vector<std::unique_ptr<sf::Texture>>

說明

您將紋理對象與引用它們的精靈一起存儲。 這是正確的,因為惡意僅保留對其紋理的引用(指針)。 這也意味着紋理地址在Sprite生存期內必須保持不變。

看來您沒有考慮std :: vector push_back()的工作方式。 向量最初會分配一些內存,一旦無處可插入新項目,向量將分配更多內存並復制所有插入的項目和新項目。 因此,所有項目地址都會更改。

在您的情況下,一個項目是一個紋理,則在更改另一個紋理后會更改其地址,因此某些精靈會“松開”其紋理。 這通常會導致繪制白色正方形。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM