Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Sprites Vector  (Read 2239 times)

0 Members and 1 Guest are viewing this topic.

Chronos

  • Newbie
  • *
  • Posts: 5
    • View Profile
Sprites Vector
« on: October 23, 2019, 05:21:56 pm »
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);
}
 

« Last Edit: October 24, 2019, 08:40:58 pm by Chronos »

Stauricus

  • Sr. Member
  • ****
  • Posts: 369
    • View Profile
    • A Mafia Graphic Novel
    • Email
Re: Sprites Vector
« Reply #1 on: October 24, 2019, 11:36:59 pm »
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.
« Last Edit: October 25, 2019, 12:07:29 am by Stauricus »
Visit my game site (and hopefully help funding it? )
Website | IndieDB

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Sprites Vector
« Reply #2 on: October 25, 2019, 08:06:41 am »
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.
Laurent Gomila - SFML developer

Chronos

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: Sprites Vector
« Reply #3 on: October 25, 2019, 08:35:55 am »
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 ...
« Last Edit: October 25, 2019, 08:54:27 am by Chronos »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Sprites Vector
« Reply #4 on: October 25, 2019, 09:41:34 am »
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.
Laurent Gomila - SFML developer

Chronos

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: Sprites Vector
« Reply #5 on: October 25, 2019, 09:46:26 am »
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  >:(

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Sprites Vector
« Reply #6 on: October 25, 2019, 10:18:59 am »
Then you probably did it wrong ;)

And why playerIconVectorTexture.front() and not playerIconVectorTexture[i] ?
Laurent Gomila - SFML developer

Chronos

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: Sprites Vector
« Reply #7 on: October 25, 2019, 10:40:10 am »
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  ;) !