Hi, welcome, and glad you got it to work!
The reason it works as a member of the class is that it continues to exists (as long as the class instance does).
The other two options you mentioned both create a new texture each time and are destroyed at the end of that scope (the closing brace: } )
The one in the class's constructor is destroyed almost immediately.
The one in the loop is destroyed at the end of the loop.
But, the one in the loop is loading the texture every frame and is best avoided. Resources (especially heavy ones like textures) should be loaded once and changed as little as possible.
So, the best option here is, as you've already found, is put the texture as a class member. You can still load it in the constructor but the member lasts as long as the class instance does.
e.g.
class Game {
public:
sf::Texture t;
Game() {
if (!t.loadFromFile("images/tiles.png")) {
std::cerr << "Unable to load texture!\n";
}
}
}
Remember to test the return value (bool) from loadFromFile (as shown in my example) as it informs you if the texture load was successful.
You could throw an exception, for example, as it's likely you wouldn't want to continue without it.