问题
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