在制作多个纹理时,SFML精灵是一个白色方块

时间:2018-03-17 12:47:06

标签: c++ sfml

我正在制作一个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;
}

}

以下是截图:

enter image description here

1 个答案:

答案 0 :(得分:0)

TL; DR Solutions,或者:

  • 使用std::vector<sf::Texture> - std::list<sf::Texture>std::forward_list<sf::Texture>以外的容器。
  • 存储指向纹理的指针 - std::vector<std::unique_ptr<sf::Texture>>

解释

存储纹理对象以及引用它们的精灵。这是正确的,因为spite只保留其纹理的引用(指针)。这也意味着在精灵生命周期内纹理地址必须保持不变。

看起来你没有考虑std :: vector push_back()是如何工作的。向量初始分配一些内存,一旦没有地方插入新项,向量就会分配更多内存并复制所有插入的项目和新的项目。所以所有项目地址都会改变。

在你的情况下,一个项目是一个纹理,它的地址在另一个纹理的iselion上被改变,所以一些sprite&#34; looses&#34;它的质地。这通常会导致绘制白色方块。