Search code examples
c++sfml

Decreasing value in vectors with SFML


I created 5 numbers using vector with SFML, but I want the second one to fall one by one at intervals of 1 second. But, they first three falling as one by one. I don't understand why something like this is happening. Can you help me?

if (second == 1)
    {

    random.at(2)-=1;
    cout << random[2] << endl;
    text.setString(to_string(random[2]));
    text.setPosition(numbers[2].getPosition().x, numbers[2].getPosition().y);
    numbers.push_back(text);
    numbers.erase(numbers.begin() + 2);
    clock.restart();


}

The program gif

Full code


Solution

  • I'll give you a hand.

    Here's what's happening:

    1. You create 5 numbers in the random array. You may not have noticed it, but they are numbered 0 to 4 (SFML is sitting on C++, and then it means that arrays starts at zero here).
    2. Every second, you update the number stocked in the 3rd place of your random array.
    3. Then it goes wrong: instead of updating the corresponding number in the numbers array, you cycle it with push_back and erase.

    Understand me here: push_back create a new element at the end of the vector, while erase removes an element from the vector and then "sort out things" so there's not number gap in the index of the vector.

    Effectively, you're handling random right, but when you try to update number you cycle through it. Like this:

    seconds:       1 2 3 4 5 6
    
    
    array content: 0 0 0 0 0 0
      (vertical)   1 1 1 1 1 1
                   2 3 4 5 6 7
                   3 4 5 6 7 8
                   4 5 6 7 8 9
    

    I'm not sure how clear I'm making this, but if you look at the array content, you'll see that by erasing and creating a new value at the end, you're cycling through the positions [2-4] of the array. That's why in your gif not all numbers are updated wrong, only 3 of them.

    The obvious solutions would be to stop erasing and pushing back in the numbers array. You can update it the same way you updated the random array. It'll be fine.

    Like this:

    if (second == 1)
        {
        random.at(2)-=1;
        cout << random[2] << endl;
        numbers[2].setString(to_string(random[2]));
        clock.restart(); 
    }
    

    Have fun.