pygame clock.tick() vs framerate in game main loop


Every pygame has a game loop that looks like this:

while running:
    for event in pygame.event.get():        
        if event.type == pygame.QUIT:
            running = False   
    print("tick " + str(pygame.time.get_ticks()))

According to the api forget_ticks():

Returns the number of millisconds since pygame.init() was called.
Before pygame is initialized this will always be 0.

But clock.tick() :

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.

I’m a bit confused, does it mean that clock.tick() directly affects how many milliseconds have passed since the start of the game?

So clock.tick(40) means I “issue” 40 frames per second and the while loop runs 40 times per second?

I don’t see the relation between fps and ticks.

I actually just tested it and get_ticks() still returns REAL time in mls no matter what fps you give to tick() - 0.1 or 30 or 60.

So it seems clock.tick() just sets up how fast game should run or how often while loop should update itself, run through itself.

However I m still a bit confused, other answers are welcome.

Asked By: ERJAN



FPS, Frames Per Second, is the number of frames shown per unit of time.
1 / FPS is the amount of time should pass between each frame.
Tick is just a measure of time in PyGame.

clock.tick(40) means that for every second at most 40 frames should pass.

Answered By: ModoUnreal

I set up high fps – clock.tick(30) or 60,
and game runs fast, and get_ticks() prints out elapsed time very fast however actual runtime from pygame.init() did not change!

I thought time runs faster because of high FPS! It does not, I tried clock.tick(0.1) – aka 1 frame per 10 seconds, and get_ticks() printed out its elapsed time only ONCE PER 10 seconds! Because the while loop was running through itself at fps = 0.1.

But if fps was higher, the update rate would be highernot the total elapsed time

Now I figured it out.

Answered By: ERJAN

I know it is already answered but I wanted to explain something I tried:

import pygame


gameDisplay = pygame.display.set_mode((800,600))
clock = pygame.time.Clock()

crashed = False

counter = 1
while not crashed:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            crashed = True
    counter += 1
    clock.tick(1) # will be 10 in the next run 

So what we will do is make two runs — one where frame per second (fps) equals 1 and the other where fps equals 10. And we will run the code for 10 seconds. I used my phone stopwatch to do this.

So, mathematically 1 fps for 10sec is 10 right and 10 fps in 10sec is 100, clearly.

So, running the first run, 1 fps, the counter variable should be around 10, depending on your timing. For the second run, at the end of 10 seconds the counter variable in your console should be around 100.

So, in brief, we could say the loop is controlling your game display
and clock.tick() specifies how fast you want to change the game display or, in other words, how fast the loop runs.

Answered By: Sam

I am a bit late, but I have an answer that I have come across based on my research. This is geared towards beginners like myself, please feel free to correct me if I am wrong.

Lets assume the following loop:

while True:
  # ... Some code which deals with the objects and surfaces
  pygame.display.flip() # displays all the changes we've made to the user
  pygame.clock.tick(60) # code that prevents our framerate from exceeding 60 fps

Ok, considering the code above, assume pygame.clock.tick measures the time elapsed from when it was last called

So lets say it is now the 2nd iteration of this loop, and the tick method has measured that 0.0157 seconds has elapsed since it was last called in the first iteration. If we calculate the FPS for this, it would be 1 frame/0.0157 seconds (if you are confused about why it is 1 frame, it is because we have only "updated" the user’s screen once since the last calling of the tick method. 1/0.0157 = 63.69 frames per second. Dang it! Thats more than 60 frames per second. Thus, the method tick will automatically "slow" down your code, preventing it from "updating" again UNTIL enough time has elapsed such that the frame rate = 60 fps.

So how will it do that? Well, using basic math we can calculate that an FPS of 60 translates to 1 frame every 0.016 seconds. So, if we make the code wait an extra 0.0003 seconds, we will achieve a frame rate of 60! This is because 0.0157 seconds has already elapsed as described in the scenario above, so we need to wait an extra 0.0003 seconds on this frame to achieve our desired frame rate.

I hope this helps anyone who is confused on this subject.

Answered By: Julian Biju