clock.tick() in the Pygame documentation:

tick()

update the clock

tick(framerate=0) -> milliseconds

This method should be called once per frame. It will compute how many milliseconds have passed since the previous call.

If you pass the optional framerate argument the function will delay to keep the game running slower than the given ticks per second. This can be used to help limit the runtime speed of a game. By calling Clock.tick(40) once per frame, the program will never run at more than 40 frames per second.

Note that this function uses SDL_Delay function which is not accurate on every platform, but does not use much CPU. Use tick_busy_loop if you want an accurate timer, and don't mind chewing CPU.

So the clock.tick() returns the time since the last call to clock.tick(), use that value to multiply all your speeds with it when you move. Example

dt = clock.tick(60)
player.position.x += player.xSpeed * dt
player.position.y += player.ySpeed * dt

This way your player will always move at the same speed regardless of what you put into the clock.tick() function

Answer from Fredrik on Stack Overflow
🌐
Pygame
pygame.org › docs › ref › time.html
pygame.time — pygame v2.6.0 documentation
get_fps() -> float · Compute your game's framerate (in frames per second). It is computed by averaging the last ten calls to Clock.tick(). Edit on GitHub · index · modules | next | previous | pygame v2.6.0 documentation » · pygame.time ·
🌐
Zenva
gamedevacademy.org › home › python › pygame › how to set pygame fps – easy game clock quick tips
How To Set Pygame FPS - Easy Game Clock Quick Tips - GameDev Academy
As rendering is part of our game loop, this means the FPS is tied directly to the number of times our game loop runs every second. As programs run extremely quickly, our game loop may run too many times per second, so to limit this, we set the maximum Pygame FPS of our game.
Published: November 10, 2023
Top answer
1 of 1
2

what is the meaning of the sleep_time variable in this example?

The time required to process a single frame will be calculated for each frame. If it takes less than 1/60th of a second (i.e. sleep_time will be bigger than 0), put the process on hold for the remained of the 1/60th of a second, so that this frame actually takes 1/60th of a second.

time.sleep(sleep_time) suspends the thread for at least the duration of sleep_time (it may be longer).

how does dt help me limit fps

So in this example, the dt will be used to make sure you have a fixed/constant time step of FPS.

Sort of.

This way of limiting the framerate is not very good. I've modified the example in the question a bit with "printouts":

import time

prev_time = time.time()
FPS = 60
STEP_TIME = 1./FPS
running = True

count = 0
accum = 0

while running:
    current_time = time.time()
    dt = current_time - prev_time
    accum += dt
    count += 1
    if accum >= 1.0:
        accum -= 1.0
        print(count)
        count = 0
      
    prev_time = current_time
    sleep_time = STEP_TIME - dt
    if sleep_time > 0:
        time.sleep(sleep_time)

With the results:

% py main.py
64
64
68
62
62
62

We don't get 60hz. For two reasons:

First, as mentioned, time.sleep(sleep_time) will guarantee that the thread sleeps for at least this amount of time. That is how the OS works. So you can't control precisely how long your program will be sleeping.

Second, let's take a closer look at dt.

dt = prev_time - current_time

so the dt is the time spent during the previous frame. That's fine and all, and it would likely work if we didn't want to throttle the framerate. The problem comes when we want to sleep. When we call time.sleep(sleep_time), we're actually calling time.sleep(1./FPS - (prev_time - current_time)). We're actually fixing last frames time. This has a nasty effect of having some frames where we'll sleep, and other frames where we'll not sleep, resulting inconsistent frame times, at least from the user perspective; adding print(dt, sleep_time) at the end of the previous code snippet, we get something like:

% py main.py
0.0 0.016666666666666666
0.03285384178161621 -0.016187175114949545
0.0 0.016666666666666666
0.033695220947265625 -0.01702855428059896
0.0 0.016666666666666666
0.03452634811401367 -0.017859681447347005
0.0 0.016666666666666666
0.03141927719116211 -0.014752610524495443
0.0002942085266113281 0.01637245814005534
0.032390594482421875 -0.01572392781575521
0.0 0.016666666666666666
0.031510353088378906 -0.01484368642171224
0.0 0.016666666666666666
0.019999265670776367 -0.0033325990041097008
0.0005021095275878906 0.016164557139078776
0.03202223777770996 -0.015355571111043295
0.0006344318389892578 0.01603223482767741
0.03662467002868652 -0.019958003362019857
0.0 0.016666666666666666

To control the frame rate, I generally prefer the "busy loop" approach, which offers a more fine grained control w.r.t. using any sleep methods.

import time

prev_time = time.perf_counter()
current_time = prev_time
FPS = 60
STEP_TIME = 1./FPS
running = True

count = 0
accum = 0

while running:
    prev_time = current_time
    current_time = time.perf_counter()
    dt = current_time - prev_time

    accum += dt
    count += 1
    if accum >= 1.0:
        accum -= 1.0
        print(count)
        count = 0
    # print(dt)

    # busy loop, where we just wait this frame's time to pass
    while time.perf_counter() < (current_time + STEP_TIME):
        pass

Please note that instead of time.time(), I use time.perf_counter() which is much more precise for what we need to do.

With this method, I get this for the actual frame rate:

% py main.py
61
60
60
60
60
60
60
60

and this for individual frame time:

% py main.py
2.100015990436077e-06
0.016670000040903687
0.016669799922965467
0.016668600030243397
0.016668600030243397
0.016668800031766295
0.016668399912305176
0.01667120005004108
0.016669100034050643
0.016668599913828075
0.016668800031766295
0.016668800031766295
0.016668600030243397
0.016668399912305176
0.016669300035573542
0.0166680000256747
0.016668400028720498
0.016668399912305176
0.0166680000256747

Although dt is still about last frame's time, we're still controlling how this frame's time is spent.

🌐
CodersLegacy
coderslegacy.com › home › python › how to display fps in pygame (frames per second)
How to display FPS in Pygame (frames per second) - CodersLegacy
July 8, 2022 - By default your Pygame program has no “fixed fps”. What this means is that your program has no limit on the number of times it updates/renders it’s objects and events.
🌐
Pygame
pygame.org › tags › fps
Pygame
A python-pygame-pyggel medieval fps · Fight the vicious alien race known as the Specters for control of planet Earth. Sabotage starships, kill robotic enemies, and explore underground lava caverns in search of Specter troops. DUGA is an oldschool first-person shooter with roguelike elements!
🌐
Engineering LibreTexts
eng.libretexts.org › bookshelves › computer science › programming languages › making games with python and pygame (sweigart) › 3: pygame basics
3.18: Frames Per Second and pygame.time.Clock Objects - Engineering LibreTexts
May 1, 2020 - import pygame, sys from pygame.locals import * pygame.init() FPS = 30 # frames per second setting fpsClock = pygame.time.Clock() # set up the window DISPLAYSURF = pygame.display.set_mode((400, 300), 0, 32) pygame.display.set_caption('Animation') ...
🌐
YouTube
youtube.com › watch
Displaying FPS On Screen in Pygame - YouTube
In this Pygame Tutorial we will learn how to set a Frame Rate for our Pygame Window, and display it On Screen.Other Pygame Tutorials:Pygame Tutorial for begi...
Published: July 28, 2021
🌐
Stack Overflow
stackoverflow.com › questions › 35617246 › setting-a-fixed-frame-rate-in-pygame-python-3
performance - Setting a fixed frame rate in Pygame, Python 3 - Stack Overflow
I'm currently making a game using Pygame (Python 3), and I'm looking for a way to make the game run at a fixed frame rate (unit FPS). Most of the game is located inside a giant while loop, where th...
Find elsewhere
🌐
GitHub
github.com › marcos-diniz › Pygame-FPS
GitHub - marcos-diniz/Pygame-FPS: Simple fps made with pygame and pyopengl
April 13, 2021 - Simple fps made with pygame and pyopengl. Contribute to marcos-diniz/Pygame-FPS development by creating an account on GitHub.
Author: marcos-diniz
🌐
Python Programming
pythonprogramming.altervista.org › pygame-how-to-display-the-frame-rate-fps-on-the-screen
Pygame: how to display the frame rate (FPS) on the screen – python programming
January 14, 2020 - import pygame pygame.init() screen = pygame.display.set_mode((400,400)) clock = pygame.time.Clock() font = pygame.font.SysFont("Arial", 18) def update_fps(): fps = str(int(clock.get_fps())) fps_text = font.render(fps, 1, pygame.Color("coral")) return fps_text loop = 1 while loop: screen.fill((0, 0, 0)) screen.blit(update_fps(), (10,0)) for event in pygame.event.get(): if event.type == pygame.QUIT: loop = 0 clock.tick(60) pygame.display.update() pygame.quit()
🌐
Pygame
pygame.org › docs
Pygame Front Page — pygame v2.6.0 documentation
# Example file showing a circle ... * dt if keys[pygame.K_d]: player_pos.x += 300 * dt # flip() the display to put your work on screen pygame.display.flip() # limits FPS to 60 # dt is delta time in seconds since last frame, used for framerate- # independent physic...
🌐
YouTube
youtube.com › watch
How to show frame rate with pygame in python - YouTube
How to show fps in pygame with python to see the frame rate on the screen and test the 'speed' of a game. https://pythonprogramming.altervista.org/how-to-sho...
Published: March 20, 2021
🌐
YouTube
youtube.com › fh coding
How To Control FPS In Pygame - YouTube
In this video I show you how to control the FPS of a game in Pygame.Don't forget to like and subscribe ;)Ryft Invite Link: https://discord.gg/KhGNeBKzJSRyft ...
Published: July 10, 2021
Views: 2K
🌐
YouTube
youtube.com › watch
Pygame Framerate Independence Tutorial: Delta Time Movement - YouTube
In this video, we'll discuss Framerate Independence. We'll learn how we can implement delta time movement and make our games play consistently across differe...
Published: January 21, 2021
🌐
Pygame
pygame.org › wiki › ConstantGameSpeed
ConstantGameSpeed - pygame wiki
TICKS_PER_SECOND = 30.0 MAX_FRAME_SKIP = 5.0 # Ball control. MAX_BALL_SPEED = 240.0 # pixels per second INIT_BALLS = 100 # initial number of balls ## Note to tweakers: Try adjusting these GameClock settings before adjusting ## the fundamental ones above. SETTINGS = ( # TicksPerSecond MaxFPS ...
🌐
YouTube
youtube.com › giovanni gatto
Pygame day 4: How to show Frame rate fps or any text in Pygame - YouTube
Show frame rate on the screen with pygame in Python or any other text.https://pythonprogramming.altervista.org/hot-to-show-the-frame-rate-fps-or-any-text-wit...
Published: December 28, 2021
Views: 364
🌐
GitHub
gist.github.com › hortonew › 4507023
Pygame - Control FPS · GitHub
Pygame - Control FPS. GitHub Gist: instantly share code, notes, and snippets.