Ale gdy tworzę zmienną TimePerFrame jako:
float deltaTime = clock.restart().asSeconds();
Wkleiłeś nie tą linie kodu? Bo szczerze mówiąc nie widze związku między zdaniem powyżej i fragmentem kodu.
Nie ma prawa działać, bo odejmujemy float od sf::Time.
To odejmuj float of float. Od tego masz metody asSeconds() itd., żeby "przekonwertować" obiekt Time na pewną wartość.
Wracając do twojego pytania:
Chodzi o zapewnienie updejtowania stanu gry w stałych odstępach czasu. W taki sposób może się okazać, że w jednej klatce update nie nastąpi ani razu (czas renderowania był tak krótki), albo raz lub więcej razy (w przypadku "więcej razy" oznacza to, że czas renderowania był kilka razy dłuższy od naszej stałej TimePerFrame). Uniezależniamy w ten sposób update stanu gry od renderowania.
Wydaje mi się, że najwięcej dzięki temu zyskuje sprawdzanie kolizji. Załóżmy, że wyrenderowanie klatki zabrało wyjątkowo dużo czasu. Załóżmy też, że w twojej grze jakiś obiekt porusza się w strone ściany przez którą nie powinien przelecieć. Zauważ, że jeśli byśmy po prostu przesunęli nasz obiekt adekwatnie do czasu dt (delta time - czas pomiędzy klatkami - w dużej częsci jest to czas renderowania), to w tym przypadku mógłby się po prostu pojawić za ścianą. Kolizja ze ścianą nigdy nawet nie została by wykryta. Uniezależniając nasz delta time od czasu renderowania, mamy pewność, że taka sytuacja, się nie zdarzy.
Teraz mam nadzieje, że kod wydaje się mieć więcej sensu :) Jak coś jest nadal niejasne, to pytaj.
Polecam ten artykuł: https://gafferongames.com/post/fix_your_timestep/
PS: wydaje mi się, że processEvents() powinieneś wyrzucić z wewnętrznej pętli. (rozumiem, że processEvents realizuje przechwytywanie inputu?)