-
Notifications
You must be signed in to change notification settings - Fork 30
Timing
Time is a very important factor, especially in games: objects move around, which means that their position and rotation changes over time. Levels may have a certain time limit. You might want the measure the time the player beats a level.
To measure time in JSFML, the Clock class is used. It has the two very basic features that a stopwatch has:
- Start or restart the clock.
- Show the measured time.
The following example creates a circle and moves it across the screen. After 3 seconds, we move the circle back to the top left corner of the screen. When the user closes the window, we print the amount of time that the program has run.
In this code, we have 3 different use cases for clocks. All of them will be explained in the following sections.
// ... (create window)
//Create a circle
CircleShape circle = new CircleShape(100);
//Create a frame clock which will be used to control the circle's movement
Clock frameClock = new Clock();
//Create a reset clock that will measure the time until 3 seconds have passed to reset the circle
Clock resetClock = new Clock();
//Create a duration clock which will measure the time that the application runs
Clock appClock = new Clock();
//Main loop
while(window.isOpen()) {
//... (clearing and drawing the circle)
//... (event handling)
//Get the amount of time that has passed since the last frame and restart the frame clock
Time deltaTime = frameClock.restart();
//Convert the time into seconds
float deltaSeconds = deltaTime.asSeconds();
//Move the circle right by 50 pixels per second
circle.move(deltaSeconds * 50, 0);
//Check if 3 seconds have passed on the reset clock
if(resetClock.getElapsedTime().asSeconds() >= 3) {
//Yes, reset the circle and the clock
circle.setPosition(0, 0);
resetClock.restart();
}
}
//Print the total amount of time that the program has been running
Time totalTime = appClock.getElapsedTime();
System.out.println("The application has run for " + totalTime.asSeconds() + " seconds.");
The appClock
is the most simple clock used above. It gets started by being created using new
. Clocks will silently "run" in the background while the rest of the application is executed. Once everything is over, we retrieve the amount of time that has passed since its creation using the [getElapsedTime](http://www.jsfml.org/javadoc/org/jsfml/system/Clock.html#getElapsedTime(\)) method.
Time periods in JSFML are represented by the immutable Time class. It provides methods to get the represented time in different units: seconds, milliseconds or microseconds.
In the case above, we convert the measured time since the startup to seconds using [asSeconds](http://www.jsfml.org/javadoc/org/jsfml/system/Time.html#asSeconds(\)) and print it out.
The resetClock
is a simple example showing how to use clocks for timed actions. Since we want to reset the circle every 3 seconds, we check the elapsed time on the clock every frame. When it surpassed 3 seconds, we put the circle back to the start and restart the clock using the [restart](http://www.jsfml.org/javadoc/org/jsfml/system/Clock.html#restart(\)) method. Its time is reset to zero, and it will take another 3 seconds for the timer to trigger.
Procedural animation is done easiest thinking with seconds. An object moving at "50 pixels per second" is much easier to imagine than "2 pixels per frame". Besides, the latter depends directly on the frame rate as well, whereas seconds do not.
In order to move the circle 50 pixels per second, we measure how long a frame takes - in seconds. We do this every frame, because the actual time may vary (due to a lot of factors that cannot be predicted or influenced).
We convert the duration of the frame to seconds (with 30 frames per second, this should be approximately 0.03 seconds) and multiply this by the desired velocity, which is 50 pixels per second.
The result is the amount of pixels that we have to move the circle in this frame in order to achieve our desired velocity.