SFML white rectangle

送分小仙女□ 提交于 2020-03-05 03:10:38

问题


I am trying to do a simple tile map. I have a problem: when I set up the map, there are only white squares. I'm normally loading the texture, so I don't know why it is like that.

Here is the code:

class Tile
{
private:
sf::Sprite sprite;
sf::Texture tex;

public:
     Tile(int x, int y, sf::Texture tex)
    {
this->tex = tex;
this->sprite.setTexture(this->tex);
this->sprite.setPosition(x, y);

    }
    void render(sf::RenderWindow* target)
    {
    target->draw(this->sprite);
    }


class Tilemap
{
private:
Tile tiles[36][64];
sf::Texture tex[4];

public:
//const/dest
Tilemap()
{
this->tex[0].loadFromFile("Resources/Tilemap/Water/water1.png");

int x = -WIDTH+WIDTH/2;
int y = -HEIGTH/2;
for (int i = 0; i < 36; i++)
{
    for (int j = 0; j < 64; j++)
    {
        this->tiles[i][j] = Tile(x, y, this->tex[0]);
        x += 60;
    }
    y += 60;
    x = -WIDTH + WIDTH / 2;
}

}


render(sf::RenderWindow* target, sf::Vector2f pos)
{
for (int i = 0; i < 34; i++)
{
    for (int j = 0; j < 64; j++)
    {
        this->tiles[i][j].render(target);
    }
}
 };
 Tilemap map;
 map = Tilemap();

回答1:


You have dangling reference in sprite.

This dangling reference occurs in the below line:

this->tiles[i][j] = Tile(x, y, this->tex[0]);

What does reference say about Sprite::setTexture ?

The texture argument refers to a texture that must exist as long as the sprite uses it. Indeed, the sprite doesn't store its own copy of the texture, but rather keeps a pointer to the one that you passed to this function. If the source texture is destroyed and the sprite tries to use it, the behavior is undefined.

Where exactly is problem ?

Tile(x, y, this->tex[0]);

Here, new instance of Tile is created. tex and sprite are member variables of Tile. And sprite by setTexture is referring to tex.

tiles[i][j] = Tile(x,...);

In the above line, copy assignment operator is called which copies sprite/tex from temporary object - created by Tile(x,y,..)). As a result in tiles[i][j] you have sprite member which refers to texture of temporary instance - Tile(..) (sprite just holds pointer to texture). And finally, at the end of the full expression temporary instance is destroyed, tex of Tile(..) is deleted, and tiles[i][j].sprite holds invalid pointer to texture.

Solution?

You have to add copy constructor (copy assignment operator) of Tile to properly initialize sprite for holding its own tex (no reference to the instance the copy is made from):

For example:

 Tile& operator=(const Tile& theOther)
 {
      this->tex = theOther.tex;
      this->sprite.setTexture(this->tex);
      return *this;
 }

in default generated copy assignment operator this->sprite points to theOther.tex texture, which is wrong.



来源:https://stackoverflow.com/questions/59631899/sfml-white-rectangle

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!