SFML community forums

Help => General => Topic started by: Forceofaqua on July 24, 2015, 12:12:40 am

Title: Accessing Sprites within a vector
Post by: Forceofaqua on July 24, 2015, 12:12:40 am
I'm have a bit of trouble as the title suggests. I've got three sprites inside of a vector. I'm building a button system for an application. The code detects which sprite is being selected, but does not  show the changes. Wierd thing is-is if I change the vector component target to a specific sprite the color change works. Does anyone know whats going on here?

        unsigned int selected = -1;

        // Load Sprite Vector
        vect.push_back(S1);
        vect.push_back(S2);
        vect.push_back(S3);

        // Application Loop
        while (Running){

                //--EVENTS--
                while (App.pollEvent(Event)){

                        ... Event handler

                        else if (Event.type == Event.MouseButtonPressed && Event.mouseButton.button == sf::Mouse::Left){
                                for (unsigned int i = 0; i < vect.size(); i++){
                                        if (ifspritecollision(vect[i], mouse.x, mouse.y)){
                                                vect[i].setColor(sf::Color(120, 120, 120));
                                                selected = i;
                                                break;
                                        }
                                }
                        }
                        else if (Event.type == Event.MouseButtonReleased && Event.mouseButton.button == sf::Mouse::Left){
                                // There are only three sprites on the screen
                                if (!(selected < 0 || 2 < selected))
                                        vect[selected].setColor(sf::Color(255, 255, 255));
                        }
       
                //... clear screen
                //... draw to screen
                //... display screen
               
        }
 

This will work for a single sprite
                        else if (Event.type == Event.MouseButtonPressed && Event.mouseButton.button == sf::Mouse::Left){
                                for (unsigned int i = 0; i < vect.size(); i++){
                                        if (ifspritecollision(vect[i], mouse.x, mouse.y)){
                                                // target for color change set to a specific sprite
                                                S1.setColor(sf::Color(120, 120, 120));
                                                selected = i;
                                                break;
                                        }
                                }
                        }
                        else if (Event.type == Event.MouseButtonReleased && Event.mouseButton.button == sf::Mouse::Left){
                                // There are only three sprites on the screen
                                if (!(selected < 0 || 2 < selected))
                                        // target for color change set to a specific sprite
                                        S1.setColor(sf::Color(255, 255, 255));
                        }
 

P.S The code has been changed for simplicity.
Title: Re: Accessing Sprites within a vector
Post by: Mörkö on July 24, 2015, 06:44:34 am
Try printing out the value of this statement:
unsigned int selected = -1;
And you will see why this following condition is illogical:
if (!(selected < 0 || 2 < selected))

For a quick fix, change the loops to something like this:
// mouse button press
for (auto & sprite : vect)
    if (ifspritecollision(sprite, mouse.x, mouse.y))
        sprite.setColor(sf::Color(120, 120, 120));
...
// mouse button release
for (auto & sprite : vect)
    sprite.setColor(sf::Color::White);
 

But what you might want to do eventually is to create your own button class that receives click events somehow and keep an internal state based on those, at least that would be the object oriented approach to this type of thing.
Title: Re: Accessing Sprites within a vector
Post by: Hapax on July 24, 2015, 05:46:46 pm
Just that first line is quite problematic. Assigning a signed value to an unsigned data type is very rarely what you actually want to do. You could just change that to an signed integer (int). You may have to cast later.

For a quick fix, change the loops to something like this:
[code]
The first one (mouse pressed), unfortunately, doesn't return the value of the item that was selected but isn't really the problem. The second one (mouse released) would indeed fix the range error (or you could remove selected < 0) but if selected is changed to an int, this would begin to work.

I would probably prefer to use selected as an unsigned int but also use an explicit boolean that kept track of whether or not a selection was made and only using selected if that boolean is true. I find this more intuitive than using negative values to represent false, most of the time.
Title: Re: Accessing Sprites within a vector
Post by: Arcade on July 24, 2015, 06:01:37 pm
In addition to what others said, how are you drawing your sprites? Are you doing?
window.draw(S1);
window.draw(S2);
window.draw(S3);
 
or drawing them in a loop like?
window.draw(vect[i]);
 

When you push back sprites into the vector, the vector will not contain your original sprites, but will store copies. Anything you do on the sprites in the vector will not change S1, S2, and S3 (and vice versa).