-
Hey !
I want to draw a few Sprites which are located in the same folder (assets/playerIcon/NUMBER.png).
I don't understand why my code isn't working. On my app I can only see the last sprite and the others are just replaced by a white square.
Could someone help me ? Thank you in advance !
static vector<Sprite> playerIcon;
static vector<Texture> playerIconVectorTexture;
int playerIconNumber = 4;
for (int i = 0; i < playerIconNumber; i++) {
std::string fileLocation = "assets/playerIcon/";
fileLocation += std::to_string(i) + ".png";
std::cout << fileLocation << std::endl;
Texture playerIconTexture;
Sprite playerIconSprite;
if (!playerIconTexture.loadFromFile(fileLocation))
{
writeToLog("Error");
exit(0);
}
else {
playerIconTexture.setSmooth(true);
playerIconVectorTexture.insert(playerIconVectorTexture.begin(), playerIconTexture);
playerIconSprite.setTexture(playerIconVectorTexture.front());
playerIconSprite.setPosition(Vector2f(200+(i*100), 400));
playerIcon.push_back(playerIconSprite);
}
}
And later :
for (Sprite x : playerIcon) {
window.draw(x);
}
-
thats a C++ problem, not really SFML: when you use vector::insert, you reallocate all the vector in memory, what means you change the adress of all elements inside vector. so, each sprite will point to a place where there WAS a texture, but there is no more; except for the last sprite, because after it, there is no more inserts and no more reallocation.
try changing playerIconVectorTexture.insert(playerIconVectorTexture.begin(), playerIconTexture);
for playerIconVectorTexture.push_back(playerIconTexture);
push back USUALLY just adds a new element at the end of the vector, so it USUALLY doesn't change everything from place. the problem is, if the vector get too big, and there is no more space to grow, it will have to be reallocated anyway.
so i suggest using playerIconVectorTexture.reserve(final_size)
before your loop starts (you could put it after the line "int playerIconNumber = 4;") if you know how big you final vector will be, to avoid that.
-
That wouldn't solve anything. Even if the vector doesn't reallocate its memory, it still stores copies. The original textures, ie. the ones that are used by sprites, are still destroyed when the for loop ends.
-
Thank you ! Stauricus I already tried to replace insert() with push_back() but it didn't change antyhing :-[
Is there a nice way to draw a large number of sprite (that have the same properties) ? I can copy paste my code for each sprite but I think it's not really elegant ...
-
It's not a problem of drawing sprites, it's a simple C++ problem of keeping used objects alive.
There are multiple solutions to this problem, and you would learn a lot by trying to figure it out by yourself. I give you a hint though: load/store all the textures first, and then create the sprites, assigning them textures from the vector.
-
This is a really good idea and I already tried to do this ;D :
playerIconSprite.setTexture(playerIconVectorTexture.front());
On the first post you can see that I have two vector : one for sprites and the other for textures. But it does not work anyway >:(
-
Then you probably did it wrong ;)
And why playerIconVectorTexture.front() and not playerIconVectorTexture[i] ?
-
Finally ...
playerIconVectorTexture.reserve(playerIconNumber);
playerIconVectorTexture.insert(playerIconVectorTexture.begin()+i, playerIconTexture);
playerIconSprite.setTexture(playerIconVectorTexture[i]);
With this it's working perfectly. Thank to both of you ;) !