I think it would be easiest just to show you a working example, and then explain it a bit.
Start with a baseline that you should be able to run if you have SFML set up:
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
|
#include <SFML/Graphics.hpp>
int main()
{
int width = 800;
int height = 600;
sf::RenderWindow window(sf::VideoMode(width, height), "SFML Test!");
sf::RectangleShape rectangle;
rectangle.setSize(sf::Vector2f(100, 50));
rectangle.setOutlineColor(sf::Color::Red);
rectangle.setOutlineThickness(5);
rectangle.setPosition(0, height/2);
window.setVerticalSyncEnabled(true);
bool left_pressed = false;
bool right_pressed = false;
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
else if (event.type == sf::Event::KeyPressed)
{
if (event.key.code == sf::Keyboard::Left)
{
left_pressed = true;
}
else if (event.key.code == sf::Keyboard::Right)
{
right_pressed = true;
}
}
else if (event.type == sf::Event::KeyReleased)
{
if (event.key.code == sf::Keyboard::Left)
{
left_pressed = false;
}
else if (event.key.code == sf::Keyboard::Right)
{
right_pressed = false;
}
}
}
sf::Vector2f delta_pos;
if (left_pressed)
{
delta_pos.x -= 5;
}
if (right_pressed)
{
delta_pos.x += 5;
}
// move rectangle
rectangle.setPosition(rectangle.getPosition() + delta_pos);
window.clear(sf::Color::Blue);
window.draw(rectangle);
window.display();
}
return 0;
}
|
If you run this, you'll be able to use the Left and Right arrow keys to move the rectangle. Nothing too much, but it works.
Now let's say we want to incorporate time. Let's make it so, after 6 seconds, the box turns magenta.
SFML already has its own sf::Time and sf::Clock functionality, but you could convert this to use the C++ standard library if you really wanted to.
https://www.sfml-dev.org/tutorials/2.5/system-time.php
All we need to do is add an sf::Clock, and then query the clock to see what the elapsed time is.
We convert this time into seconds, and if the time is >6 seconds, set the rectangle to be magenta.
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
|
#include <SFML/Graphics.hpp>
int main()
{
int width = 800;
int height = 600;
sf::RenderWindow window(sf::VideoMode(width, height), "SFML Test!");
sf::RectangleShape rectangle;
rectangle.setSize(sf::Vector2f(100, 50));
rectangle.setOutlineColor(sf::Color::Red);
rectangle.setOutlineThickness(5);
rectangle.setPosition(0, height/2);
window.setVerticalSyncEnabled(true);
sf::Clock clock;
bool left_pressed = false;
bool right_pressed = false;
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
else if (event.type == sf::Event::KeyPressed)
{
if (event.key.code == sf::Keyboard::Left)
{
left_pressed = true;
}
else if (event.key.code == sf::Keyboard::Right)
{
right_pressed = true;
}
}
else if (event.type == sf::Event::KeyReleased)
{
if (event.key.code == sf::Keyboard::Left)
{
left_pressed = false;
}
else if (event.key.code == sf::Keyboard::Right)
{
right_pressed = false;
}
}
}
sf::Vector2f delta_pos;
if (left_pressed)
{
delta_pos.x -= 5;
}
if (right_pressed)
{
delta_pos.x += 5;
}
sf::Time elapsed = clock.getElapsedTime();
if (elapsed.asSeconds() > 6.0f)
{
rectangle.setFillColor(sf::Color::Magenta);
}
// move rectangle
rectangle.setPosition(rectangle.getPosition() + delta_pos);
window.clear(sf::Color::Blue);
window.draw(rectangle);
window.display();
}
return 0;
}
|
By the way, once you think you've understood basic timing (or maybe even now), I suggest reading this article:
https://gafferongames.com/post/fix_your_timestep/
It might help fix future stutter in your game's frames.
________________________________________________
If you need to use C++ <chrono> instead of sf::Clock/sf::Time, you can.
Change the initial sf::Clock logic to:
|
auto start_time = std::chrono::system_clock::now();
|
Change the loop logic to:
1 2 3 4 5 6
|
auto end_time = std::chrono::system_clock::now();
std::chrono::duration<double> diff = end_time - start_time;
if (diff.count() > 6.0)
{
rectangle.setFillColor(sf::Color::Magenta);
}
|
________________________________________________
PS: I used graphics since that was the easiest to demonstrate, but of course you could use the same clocks and logic for a text-based thing too.