SFML Countdown Timer Help

Alright, another SFML issue. I'm pretty sure this has to do with my timer.

I want to try and display a timer on screen in seconds. It works thus far, but instead of replacing the current second, it is added on instead.

Example: Instead of going 30, replacing 30 with 29, then replacing 29 with 28, it goes 302928. The window won't clear the previous number and replace it with the next.

I'm a bit stumped. Here's my code. (Line 95 is where the timer method starts)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#include "SFML/Graphics.hpp"
#include "SFML/Audio.hpp"
#include "SFML/Window.hpp"
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <sstream>
#include <iomanip>
#include <locale>

int main()
{
    sf::RenderWindow window(sf::VideoMode(800, 600), "Sandals");
    window.setFramerateLimit(60);

    //LOAD GAME MUSIC
    sf::Music gameMusic;
    if (!gameMusic.openFromFile("music/Quirky_Dog.ogg")) {
        std::cerr << "No music file found!" << std::endl;
    }
    //LOAD PLAYER SPRITE TEXTURE
    sf::Texture sprite;
    if (!sprite.loadFromFile("images/test_sprite.png")) {
        std::cerr << "No sprite image found!" << std::endl;
    }

    //LOAD SANDALS TEXTURE
    sf::Texture sandalsTexture;
    if (!sandalsTexture.loadFromFile("images/test_sprite.png")) {
        std::cerr << "No sprite image found!" << std::endl;
    }

    //LOAD GAME TIMER FONT
    sf::Font timerFont;
    if (!timerFont.loadFromFile("font/arial.ttf")) {
        std::cerr << "No font file found!" << std::endl;
    }

    //GAME CLOCK & TIMER
    sf::Clock clock;
    int countdown = 30;

    //convert countdown to a string
    std::string countdownString;
    std::ostringstream convert;
    convert << countdown;
    countdownString = convert.str();

    //LOAD FONT AND TEXT
    sf::Text timerText;
    timerText.setFont(timerFont);
    timerText.setString(countdownString);
    timerText.setPosition(10, 0);
    timerText.setCharacterSize(40);


    //RANDOMIZE SANDALS APPEARANCES
    int maxRandX, maxRandY, randomX, randomY;
    maxRandX = 750;
    maxRandY = 550;

    srand(time(0));
    randomX = (rand () % maxRandX) + 1;
    randomY = (rand () % maxRandY) + 1;


    //LOAD SANDALS SPRITE
    sf::Sprite sandalsSprite(sandalsTexture);
    sandalsSprite.setPosition(randomX, randomY);

    //LOAD PLAYER SPRITE
    sf::Sprite player(sprite);
    player.setPosition(400, 400);

    //LOAD GAME MUSIC
    gameMusic.play();

    //PLAYER MOVEMENT VARIABLES
    float playerMovementSpeed = 5;

    //SANDALS COLLECTED
    int sandalsCollected = 0;

    while (window.isOpen())
        {
            sf::Event event;
            while (window.pollEvent(event))
            {
                if (event.type == sf::Event::Closed)
                    window.close();
                if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape))
                    window.close();
            }

            //TIMER - 30 SECONDS
                int timer = clock.getElapsedTime().asSeconds();
                std::cout << timer << std::endl;

                if (timer > 0) {
                    countdown--;
                    convert << countdown;
                    countdownString = convert.str();
                    timerText.setString(countdownString);
                    clock.restart();
                }

            //PLAYER MOVEMENT
                if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
                    player.move(-playerMovementSpeed, 0);
                if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
                    player.move(0, playerMovementSpeed);
                if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
                    player.move(0, -playerMovementSpeed);
                if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
                    player.move(playerMovementSpeed, 0);

            //PREVENT SPRITE FROM EXITING GAME WINDOW
                if (player.getPosition().y >= 550)
                    player.setPosition(player.getPosition().x, player.getPosition().y - playerMovementSpeed);
                if (player.getPosition().y <= 0)
                    player.setPosition(player.getPosition().x, player.getPosition().y + playerMovementSpeed);
                if (player.getPosition().x >= 750)
                    player.setPosition(player.getPosition().x - playerMovementSpeed, player.getPosition().y);
                if (player.getPosition().x <= 0)
                    player.setPosition(player.getPosition().x + playerMovementSpeed, player.getPosition().y);

            //COLLISION DETECTION, SANDALS COLLECTED, & RANDOM PLACEMENT
                if (player.getGlobalBounds().intersects(sandalsSprite.getGlobalBounds())) {
                    std::cout << "You have collected some sandals" << std::endl;

                    randomX = (rand () % maxRandX) + 1;
                    randomY = (rand () % maxRandY) + 1;

                    sandalsSprite.setPosition(randomX, randomY);
                    sandalsCollected++;

                    std::cout << "Sandals Collected: " << sandalsCollected << std::endl;
                }


            window.clear();
            window.draw(player);
            window.draw(sandalsSprite);
            window.draw(timerText);
            window.display();
        }

    return 0;
}
Last edited on
Insert some "\r" before displaying the new number.
@modoran

What exactly does "\r" do? I've never heard of it before.

EDIT:
I changed line 95-105 and used /r like you said, but I got this weird box.

1
2
3
4
5
6
7
if (timer > 0) {
                    countdown--;
                    convert << countdown;
                    countdownString = convert.str();
                    timerText.setString("\r" + countdownString);
                    clock.restart();
                }


Picture of weird box http://i.imgur.com/C0xWrEr.png
Last edited on
Your 'convert' object is never cleared, so you keep appending data rather than resetting it.

If you are using C++11 (which you should be, it's 2015), then there's no need for a convert object anyway... just use std::to_string:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
                if (timer > 0) {
                    countdown--;
                    
                    // get rid of this crap:
                    //convert << countdown;
                    //countdownString = convert.str();
                    //timerText.setString(countdownString);
                    
                    // do this instead:
                    timerText.setString( std::to_string(countdown) );
                    
                    
                    clock.restart();
                }
Topic archived. No new replies allowed.