SFML community forums
Help => General => Topic started by: zepto on November 25, 2011, 11:09:14 pm
-
Goal
Move or rotate a sprite smoothly on the screen with SFML2.
Implementation
This code should rotate the SFML logo sfml-small.png (http://sfml-dev.org/logo/sfml-small.png).
#include <SFML/Graphics.hpp>
int main()
{
sf::RenderWindow window(sf::VideoMode(800, 600), "Gameloops and timing");
window.EnableVerticalSync(true);
sf::Texture image;
if (!image.LoadFromFile("sfml-small.png")) {
return EXIT_FAILURE;
}
sf::Sprite sprite(image);
sprite.Move(window.GetWidth() / 2.0, window.GetHeight() / 2.0);
const sf::Uint32 FPS = 50;
const sf::Uint32 SKIP_TICKS = 1000 / FPS;
sf::Uint32 sleep_time = 0;
sf::Clock clock;
sf::Uint32 next_game_tick = clock.GetElapsedTime();
while (window.IsOpened())
{
sf::Event event;
while (window.PollEvent(event))
{
if (event.Type == sf::Event::Closed) {
window.Close();
}
}
sprite.Rotate(90.f / FPS);
window.Clear();
window.Draw(sprite);
window.Display();
next_game_tick += SKIP_TICKS;
sleep_time = next_game_tick - clock.GetElapsedTime();
if (sleep_time >= 0) {
sf::Sleep(sleep_time);
} else {
// running behind
}
}
return EXIT_SUCCESS;
}
Observations
- The sprite sometimes randomly jumps back when it should rotate continiously with constant angular velocity
- The problem is independent of the programming language or operating system
- I noticed similar issues in a lot of games and physics simulations
Help
What am I doing wrong? Is it inaccurate timing, or is vsync not working? I have no clue what's going on.
-
The problem is independent of the programming language
So please give it in C++ so that more people (including me) can test it ;)
-
Ok, I implemented the game loop FPS dependent on Constant Game Speed from the blog article deWiTTERS Game Loop (http://www.koonsolo.com/news/dewitters-gameloop/) in C++ with SFML2.
It has the same issues.
-
Your code doesn't work, on the second iteration sleep_time is huge (negative but its type is unsigned) so it sleeps forever.
-
Oops my bad, sleep_time should be an integer: new code (http://pastebin.com/FYaBrPtX)
From the output it looks to me like everything is working as expected.
Every (40 +- 1) ms the sprite is rotated by 3.6 degrees, I don't understand why the rotation looks so choppy.
0, 1
3.6, 40
7.2, 80
10.8, 120
14.4, 161
18, 201
21.6, 241
25.2, 281
28.8, 320
32.4, 361
36, 401
39.6, 441
43.2, 481
46.8, 521
50.4, 561
54, 601
57.6, 640
61.2, 681
64.8, 720
68.4, 760
72, 801
75.6, 841
79.2, 880
82.8, 921
86.4, 961
90, 1000
-
try the built in window.SetFrameratelimit(FPS)
-
try the built in window.SetFrameratelimit(FPS)
No this didn't work, also the gameloop is already limited by the FPS.
Any other ideas?
-
for me, it's limited by EnableVerticalSync and not by FPS
-
Let VSync decide the FPS of the game.
Enable window vsync and use GetFrameTime function to obtain smooth movements and rotations. :) It works!